QgsExpression::referencedColumns() returns QSet instead of QStringList
+
QgsExpression::Node::referencedColumns() returns QSet instead of QStringList
+
QgsExpression::Function::referencedColumns() returns QSet instead of QStringList
\subsection qgis_api_break_3_0_QgsFeature QgsFeature
@@ -1087,6 +1090,14 @@ be used instead of a null pointer if no transformation is required.
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.
@@ -1482,6 +1493,8 @@ optional property map passing down layer level properties to the SLD encoders. I
scaleMinDenom and scaleMaxDenom properties.
The RotationField capabitity was removed. This is now handled using data defined rotation at a symbol layer level
setScaleMethodToSymbol was removed. This is now handled using data defined scaling at a symbol layer level
+
setScaleMethodToSymbol was removed. This is now handled using data defined scaling at a symbol layer level
+
usedAttributes is now a const method and returns QSet instead of QStringList
diff --git a/mac/app.info.plist.in b/mac/app.info.plist.in
index 5c103012b61..4513d99ab0e 100644
--- a/mac/app.info.plist.in
+++ b/mac/app.info.plist.in
@@ -7,7 +7,7 @@
CFBundleNameQGISCFBundleIdentifier
- org.qgis.qgis2
+ org.qgis.qgis3CFBundleExecutable${QGIS_APP_NAME}CFBundlePackageType
diff --git a/mac/browser.info.plist.in b/mac/browser.info.plist.in
index 38617f88565..c2eac319918 100644
--- a/mac/browser.info.plist.in
+++ b/mac/browser.info.plist.in
@@ -7,7 +7,7 @@
CFBundleNameQGIS BrowserCFBundleIdentifier
- org.qgis.qgis2_browser
+ org.qgis.qgis3_browserCFBundleExecutableQGIS BrowserCFBundlePackageType
diff --git a/ms-windows/osgeo4w/package-nightly.cmd b/ms-windows/osgeo4w/package-nightly.cmd
index df96c18e673..042b7703ef5 100644
--- a/ms-windows/osgeo4w/package-nightly.cmd
+++ b/ms-windows/osgeo4w/package-nightly.cmd
@@ -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
diff --git a/ms-windows/osgeo4w/package.cmd b/ms-windows/osgeo4w/package.cmd
index 67bac59be67..7d02cbb0518 100644
--- a/ms-windows/osgeo4w/package.cmd
+++ b/ms-windows/osgeo4w/package.cmd
@@ -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%
diff --git a/ms-windows/plugins.nsh b/ms-windows/plugins.nsh
index a4384c54780..f751da0d410 100644
--- a/ms-windows/plugins.nsh
+++ b/ms-windows/plugins.nsh
@@ -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 #################################
diff --git a/ms-windows/python_plugins.nsh b/ms-windows/python_plugins.nsh
index dec5c76dadc..7a86b37ec82 100644
--- a/ms-windows/python_plugins.nsh
+++ b/ms-windows/python_plugins.nsh
@@ -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 #################################
diff --git a/python/core/auth/qgsauthmanager.sip b/python/core/auth/qgsauthmanager.sip
index f2f6200c1c0..4be77a4dbc6 100644
--- a/python/core/auth/qgsauthmanager.sip
+++ b/python/core/auth/qgsauthmanager.sip
@@ -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;
diff --git a/python/core/composer/qgscomposeritemcommand.sip b/python/core/composer/qgscomposeritemcommand.sip
index 0f517ffdd46..564d6c5a770 100644
--- a/python/core/composer/qgscomposeritemcommand.sip
+++ b/python/core/composer/qgscomposeritemcommand.sip
@@ -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,
diff --git a/python/core/composer/qgscomposermultiframecommand.sip b/python/core/composer/qgscomposermultiframecommand.sip
index e405fa291ac..23738b81f81 100644
--- a/python/core/composer/qgscomposermultiframecommand.sip
+++ b/python/core/composer/qgscomposermultiframecommand.sip
@@ -49,7 +49,11 @@ class QgsComposerMultiFrameMergeCommand: QgsComposerMultiFrameCommand
TableMaximumFeatures,
TableMargin,
TableGridStrokeWidth,
- TableCellStyle
+ TableCellStyle,
+ TableHeaderFontColor,
+ TableContentFontColor,
+ TableGridColor,
+ TableBackgroundColor,
};
QgsComposerMultiFrameMergeCommand( Context c, QgsComposerMultiFrame* multiFrame, const QString& text );
diff --git a/python/core/qgsapplication.sip b/python/core/qgsapplication.sip
index 05bcc95a51f..8a8dd5a24ce 100644
--- a/python/core/qgsapplication.sip
+++ b/python/core/qgsapplication.sip
@@ -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
diff --git a/python/core/qgsdatadefined.sip b/python/core/qgsdatadefined.sip
index f753eda2af8..f769081fdea 100644
--- a/python/core/qgsdatadefined.sip
+++ b/python/core/qgsdatadefined.sip
@@ -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 referencedColumns( const QgsExpressionContext& context = QgsExpressionContext() );
/**
* Get the field which this QgsDataDefined represents. Be aware that this may return
diff --git a/python/core/qgsexpression.sip b/python/core/qgsexpression.sip
index caa560ef0c9..f4dc271ecd8 100644
--- a/python/core/qgsexpression.sip
+++ b/python/core/qgsexpression.sip
@@ -51,7 +51,7 @@ class QgsExpression
*
* TODO QGIS3: Return QSet
*/
- QStringList referencedColumns() const;
+ QSet 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& referencedColumns = QSet(),
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& referencedColumns = QSet(),
bool lazyEval = false,
bool handlesNull = false,
bool isContextual = false );
@@ -350,7 +350,7 @@ class QgsExpression
*/
bool lazyEval() const;
- virtual QStringList referencedColumns() const;
+ virtual QSet 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 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 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 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 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 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 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 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 referencedColumns() const;
virtual bool needsGeometry() const;
virtual QgsExpression::Node* clone() const;
};
diff --git a/python/core/qgsexpressioncontext.sip b/python/core/qgsexpressioncontext.sip
index f2712123675..8aece97fac6 100644
--- a/python/core/qgsexpressioncontext.sip
+++ b/python/core/qgsexpressioncontext.sip
@@ -17,7 +17,7 @@ class QgsScopedExpressionFunction : QgsExpression::Function
const QString& group,
const QString& helpText = QString(),
bool usesGeometry = false,
- const QStringList& referencedColumns = QStringList(),
+ const QSet& referencedColumns = QSet(),
bool lazyEval = false,
bool handlesNull = false,
bool isContextual = true );
diff --git a/python/core/qgsexpressionfieldbuffer.sip b/python/core/qgsexpressionfieldbuffer.sip
index dfa3aee5e8f..8bceb4a67db 100644
--- a/python/core/qgsexpressionfieldbuffer.sip
+++ b/python/core/qgsexpressionfieldbuffer.sip
@@ -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
*
diff --git a/python/core/qgspallabeling.sip b/python/core/qgspallabeling.sip
index 71c11d37f55..4c7ab13e101 100644
--- a/python/core/qgspallabeling.sip
+++ b/python/core/qgspallabeling.sip
@@ -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& 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& 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& 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& attrNames, QgsRenderContext& ctx );
/** Register a feature for labelling.
* @param layerID string identifying layer associated with label
diff --git a/python/core/qgsrelation.sip b/python/core/qgsrelation.sip
index ea4a1f5dc86..cc347aa2a3b 100644
--- a/python/core/qgsrelation.sip
+++ b/python/core/qgsrelation.sip
@@ -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.
diff --git a/python/core/qgsrelationmanager.sip b/python/core/qgsrelationmanager.sip
index c77d1676659..4704694fe12 100644
--- a/python/core/qgsrelationmanager.sip
+++ b/python/core/qgsrelationmanager.sip
@@ -90,6 +90,16 @@ class QgsRelationManager : QObject
*/
QList 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 discoverRelations( const QList& existingRelations, const QList& layers );
+
signals:
/** This signal is emitted when the relations were loaded after reading a project */
void relationsLoaded();
diff --git a/python/core/qgsvectordataprovider.sip b/python/core/qgsvectordataprovider.sip
index 90185af6601..b9c62809c02 100644
--- a/python/core/qgsvectordataprovider.sip
+++ b/python/core/qgsvectordataprovider.sip
@@ -371,6 +371,15 @@ class QgsVectorDataProvider : QgsDataProvider
*/
virtual QSet 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 discoverRelations( const QgsVectorLayer* self, const QList& layers ) const;
+
signals:
/** Signals an error in this provider */
void raiseError( const QString& msg );
diff --git a/python/core/symbology-ng/qgs25drenderer.sip b/python/core/symbology-ng/qgs25drenderer.sip
index 56c58f60091..dce3ace659d 100644
--- a/python/core/symbology-ng/qgs25drenderer.sip
+++ b/python/core/symbology-ng/qgs25drenderer.sip
@@ -33,7 +33,7 @@ class Qgs25DRenderer : QgsFeatureRenderer
void startRender( QgsRenderContext& context, const QgsFields& fields );
void stopRender( QgsRenderContext& context );
- QList usedAttributes();
+ QSet usedAttributes() const;
QgsFeatureRenderer* clone() const;
virtual QgsSymbol* symbolForFeature( QgsFeature& feature, QgsRenderContext& context );
diff --git a/python/core/symbology-ng/qgscategorizedsymbolrenderer.sip b/python/core/symbology-ng/qgscategorizedsymbolrenderer.sip
index 7c27c6053f7..f7b143b602d 100644
--- a/python/core/symbology-ng/qgscategorizedsymbolrenderer.sip
+++ b/python/core/symbology-ng/qgscategorizedsymbolrenderer.sip
@@ -59,7 +59,7 @@ class QgsCategorizedSymbolRenderer : QgsFeatureRenderer
virtual void stopRender( QgsRenderContext& context );
- virtual QList usedAttributes();
+ virtual QSet usedAttributes() const;
virtual QString dump() const;
diff --git a/python/core/symbology-ng/qgsgraduatedsymbolrenderer.sip b/python/core/symbology-ng/qgsgraduatedsymbolrenderer.sip
index 7a32a49a8a5..c9f7d6de439 100644
--- a/python/core/symbology-ng/qgsgraduatedsymbolrenderer.sip
+++ b/python/core/symbology-ng/qgsgraduatedsymbolrenderer.sip
@@ -102,7 +102,7 @@ class QgsGraduatedSymbolRenderer : QgsFeatureRenderer
virtual void stopRender( QgsRenderContext& context );
- virtual QList usedAttributes();
+ virtual QSet usedAttributes() const;
virtual QString dump() const;
diff --git a/python/core/symbology-ng/qgsheatmaprenderer.sip b/python/core/symbology-ng/qgsheatmaprenderer.sip
index c6664ee99da..3e9da2d1569 100644
--- a/python/core/symbology-ng/qgsheatmaprenderer.sip
+++ b/python/core/symbology-ng/qgsheatmaprenderer.sip
@@ -18,7 +18,7 @@ class QgsHeatmapRenderer : QgsFeatureRenderer
//! @note symbol2 in python bindings
virtual QgsSymbolList symbols( QgsRenderContext& context );
virtual QString dump() const;
- virtual QList usedAttributes();
+ virtual QSet usedAttributes() const;
static QgsFeatureRenderer* create( QDomElement& element ) /Factory/;
virtual QDomElement save( QDomDocument& doc );
static QgsHeatmapRenderer* convertFromRenderer( const QgsFeatureRenderer* renderer ) /Factory/;
diff --git a/python/core/symbology-ng/qgsinvertedpolygonrenderer.sip b/python/core/symbology-ng/qgsinvertedpolygonrenderer.sip
index 65f97d54cff..ca39659faf3 100644
--- a/python/core/symbology-ng/qgsinvertedpolygonrenderer.sip
+++ b/python/core/symbology-ng/qgsinvertedpolygonrenderer.sip
@@ -39,7 +39,7 @@ class QgsInvertedPolygonRenderer : QgsFeatureRenderer
virtual QString dump() const;
/** Proxy that will call this method on the embedded renderer. */
- virtual QList usedAttributes();
+ virtual QSet 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.
diff --git a/python/core/symbology-ng/qgsnullsymbolrenderer.sip b/python/core/symbology-ng/qgsnullsymbolrenderer.sip
index 3f140595503..7fa52b478b0 100644
--- a/python/core/symbology-ng/qgsnullsymbolrenderer.sip
+++ b/python/core/symbology-ng/qgsnullsymbolrenderer.sip
@@ -24,7 +24,7 @@ class QgsNullSymbolRenderer : QgsFeatureRenderer
virtual void stopRender( QgsRenderContext& context );
virtual bool willRenderFeature( QgsFeature& feat, QgsRenderContext& context );
- virtual QList usedAttributes();
+ virtual QSet usedAttributes() const;
virtual QString dump() const;
virtual QgsFeatureRenderer* clone() const /Factory/;
virtual QgsSymbolList symbols( QgsRenderContext& context );
diff --git a/python/core/symbology-ng/qgspointclusterrenderer.sip b/python/core/symbology-ng/qgspointclusterrenderer.sip
index 57e6a530885..298e88cfb4f 100644
--- a/python/core/symbology-ng/qgspointclusterrenderer.sip
+++ b/python/core/symbology-ng/qgspointclusterrenderer.sip
@@ -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 usedAttributes();
+ virtual QSet usedAttributes() const;
//! Create a renderer from XML element
static QgsFeatureRenderer* create( QDomElement& symbologyElem ) /Factory/;
diff --git a/python/core/symbology-ng/qgspointdisplacementrenderer.sip b/python/core/symbology-ng/qgspointdisplacementrenderer.sip
index 966c3f6d17f..36713b2ca23 100644
--- a/python/core/symbology-ng/qgspointdisplacementrenderer.sip
+++ b/python/core/symbology-ng/qgspointdisplacementrenderer.sip
@@ -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 usedAttributes();
+ virtual QSet usedAttributes() const;
//! Create a renderer from XML element
static QgsFeatureRenderer* create( QDomElement& symbologyElem ) /Factory/;
diff --git a/python/core/symbology-ng/qgspointdistancerenderer.sip b/python/core/symbology-ng/qgspointdistancerenderer.sip
index c2bead6b27b..761c0df5dfd 100644
--- a/python/core/symbology-ng/qgspointdistancerenderer.sip
+++ b/python/core/symbology-ng/qgspointdistancerenderer.sip
@@ -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 usedAttributes();
+ virtual QSet usedAttributes() const;
virtual Capabilities capabilities();
virtual QgsSymbolList symbols( QgsRenderContext& context );
virtual QgsSymbol* symbolForFeature( QgsFeature& feature, QgsRenderContext& context );
diff --git a/python/core/symbology-ng/qgsrenderer.sip b/python/core/symbology-ng/qgsrenderer.sip
index bf0cdd6b25e..b09f7e95427 100644
--- a/python/core/symbology-ng/qgsrenderer.sip
+++ b/python/core/symbology-ng/qgsrenderer.sip
@@ -119,10 +119,8 @@ class QgsFeatureRenderer
/**
* Returns a set of attributes required for this renderer.
- *
- * TODO QGIS3: Change QList to QSet
*/
- virtual QList usedAttributes() = 0;
+ virtual QSet usedAttributes() const = 0;
/**
* Returns true if this renderer requires the geometry to apply the filter.
diff --git a/python/core/symbology-ng/qgsrulebasedrenderer.sip b/python/core/symbology-ng/qgsrulebasedrenderer.sip
index 8eff5f1a8b0..e65197fb364 100644
--- a/python/core/symbology-ng/qgsrulebasedrenderer.sip
+++ b/python/core/symbology-ng/qgsrulebasedrenderer.sip
@@ -340,7 +340,7 @@ class QgsRuleBasedRenderer : QgsFeatureRenderer
virtual QString filter( const QgsFields& fields = QgsFields() );
- virtual QList usedAttributes();
+ virtual QSet usedAttributes() const;
virtual bool filterNeedsGeometry() const;
diff --git a/python/core/symbology-ng/qgssinglesymbolrenderer.sip b/python/core/symbology-ng/qgssinglesymbolrenderer.sip
index fa162e1069d..11bcb202a92 100644
--- a/python/core/symbology-ng/qgssinglesymbolrenderer.sip
+++ b/python/core/symbology-ng/qgssinglesymbolrenderer.sip
@@ -19,7 +19,7 @@ class QgsSingleSymbolRenderer : QgsFeatureRenderer
virtual void stopRender( QgsRenderContext& context );
- virtual QList usedAttributes();
+ virtual QSet usedAttributes() const;
QgsSymbol* symbol() const;
void setSymbol( QgsSymbol* s /Transfer/ );
diff --git a/python/gui/qgspanelwidgetstack.sip b/python/gui/qgspanelwidgetstack.sip
index e13357945f6..17566eb0410 100644
--- a/python/gui/qgspanelwidgetstack.sip
+++ b/python/gui/qgspanelwidgetstack.sip
@@ -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.
diff --git a/python/plugins/GdalTools/tools/doRasterize.py b/python/plugins/GdalTools/tools/doRasterize.py
index b682da930f9..9b88dabf2b5 100644
--- a/python/plugins/GdalTools/tools/doRasterize.py
+++ b/python/plugins/GdalTools/tools/doRasterize.py
@@ -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))
diff --git a/python/plugins/MetaSearch/pavement.py b/python/plugins/MetaSearch/pavement.py
index 8a4f4293697..10abad95897 100644
--- a/python/plugins/MetaSearch/pavement.py
+++ b/python/plugins/MetaSearch/pavement.py
@@ -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):
diff --git a/python/plugins/processing/algs/gdal/warp.py b/python/plugins/processing/algs/gdal/warp.py
index e729d19af85..7040e11da99 100644
--- a/python/plugins/processing/algs/gdal/warp.py
+++ b/python/plugins/processing/algs/gdal/warp.py
@@ -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,
diff --git a/python/plugins/processing/algs/otb/maintenance/README b/python/plugins/processing/algs/otb/maintenance/README
index ba7c6122925..487759026cd 100644
--- a/python/plugins/processing/algs/otb/maintenance/README
+++ b/python/plugins/processing/algs/otb/maintenance/README
@@ -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
diff --git a/python/plugins/processing/gui/TestTools.py b/python/plugins/processing/gui/TestTools.py
index a8d32091592..e5f0ebe5e2d 100644
--- a/python/plugins/processing/gui/TestTools.py
+++ b/python/plugins/processing/gui/TestTools.py
@@ -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()
diff --git a/python/plugins/processing/tools/postgis.py b/python/plugins/processing/tools/postgis.py
index 1ac4441f0b5..4140ac63437 100644
--- a/python/plugins/processing/tools/postgis.py
+++ b/python/plugins/processing/tools/postgis.py
@@ -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:
diff --git a/python/plugins/processing/tools/vector.py b/python/plugins/processing/tools/vector.py
index 169fe6d78ba..d8b135b8582 100644
--- a/python/plugins/processing/tools/vector.py
+++ b/python/plugins/processing/tools/vector.py
@@ -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()
diff --git a/resources/context_help/HeatmapGui b/resources/context_help/HeatmapGui
index e722f10e928..612d8d28347 100644
--- a/resources/context_help/HeatmapGui
+++ b/resources/context_help/HeatmapGui
@@ -26,7 +26,7 @@ clustering of points.
Rows and Columns
Used to change the dimensions of the output raster file. These values are also linked to the Cell size X and Cell size Y 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!
Cell size X and Y
diff --git a/resources/context_help/PythonConsole b/resources/context_help/PythonConsole
index 041f2ad0394..1554b9d227c 100644
--- a/resources/context_help/PythonConsole
+++ b/resources/context_help/PythonConsole
@@ -52,7 +52,7 @@ uncomment code, check syntax, share the code via codepad.org and much more).
Open PyQGIS Cookbook by typing .
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
+The history will be saved into the file ~/.qgis3/console_history.txt
diff --git a/scripts/mkuidefaults.py b/scripts/mkuidefaults.py
index 1a3ad6c7de0..223bf79d4e2 100644
--- a/scripts/mkuidefaults.py
+++ b/scripts/mkuidefaults.py
@@ -32,7 +32,7 @@ def chunks(l, n):
QCoreApplication.setOrganizationName("QGIS")
QCoreApplication.setOrganizationDomain("qgis.org")
-QCoreApplication.setApplicationName("QGIS2")
+QCoreApplication.setApplicationName("QGIS3")
s = QSettings()
diff --git a/src/analysis/CMakeLists.txt b/src/analysis/CMakeLists.txt
index e3580471708..5da66b09cbe 100644
--- a/src/analysis/CMakeLists.txt
+++ b/src/analysis/CMakeLists.txt
@@ -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}"
diff --git a/src/analysis/network/CMakeLists.txt b/src/analysis/network/CMakeLists.txt
index 2a83a23c817..e59d7c21d41 100644
--- a/src/analysis/network/CMakeLists.txt
+++ b/src/analysis/network/CMakeLists.txt
@@ -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}"
diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt
index aaab88c269e..8907d907a27 100644
--- a/src/app/CMakeLists.txt
+++ b/src/app/CMakeLists.txt
@@ -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
diff --git a/src/app/composer/qgscomposer.cpp b/src/app/composer/qgscomposer.cpp
index 06444932188..cd55b1f2740 100644
--- a/src/app/composer/qgscomposer.cpp
+++ b/src/app/composer/qgscomposer.cpp
@@ -67,6 +67,7 @@
#include "qgsvectorlayer.h"
#include "qgscomposerimageexportoptionsdialog.h"
#include "ui_qgssvgexportoptions.h"
+#include "qgspanelwidgetstack.h"
#include
#include
@@ -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::const_iterator it = mItemWidgetMap.constFind( item );
+ QMap::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::const_iterator it = mItemWidgetMap.constFind( item );
+ QMap::const_iterator it = mItemWidgetMap.constFind( item );
if ( it == mItemWidgetMap.constEnd() )
{
@@ -3800,7 +3802,7 @@ void QgsComposer::setSelectionTool()
bool QgsComposer::containsWmsLayer() const
{
- QMap::const_iterator item_it = mItemWidgetMap.constBegin();
+ QMap::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::const_iterator item_it = mItemWidgetMap.constBegin();
+ QMap::const_iterator item_it = mItemWidgetMap.constBegin();
QgsComposerItem* currentItem = nullptr;
QgsComposerMap* currentMap = nullptr;
@@ -3893,7 +3895,7 @@ void QgsComposer::showAdvancedEffectsWarning()
void QgsComposer::cleanupAfterTemplateRead()
{
- QMap::const_iterator itemIt = mItemWidgetMap.constBegin();
+ QMap::const_iterator itemIt = mItemWidgetMap.constBegin();
for ( ; itemIt != mItemWidgetMap.constEnd(); ++itemIt )
{
//update all legends completely
diff --git a/src/app/composer/qgscomposer.h b/src/app/composer/qgscomposer.h
index 05043a3a4f6..664d693ff93 100644
--- a/src/app/composer/qgscomposer.h
+++ b/src/app/composer/qgscomposer.h
@@ -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 mItemWidgetMap;
+ QMap 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;
diff --git a/src/app/composer/qgscomposerarrowwidget.cpp b/src/app/composer/qgscomposerarrowwidget.cpp
index 47effd16247..abaaa6d6f51 100644
--- a/src/app/composer/qgscomposerarrowwidget.cpp
+++ b/src/app/composer/qgscomposerarrowwidget.cpp
@@ -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();
diff --git a/src/app/composer/qgscomposerattributetablewidget.cpp b/src/app/composer/qgscomposerattributetablewidget.cpp
index 963a128d587..a2a264e0b96 100644
--- a/src/app/composer/qgscomposerattributetablewidget.cpp
+++ b/src/app/composer/qgscomposerattributetablewidget.cpp
@@ -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 )
diff --git a/src/app/composer/qgscomposerhtmlwidget.cpp b/src/app/composer/qgscomposerhtmlwidget.cpp
index 5c0a904c856..ca4c48eba1a 100644
--- a/src/app/composer/qgscomposerhtmlwidget.cpp
+++ b/src/app/composer/qgscomposerhtmlwidget.cpp
@@ -31,6 +31,7 @@ QgsComposerHtmlWidget::QgsComposerHtmlWidget( QgsComposerHtml* html, QgsComposer
, mFrame( frame )
{
setupUi( this );
+ setPanelTitle( tr( "HTML properties" ) );
//setup html editor
mHtmlEditor = new QgsCodeEditorHTML( this );
diff --git a/src/app/composer/qgscomposeritemwidget.cpp b/src/app/composer/qgscomposeritemwidget.cpp
index f699d972372..30393dfdaf9 100644
--- a/src/app/composer/qgscomposeritemwidget.cpp
+++ b/src/app/composer/qgscomposeritemwidget.cpp
@@ -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( 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();
+}
diff --git a/src/app/composer/qgscomposeritemwidget.h b/src/app/composer/qgscomposeritemwidget.h
index b4004be3205..defdec92514 100644
--- a/src/app/composer/qgscomposeritemwidget.h
+++ b/src/app/composer/qgscomposeritemwidget.h
@@ -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;
diff --git a/src/app/composer/qgscomposerlabelwidget.cpp b/src/app/composer/qgscomposerlabelwidget.cpp
index 1fd9fdc1807..31d8b80fc96 100644
--- a/src/app/composer/qgscomposerlabelwidget.cpp
+++ b/src/app/composer/qgscomposerlabelwidget.cpp
@@ -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();
diff --git a/src/app/composer/qgscomposerlegendwidget.cpp b/src/app/composer/qgscomposerlegendwidget.cpp
index 2cd9e12452f..6bd43017536 100644
--- a/src/app/composer/qgscomposerlegendwidget.cpp
+++ b/src/app/composer/qgscomposerlegendwidget.cpp
@@ -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();
diff --git a/src/app/composer/qgscomposermapwidget.cpp b/src/app/composer/qgscomposermapwidget.cpp
index 753c5f913ab..82d1569c16c 100644
--- a/src/app/composer/qgscomposermapwidget.cpp
+++ b/src/app/composer/qgscomposermapwidget.cpp
@@ -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( sender() );
+ grid->setLineSymbol( dynamic_cast< QgsLineSymbol* >( w->symbol()->clone() ) );
+ mComposerMap->update();
+}
+
+void QgsComposerMapWidget::cleanUpGridLineStyleSelector( QgsPanelWidget* container )
+{
+ QgsSymbolSelectorWidget* w = qobject_cast( 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( sender() );
+ grid->setMarkerSymbol( dynamic_cast< QgsMarkerSymbol* >( w->symbol()->clone() ) );
+ mComposerMap->update();
+}
+
+void QgsComposerMapWidget::cleanUpGridMarkerStyleSelector( QgsPanelWidget* container )
+{
+ QgsSymbolSelectorWidget* w = qobject_cast( 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( sender() );
+ overview->setFrameSymbol( dynamic_cast< QgsFillSymbol* >( w->symbol()->clone() ) );
+ mComposerMap->update();
+}
+
+void QgsComposerMapWidget::cleanUpOverviewFrameStyleSelector( QgsPanelWidget* container )
+{
+ QgsSymbolSelectorWidget* w = qobject_cast( 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( 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( 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( 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( 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( 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( 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 )
diff --git a/src/app/composer/qgscomposermapwidget.h b/src/app/composer/qgscomposermapwidget.h
index a02a16c3232..727bc4cb347 100644
--- a/src/app/composer/qgscomposermapwidget.h
+++ b/src/app/composer/qgscomposermapwidget.h
@@ -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;
diff --git a/src/app/composer/qgscomposerpicturewidget.cpp b/src/app/composer/qgscomposerpicturewidget.cpp
index b1087196108..cc055d8de15 100644
--- a/src/app/composer/qgscomposerpicturewidget.cpp
+++ b/src/app/composer/qgscomposerpicturewidget.cpp
@@ -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();
diff --git a/src/app/composer/qgscomposerpolygonwidget.cpp b/src/app/composer/qgscomposerpolygonwidget.cpp
index 8a0832814a8..cf20635f5a5 100644
--- a/src/app/composer/qgscomposerpolygonwidget.cpp
+++ b/src/app/composer/qgscomposerpolygonwidget.cpp
@@ -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 );
diff --git a/src/app/composer/qgscomposerpolylinewidget.cpp b/src/app/composer/qgscomposerpolylinewidget.cpp
index f16bef6c823..5e0777713ca 100644
--- a/src/app/composer/qgscomposerpolylinewidget.cpp
+++ b/src/app/composer/qgscomposerpolylinewidget.cpp
@@ -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 );
diff --git a/src/app/composer/qgscomposerscalebarwidget.cpp b/src/app/composer/qgscomposerscalebarwidget.cpp
index 4992ddcbd70..102b6dc1dff 100644
--- a/src/app/composer/qgscomposerscalebarwidget.cpp
+++ b/src/app/composer/qgscomposerscalebarwidget.cpp
@@ -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 );
diff --git a/src/app/composer/qgscomposershapewidget.cpp b/src/app/composer/qgscomposershapewidget.cpp
index fc9770413e4..b076b14cff4 100644
--- a/src/app/composer/qgscomposershapewidget.cpp
+++ b/src/app/composer/qgscomposershapewidget.cpp
@@ -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( sender() );
+ mComposerShape->setShapeStyleSymbol( dynamic_cast< QgsFillSymbol* >( w->symbol() ) );
+}
+
+void QgsComposerShapeWidget::cleanUpSymbolSelector( QgsPanelWidget* container )
+{
+ QgsSymbolSelectorWidget* w = qobject_cast( container );
+ if ( !w )
+ return;
+
+ delete w->symbol();
+ updateShapeStyle();
+ mComposerShape->endCommand();
+}
+
diff --git a/src/app/composer/qgscomposershapewidget.h b/src/app/composer/qgscomposershapewidget.h
index 053af65970c..21b86ea55ba 100644
--- a/src/app/composer/qgscomposershapewidget.h
+++ b/src/app/composer/qgscomposershapewidget.h
@@ -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
diff --git a/src/app/gps/qwtpolar-0.1/qwt_polar_plot.cpp b/src/app/gps/qwtpolar-0.1/qwt_polar_plot.cpp
index 623d6ac7480..b2af0cc441e 100644
--- a/src/app/gps/qwtpolar-0.1/qwt_polar_plot.cpp
+++ b/src/app/gps/qwtpolar-0.1/qwt_polar_plot.cpp
@@ -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
diff --git a/src/app/gps/qwtpolar-1.0/qwt_polar_plot.cpp b/src/app/gps/qwtpolar-1.0/qwt_polar_plot.cpp
index aa6c4041290..add40f7f02f 100644
--- a/src/app/gps/qwtpolar-1.0/qwt_polar_plot.cpp
+++ b/src/app/gps/qwtpolar-1.0/qwt_polar_plot.cpp
@@ -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
diff --git a/src/app/gps/qwtpolar-1.1.1/qwt_polar_plot.cpp b/src/app/gps/qwtpolar-1.1.1/qwt_polar_plot.cpp
index 09cc5403505..b1b8b53dab5 100644
--- a/src/app/gps/qwtpolar-1.1.1/qwt_polar_plot.cpp
+++ b/src/app/gps/qwtpolar-1.1.1/qwt_polar_plot.cpp
@@ -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
diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp
index c7ce395726b..04493279e7a 100644
--- a/src/app/qgisapp.cpp
+++ b/src/app/qgisapp.cpp
@@ -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;
diff --git a/src/app/qgsdiscoverrelationsdlg.cpp b/src/app/qgsdiscoverrelationsdlg.cpp
new file mode 100644
index 00000000000..a524867f3f0
--- /dev/null
+++ b/src/app/qgsdiscoverrelationsdlg.cpp
@@ -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
+
+QgsDiscoverRelationsDlg::QgsDiscoverRelationsDlg( const QList& existingRelations, const QList& 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 QgsDiscoverRelationsDlg::relations() const
+{
+ QList 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() );
+}
\ No newline at end of file
diff --git a/src/app/qgsdiscoverrelationsdlg.h b/src/app/qgsdiscoverrelationsdlg.h
new file mode 100644
index 00000000000..b890b524e12
--- /dev/null
+++ b/src/app/qgsdiscoverrelationsdlg.h
@@ -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
+#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& existingRelations, const QList& layers, QWidget *parent = nullptr );
+
+ /**
+ * Get the selected relations.
+ */
+ QList relations() const;
+
+ private slots:
+ void onSelectionChanged();
+
+ private:
+ QList mLayers;
+ QList mFoundRelations;
+
+ void addRelation( const QgsRelation &rel );
+
+};
+
+#endif // QGSDISCOVERRELATIONSDLG_H
diff --git a/src/app/qgslayerstylingwidget.cpp b/src/app/qgslayerstylingwidget.cpp
index 0d6f575b67e..27c170dadff 100644
--- a/src/app/qgslayerstylingwidget.cpp
+++ b/src/app/qgslayerstylingwidget.cpp
@@ -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( 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( 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;
}
diff --git a/src/app/qgsrelationmanagerdialog.cpp b/src/app/qgsrelationmanagerdialog.cpp
index a7c78d6b69d..04314ada37c 100644
--- a/src/app/qgsrelationmanagerdialog.cpp
+++ b/src/app/qgsrelationmanagerdialog.cpp
@@ -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( 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() )
diff --git a/src/app/qgsrelationmanagerdialog.h b/src/app/qgsrelationmanagerdialog.h
index 8032beaa811..cf7ad5917f8 100644
--- a/src/app/qgsrelationmanagerdialog.h
+++ b/src/app/qgsrelationmanagerdialog.h
@@ -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:
diff --git a/src/browser/main.cpp b/src/browser/main.cpp
index 7fb6d6d9a78..5fb4d3182ca 100644
--- a/src/browser/main.cpp
+++ b/src/browser/main.cpp
@@ -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
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 44d48f8ec79..dd64fdb41d9 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -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}"
diff --git a/src/core/auth/qgsauthmanager.h b/src/core/auth/qgsauthmanager.h
index a6be82feedd..fee03683487 100644
--- a/src/core/auth/qgsauthmanager.h
+++ b/src/core/auth/qgsauthmanager.h
@@ -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; }
diff --git a/src/core/composer/qgscomposeritemcommand.h b/src/core/composer/qgscomposeritemcommand.h
index 0a5a094b4f8..4b931186176 100644
--- a/src/core/composer/qgscomposeritemcommand.h
+++ b/src/core/composer/qgscomposeritemcommand.h
@@ -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,
diff --git a/src/core/composer/qgscomposermultiframecommand.h b/src/core/composer/qgscomposermultiframecommand.h
index cc72fe3e844..255c5065fbf 100644
--- a/src/core/composer/qgscomposermultiframecommand.h
+++ b/src/core/composer/qgscomposermultiframecommand.h
@@ -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 );
diff --git a/src/core/dxf/qgsdxfexport.cpp b/src/core/dxf/qgsdxfexport.cpp
index 76263384de3..4c1d20920c3 100644
--- a/src/core/dxf/qgsdxfexport.cpp
+++ b/src/core/dxf/qgsdxfexport.cpp
@@ -965,12 +965,11 @@ void QgsDxfExport::writeEntities()
}
renderer->startRender( ctx, vl->fields() );
- QStringList attributes = renderer->usedAttributes();
+ QSet 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 );
diff --git a/src/core/qgsaggregatecalculator.cpp b/src/core/qgsaggregatecalculator.cpp
index 46b16b377e2..59d32584ec0 100644
--- a/src/core/qgsaggregatecalculator.cpp
+++ b/src/core/qgsaggregatecalculator.cpp
@@ -71,9 +71,9 @@ QVariant QgsAggregateCalculator::calculate( QgsAggregateCalculator::Aggregate ag
}
}
- QStringList lst;
+ QSet lst;
if ( expression.isNull() )
- lst.append( fieldOrExpression );
+ lst.insert( fieldOrExpression );
else
lst = expression->referencedColumns();
diff --git a/src/core/qgsapplication.cpp b/src/core/qgsapplication.cpp
index 99c1465e2aa..898f9371e4e 100644
--- a/src/core/qgsapplication.cpp
+++ b/src/core/qgsapplication.cpp
@@ -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() );
}
}
diff --git a/src/core/qgsapplication.h b/src/core/qgsapplication.h
index 9bb559f7296..cb468852a3f 100644
--- a/src/core/qgsapplication.h
+++ b/src/core/qgsapplication.h
@@ -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
diff --git a/src/core/qgsdatadefined.cpp b/src/core/qgsdatadefined.cpp
index c09d0c3fdd7..8600a4bca7f 100644
--- a/src/core/qgsdatadefined.cpp
+++ b/src/core/qgsdatadefined.cpp
@@ -187,7 +187,7 @@ QgsExpression *QgsDataDefined::expression()
return d->expression;
}
-QStringList QgsDataDefined::referencedColumns( const QgsExpressionContext& context )
+QSet QgsDataDefined::referencedColumns( const QgsExpressionContext& context )
{
if ( !d->exprRefColumns.isEmpty() )
{
diff --git a/src/core/qgsdatadefined.h b/src/core/qgsdatadefined.h
index 27ba85ba921..285fe6e2a08 100644
--- a/src/core/qgsdatadefined.h
+++ b/src/core/qgsdatadefined.h
@@ -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 referencedColumns( const QgsExpressionContext& context = QgsExpressionContext() );
/**
* Get the field which this QgsDataDefined represents. Be aware that this may return
diff --git a/src/core/qgsdatadefined_p.h b/src/core/qgsdatadefined_p.h
index 23d83db9139..8b7d4c1ede3 100644
--- a/src/core/qgsdatadefined_p.h
+++ b/src/core/qgsdatadefined_p.h
@@ -80,7 +80,7 @@ class QgsDataDefinedPrivate : public QSharedData
QString field;
bool expressionPrepared;
- QStringList exprRefColumns;
+ QSet exprRefColumns;
};
/// @endcond
diff --git a/src/core/qgsexpression.cpp b/src/core/qgsexpression.cpp
index c8ac0939ce2..36f6133753a 100644
--- a/src/core/qgsexpression.cpp
+++ b/src/core/qgsexpression.cpp
@@ -3427,43 +3427,43 @@ const QList& 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(), false, QStringList() << "$pi" )
+ << new StaticFunction( "to_int", 1, fcnToInt, "Conversions", QString(), false, QSet(), false, QStringList() << "toint" )
+ << new StaticFunction( "to_real", 1, fcnToReal, "Conversions", QString(), false, QSet(), false, QStringList() << "toreal" )
+ << new StaticFunction( "to_string", 1, fcnToString, "Conversions", QString(), false, QSet(), false, QStringList() << "tostring" )
+ << new StaticFunction( "to_datetime", 1, fcnToDateTime, "Conversions", QString(), false, QSet(), false, QStringList() << "todatetime" )
+ << new StaticFunction( "to_date", 1, fcnToDate, "Conversions", QString(), false, QSet(), false, QStringList() << "todate" )
+ << new StaticFunction( "to_time", 1, fcnToTime, "Conversions", QString(), false, QSet(), false, QStringList() << "totime" )
+ << new StaticFunction( "to_interval", 1, fcnToInterval, "Conversions", QString(), false, QSet(), false, QStringList() << "tointerval" )
+ << new StaticFunction( "coalesce", -1, fcnCoalesce, "Conditionals", QString(), false, QSet(), false, QStringList(), true )
+ << new StaticFunction( "if", 3, fcnIf, "Conditionals", QString(), False, QSet(), 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(), 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() << 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(), true )
+ << new StaticFunction( "count_distinct", aggParams, fcnAggregateCountDistinct, "Aggregates", QString(), False, QSet(), true )
+ << new StaticFunction( "count_missing", aggParams, fcnAggregateCountMissing, "Aggregates", QString(), False, QSet(), true )
+ << new StaticFunction( "minimum", aggParams, fcnAggregateMin, "Aggregates", QString(), False, QSet(), true )
+ << new StaticFunction( "maximum", aggParams, fcnAggregateMax, "Aggregates", QString(), False, QSet(), true )
+ << new StaticFunction( "sum", aggParams, fcnAggregateSum, "Aggregates", QString(), False, QSet(), true )
+ << new StaticFunction( "mean", aggParams, fcnAggregateMean, "Aggregates", QString(), False, QSet(), true )
+ << new StaticFunction( "median", aggParams, fcnAggregateMedian, "Aggregates", QString(), False, QSet(), true )
+ << new StaticFunction( "stdev", aggParams, fcnAggregateStdev, "Aggregates", QString(), False, QSet(), true )
+ << new StaticFunction( "range", aggParams, fcnAggregateRange, "Aggregates", QString(), False, QSet(), true )
+ << new StaticFunction( "minority", aggParams, fcnAggregateMinority, "Aggregates", QString(), False, QSet(), true )
+ << new StaticFunction( "majority", aggParams, fcnAggregateMajority, "Aggregates", QString(), False, QSet(), true )
+ << new StaticFunction( "q1", aggParams, fcnAggregateQ1, "Aggregates", QString(), False, QSet(), true )
+ << new StaticFunction( "q3", aggParams, fcnAggregateQ3, "Aggregates", QString(), False, QSet(), true )
+ << new StaticFunction( "iqr", aggParams, fcnAggregateIQR, "Aggregates", QString(), False, QSet(), true )
+ << new StaticFunction( "min_length", aggParams, fcnAggregateMinLength, "Aggregates", QString(), False, QSet(), true )
+ << new StaticFunction( "max_length", aggParams, fcnAggregateMaxLength, "Aggregates", QString(), False, QSet(), true )
+ << new StaticFunction( "collect", aggParams, fcnAggregateCollectGeometry, "Aggregates", QString(), False, QSet(), true )
+ << new StaticFunction( "concatenate", aggParams << Parameter( "concatenator", true ), fcnAggregateStringConcat, "Aggregates", QString(), False, QSet(), 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(), 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::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(), 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::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(), false, QStringList() << "xat" << "x_at" )
+ << new StaticFunction( "$y_at", 1, fcnYat, "GeometryGroup", QString(), true, QSet(), false, QStringList() << "yat" << "y_at" )
+ << new StaticFunction( "x_min", 1, fcnXMin, "GeometryGroup", QString(), false, QSet(), false, QStringList() << "xmin" )
+ << new StaticFunction( "x_max", 1, fcnXMax, "GeometryGroup", QString(), false, QSet(), false, QStringList() << "xmax" )
+ << new StaticFunction( "y_min", 1, fcnYMin, "GeometryGroup", QString(), false, QSet(), false, QStringList() << "ymin" )
+ << new StaticFunction( "y_max", 1, fcnYMax, "GeometryGroup", QString(), false, QSet(), false, QStringList() << "ymax" )
+ << new StaticFunction( "geom_from_wkt", 1, fcnGeomFromWKT, "GeometryGroup", QString(), false, QSet(), false, QStringList() << "geomFromWKT" )
+ << new StaticFunction( "geom_from_gml", 1, fcnGeomFromGML, "GeometryGroup", QString(), false, QSet(), 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(), 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::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(), 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(), 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(), 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::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(), false, QStringList() << "$uuid" )
+ << new StaticFunction( "get_feature", 3, fcnGetFeature, "Record", QString(), false, QSet(), 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() << QgsFeatureRequest::AllAttributes )
+ << new StaticFunction( "attribute", 2, fcnAttribute, "Record", QString(), false, QSet() << 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 QgsExpression::referencedColumns() const
{
if ( !d->mRootNode )
- return QStringList();
+ return QSet();
- 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 QgsExpression::referencedAttributeIndexes( const QgsFields& fields ) const
@@ -3829,10 +3821,10 @@ QSet QgsExpression::referencedAttributeIndexes( const QgsFields& fields ) c
if ( !d->mRootNode )
return QSet();
- QStringList referencedFields = d->mRootNode->referencedColumns();
+ const QSet referencedFields = d->mRootNode->referencedColumns();
QSet 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 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 QgsExpression::NodeFunction::referencedColumns() const
{
Function* fd = Functions()[mFnIndex];
- QStringList functionColumns = fd->referencedColumns();
+ QSet 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 QgsExpression::NodeCondition::referencedColumns() const
{
- QStringList lst;
+ QSet 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 QgsExpression::NodeInOperator::referencedColumns() const
+{
+ QSet 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;
+}
diff --git a/src/core/qgsexpression.h b/src/core/qgsexpression.h
index 663f3e47e88..2216afd0b6d 100644
--- a/src/core/qgsexpression.h
+++ b/src/core/qgsexpression.h
@@ -183,7 +183,7 @@ class CORE_EXPORT QgsExpression
*
* TODO QGIS3: Return QSet
*/
- QStringList referencedColumns() const;
+ QSet 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& referencedColumns = QSet(),
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& referencedColumns = QSet(),
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 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 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& referencedColumns = QSet(),
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& referencedColumns = QSet(),
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 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 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 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 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 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 referencedColumns() const override { return QSet(); }
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 referencedColumns() const override { return QSet() << 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 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
diff --git a/src/core/qgsexpressioncontext.h b/src/core/qgsexpressioncontext.h
index c7d33787e10..620f74b1b44 100644
--- a/src/core/qgsexpressioncontext.h
+++ b/src/core/qgsexpressioncontext.h
@@ -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& referencedColumns = QSet(),
bool lazyEval = false,
bool handlesNull = false,
bool isContextual = true )
diff --git a/src/core/qgsexpressionfieldbuffer.cpp b/src/core/qgsexpressionfieldbuffer.cpp
index 84766c79ad9..9b73009998e 100644
--- a/src/core/qgsexpressionfieldbuffer.cpp
+++ b/src/core/qgsexpressionfieldbuffer.cpp
@@ -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 );
diff --git a/src/core/qgsexpressionfieldbuffer.h b/src/core/qgsexpressionfieldbuffer.h
index 6ac2d46a419..b73c4bd5f37 100644
--- a/src/core/qgsexpressionfieldbuffer.h
+++ b/src/core/qgsexpressionfieldbuffer.h
@@ -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
*
diff --git a/src/core/qgsfeaturerequest.cpp b/src/core/qgsfeaturerequest.cpp
index a816b2ec229..8c010d7358c 100644
--- a/src/core/qgsfeaturerequest.cpp
+++ b/src/core/qgsfeaturerequest.cpp
@@ -216,6 +216,27 @@ QgsFeatureRequest& QgsFeatureRequest::setSubsetOfAttributes( const QStringList&
return *this;
}
+QgsFeatureRequest& QgsFeatureRequest::setSubsetOfAttributes( const QSet& 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 QgsFeatureRequest::OrderBy::usedAttributes() const
{
const OrderByClause& clause = *it;
- usedAttributes.unite( clause.expression().referencedColumns().toSet() );
+ usedAttributes.unite( clause.expression().referencedColumns() );
}
return usedAttributes;
diff --git a/src/core/qgsfeaturerequest.h b/src/core/qgsfeaturerequest.h
index 006deae7b91..7c8d0a128ad 100644
--- a/src/core/qgsfeaturerequest.h
+++ b/src/core/qgsfeaturerequest.h
@@ -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& attrNames, const QgsFields& fields );
+
//! Set a simplification method for geometries that will be fetched
//! @note added in 2.2
QgsFeatureRequest& setSimplifyMethod( const QgsSimplifyMethod& simplifyMethod );
diff --git a/src/core/qgsogcutils.cpp b/src/core/qgsogcutils.cpp
index bd4a2584652..693cae80ae0 100644
--- a/src/core/qgsogcutils.cpp
+++ b/src/core/qgsogcutils.cpp
@@ -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( 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
+ // setup wildCards to
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
+ // setup wildCards to
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 );
diff --git a/src/core/qgsogrutils.cpp b/src/core/qgsogrutils.cpp
index a1833aa1741..3f1da65e0be 100644
--- a/src/core/qgsogrutils.cpp
+++ b/src/core/qgsogrutils.cpp
@@ -274,7 +274,7 @@ QgsFeatureList QgsOgrUtils::stringToFeatureList( const QString& string, const Qg
}
OGR_DS_Destroy( hDS );
- VSIUnlink( "/vsimem/clipboard.dat" );
+ VSIUnlink( TO8( randomFileName ) );
return features;
}
diff --git a/src/core/qgspallabeling.cpp b/src/core/qgspallabeling.cpp
index af7c65606f4..e3f33f5754a 100644
--- a/src/core/qgspallabeling.cpp
+++ b/src/core/qgspallabeling.cpp
@@ -3946,7 +3946,7 @@ void QgsPalLabeling::clearActiveLayer( const QString &layerID )
}
-int QgsPalLabeling::prepareLayer( QgsVectorLayer* layer, QStringList& attrNames, QgsRenderContext& ctx )
+int QgsPalLabeling::prepareLayer( QgsVectorLayer* layer, QSet& attrNames, QgsRenderContext& ctx )
{
if ( !willUseLayer( layer ) )
{
@@ -3974,7 +3974,7 @@ int QgsPalLabeling::prepareLayer( QgsVectorLayer* layer, QStringList& attrNames,
return 1; // init successful
}
-int QgsPalLabeling::prepareDiagramLayer( QgsVectorLayer* layer, QStringList& attrNames, QgsRenderContext& ctx )
+int QgsPalLabeling::prepareDiagramLayer( QgsVectorLayer* layer, QSet& attrNames, QgsRenderContext& ctx )
{
QgsVectorLayerDiagramProvider* dp = new QgsVectorLayerDiagramProvider( layer, false );
// need to be added before calling prepare() - uses map settings from engine
diff --git a/src/core/qgspallabeling.h b/src/core/qgspallabeling.h
index 7e934e8c363..ef3635b10d5 100644
--- a/src/core/qgspallabeling.h
+++ b/src/core/qgspallabeling.h
@@ -135,11 +135,11 @@ class CORE_EXPORT 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& 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& attrNames, QgsRenderContext &ctx )
{ Q_UNUSED( layer ); Q_UNUSED( attrNames ); Q_UNUSED( ctx ); return 0; }
//! called for every feature
@@ -1037,10 +1037,10 @@ class CORE_EXPORT QgsPalLabeling : public QgsLabelingEngineInterface
//! clears data defined objects from PAL layer settings for a registered layer
virtual void clearActiveLayer( const QString& layerID ) override;
//! hook called when drawing layer before issuing select()
- virtual int prepareLayer( QgsVectorLayer* layer, QStringList &attrNames, QgsRenderContext& ctx ) override;
+ virtual int prepareLayer( QgsVectorLayer* layer, QSet& attrNames, QgsRenderContext& ctx ) override;
//! adds a diagram layer to the labeling engine
//! @note added in QGIS 2.12
- virtual int prepareDiagramLayer( QgsVectorLayer* layer, QStringList& attrNames, QgsRenderContext& ctx ) override;
+ virtual int prepareDiagramLayer( QgsVectorLayer* layer, QSet& attrNames, QgsRenderContext& ctx ) override;
/** Register a feature for labelling.
* @param layerID string identifying layer associated with label
diff --git a/src/core/qgsprojectproperty.cpp b/src/core/qgsprojectproperty.cpp
index df756ceb406..221edea3d9f 100644
--- a/src/core/qgsprojectproperty.cpp
+++ b/src/core/qgsprojectproperty.cpp
@@ -21,6 +21,18 @@
#include
#include
+QgsProperty::QgsProperty()
+{
+}
+
+QgsProperty::~QgsProperty()
+{
+}
+
+QgsPropertyValue::~QgsPropertyValue()
+{
+}
+
void QgsPropertyValue::dump( int tabs ) const
{
QString tabString;
diff --git a/src/core/qgsprojectproperty.h b/src/core/qgsprojectproperty.h
index 0a4b6e8b4d4..8eae560b0fe 100644
--- a/src/core/qgsprojectproperty.h
+++ b/src/core/qgsprojectproperty.h
@@ -47,12 +47,8 @@ class QDomDocument;
class CORE_EXPORT QgsProperty
{
public:
-
- QgsProperty()
- {}
-
- virtual ~QgsProperty()
- {}
+ QgsProperty();
+ virtual ~QgsProperty();
/** Dumps out the keys and values
*
@@ -125,7 +121,7 @@ class CORE_EXPORT QgsPropertyValue : public QgsProperty
: value_( value )
{}
- virtual ~QgsPropertyValue() {}
+ virtual ~QgsPropertyValue();
/** Returns true if is a QgsPropertyKey */
virtual bool isKey() const override { return false; }
@@ -208,7 +204,7 @@ class CORE_EXPORT QgsPropertyKey : public QgsProperty
/// add the given property key
- QgsPropertyKey * addKey( const QString & keyName )
+ QgsPropertyKey *addKey( const QString & keyName )
{
delete mProperties.take( keyName );
mProperties.insert( keyName, new QgsPropertyKey( keyName ) );
diff --git a/src/core/qgsrelation.cpp b/src/core/qgsrelation.cpp
index bdc3997d628..b2c67f8ee9e 100644
--- a/src/core/qgsrelation.cpp
+++ b/src/core/qgsrelation.cpp
@@ -248,6 +248,16 @@ QString QgsRelation::id() const
return mRelationId;
}
+void QgsRelation::generateId()
+{
+ mRelationId = QString( "%1_%2_%3_%4" )
+ .arg( referencingLayerId(),
+ mFieldPairs.at( 0 ).referencingField(),
+ referencedLayerId(),
+ mFieldPairs.at( 0 ).referencedField() );
+ updateRelationStatus();
+}
+
QString QgsRelation::referencingLayerId() const
{
return mReferencingLayerId;
@@ -301,6 +311,11 @@ bool QgsRelation::isValid() const
return mValid;
}
+bool QgsRelation::hasEqualDefinition( const QgsRelation& other ) const
+{
+ return mReferencedLayerId == other.mReferencedLayerId && mReferencingLayerId == other.mReferencingLayerId && mFieldPairs == other.mFieldPairs;
+}
+
void QgsRelation::updateRelationStatus()
{
const QMap& mapLayers = QgsMapLayerRegistry::instance()->mapLayers();
diff --git a/src/core/qgsrelation.h b/src/core/qgsrelation.h
index 26fe3d56029..3cc48dcfe20 100644
--- a/src/core/qgsrelation.h
+++ b/src/core/qgsrelation.h
@@ -57,6 +57,8 @@ class CORE_EXPORT QgsRelation
QString referencingField() const { return first; }
//! Get the name of the referenced (parent) field
QString referencedField() const { return second; }
+
+ bool operator==( const FieldPair& other ) const { return first == other.first && second == other.second; }
};
/**
@@ -210,6 +212,12 @@ class CORE_EXPORT 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
@@ -272,6 +280,15 @@ class CORE_EXPORT 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.
diff --git a/src/core/qgsrelationmanager.cpp b/src/core/qgsrelationmanager.cpp
index e077178c362..48e3d132e1c 100644
--- a/src/core/qgsrelationmanager.cpp
+++ b/src/core/qgsrelationmanager.cpp
@@ -19,6 +19,7 @@
#include "qgslogger.h"
#include "qgsmaplayerregistry.h"
#include "qgsproject.h"
+#include "qgsvectordataprovider.h"
#include "qgsvectorlayer.h"
QgsRelationManager::QgsRelationManager( QgsProject* project )
@@ -217,3 +218,28 @@ void QgsRelationManager::layersRemoved( const QStringList& layers )
emit changed();
}
}
+
+static bool hasRelationWithEqualDefinition( const QList& existingRelations, const QgsRelation& relation )
+{
+ Q_FOREACH ( const QgsRelation& cur, existingRelations )
+ {
+ if ( cur.hasEqualDefinition( relation ) ) return true;
+ }
+ return false;
+}
+
+QList QgsRelationManager::discoverRelations( const QList& existingRelations, const QList& layers )
+{
+ QList result;
+ Q_FOREACH ( const QgsVectorLayer* layer, layers )
+ {
+ Q_FOREACH ( const QgsRelation& relation, layer->dataProvider()->discoverRelations( layer, layers ) )
+ {
+ if ( !hasRelationWithEqualDefinition( existingRelations, relation ) )
+ {
+ result.append( relation );
+ }
+ }
+ }
+ return result;
+}
diff --git a/src/core/qgsrelationmanager.h b/src/core/qgsrelationmanager.h
index ff4d3c41c27..30450c6686d 100644
--- a/src/core/qgsrelationmanager.h
+++ b/src/core/qgsrelationmanager.h
@@ -117,6 +117,16 @@ class CORE_EXPORT QgsRelationManager : public QObject
*/
QList referencedRelations( QgsVectorLayer *layer = nullptr ) 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 discoverRelations( const QList& existingRelations, const QList& layers );
+
signals:
/** This signal is emitted when the relations were loaded after reading a project */
void relationsLoaded();
diff --git a/src/core/qgsrulebasedlabeling.cpp b/src/core/qgsrulebasedlabeling.cpp
index 840843a8af9..1846db12d88 100644
--- a/src/core/qgsrulebasedlabeling.cpp
+++ b/src/core/qgsrulebasedlabeling.cpp
@@ -32,7 +32,7 @@ QgsVectorLayerLabelProvider *QgsRuleBasedLabelProvider::createProvider( QgsVecto
return new QgsVectorLayerLabelProvider( layer, providerId, withFeatureLoop, settings );
}
-bool QgsRuleBasedLabelProvider::prepare( const QgsRenderContext& context, QStringList& attributeNames )
+bool QgsRuleBasedLabelProvider::prepare( const QgsRenderContext& context, QSet& attributeNames )
{
Q_FOREACH ( QgsVectorLayerLabelProvider* provider, mSubProviders )
provider->setEngine( mEngine );
@@ -264,7 +264,7 @@ void QgsRuleBasedLabeling::Rule::createSubProviders( QgsVectorLayer* layer, QgsR
}
}
-void QgsRuleBasedLabeling::Rule::prepare( const QgsRenderContext& context, QStringList& attributeNames, QgsRuleBasedLabeling::RuleToProviderMap& subProviders )
+void QgsRuleBasedLabeling::Rule::prepare( const QgsRenderContext& context, QSet& attributeNames, QgsRuleBasedLabeling::RuleToProviderMap& subProviders )
{
if ( mSettings )
{
@@ -278,7 +278,7 @@ void QgsRuleBasedLabeling::Rule::prepare( const QgsRenderContext& context, QStri
if ( mFilter )
{
- attributeNames << mFilter->referencedColumns();
+ attributeNames.unite( mFilter->referencedColumns() );
mFilter->prepare( &context.expressionContext() );
}
diff --git a/src/core/qgsrulebasedlabeling.h b/src/core/qgsrulebasedlabeling.h
index 3d778f4656a..addc6449500 100644
--- a/src/core/qgsrulebasedlabeling.h
+++ b/src/core/qgsrulebasedlabeling.h
@@ -238,7 +238,7 @@ class CORE_EXPORT QgsRuleBasedLabeling : public QgsAbstractVectorLayerLabeling
void subProviderIds( QStringList& list ) const;
//! call prepare() on sub-providers and populate attributeNames
- void prepare( const QgsRenderContext& context, QStringList& attributeNames, RuleToProviderMap& subProviders );
+ void prepare( const QgsRenderContext& context, QSet& attributeNames, RuleToProviderMap& subProviders );
//! register individual features
RegisterResult registerFeature( QgsFeature& feature, QgsRenderContext& context, RuleToProviderMap& subProviders, QgsGeometry* obstacleGeometry = nullptr );
@@ -330,7 +330,7 @@ class CORE_EXPORT QgsRuleBasedLabelProvider : public QgsVectorLayerLabelProvider
// reimplemented
- virtual bool prepare( const QgsRenderContext& context, QStringList& attributeNames ) override;
+ virtual bool prepare( const QgsRenderContext& context, QSet& attributeNames ) override;
virtual void registerFeature( QgsFeature& feature, QgsRenderContext& context, QgsGeometry* obstacleGeometry = nullptr ) override;
diff --git a/src/core/qgsvectordataprovider.cpp b/src/core/qgsvectordataprovider.cpp
index 5a0f73229a9..b689183db89 100644
--- a/src/core/qgsvectordataprovider.cpp
+++ b/src/core/qgsvectordataprovider.cpp
@@ -718,3 +718,8 @@ QgsGeometry* QgsVectorDataProvider::convertToProviderType( const QgsGeometry& ge
}
QStringList QgsVectorDataProvider::smEncodings;
+
+QList QgsVectorDataProvider::discoverRelations( const QgsVectorLayer*, const QList& ) const
+{
+ return QList();
+}
\ No newline at end of file
diff --git a/src/core/qgsvectordataprovider.h b/src/core/qgsvectordataprovider.h
index 7d092d5e6a7..2addd3ac4c9 100644
--- a/src/core/qgsvectordataprovider.h
+++ b/src/core/qgsvectordataprovider.h
@@ -28,6 +28,7 @@ class QTextCodec;
#include "qgsfeature.h"
#include "qgsaggregatecalculator.h"
#include "qgsmaplayerdependency.h"
+#include "qgsrelation.h"
typedef QList QgsAttributeList;
typedef QSet QgsAttributeIds;
@@ -433,6 +434,15 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider
*/
virtual QSet 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 discoverRelations( const QgsVectorLayer* self, const QList& layers ) const;
+
signals:
/** Signals an error in this provider */
void raiseError( const QString& msg );
diff --git a/src/core/qgsvectorfilewriter.cpp b/src/core/qgsvectorfilewriter.cpp
index 482fcd65856..b74dce3c74c 100644
--- a/src/core/qgsvectorfilewriter.cpp
+++ b/src/core/qgsvectorfilewriter.cpp
@@ -2863,13 +2863,13 @@ void QgsVectorFileWriter::addRendererAttributes( QgsVectorLayer* vl, QgsAttribut
QgsFeatureRenderer* renderer = symbologyRenderer( vl );
if ( renderer )
{
- QList rendererAttributes = renderer->usedAttributes();
- for ( int i = 0; i < rendererAttributes.size(); ++i )
+ const QSet rendererAttributes = renderer->usedAttributes();
+ for ( const QString& attr : rendererAttributes )
{
- int index = vl->fields().lookupField( rendererAttributes.at( i ) );
+ int index = vl->fields().lookupField( attr );
if ( index != -1 )
{
- attList.push_back( vl->fields().lookupField( rendererAttributes.at( i ) ) );
+ attList.append( index );
}
}
}
diff --git a/src/core/qgsvectorlayer.cpp b/src/core/qgsvectorlayer.cpp
index 56623d5d51b..23c0cabfb07 100644
--- a/src/core/qgsvectorlayer.cpp
+++ b/src/core/qgsvectorlayer.cpp
@@ -2125,10 +2125,41 @@ void QgsVectorLayer::removeFieldAlias( int attIndex )
bool QgsVectorLayer::renameAttribute( int index, const QString& newName )
{
- if ( !mEditBuffer || !mDataProvider )
+ if ( index < 0 || index >= fields().count() )
return false;
- return mEditBuffer->renameAttribute( index, newName );
+ switch ( mFields.fieldOrigin( index ) )
+ {
+ case QgsFields::OriginExpression:
+ {
+ if ( mExpressionFieldBuffer )
+ {
+ int oi = mFields.fieldOriginIndex( index );
+ mExpressionFieldBuffer->renameExpression( oi, newName );
+ updateFields();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ case QgsFields::OriginProvider:
+ case QgsFields::OriginEdit:
+
+ if ( !mEditBuffer || !mDataProvider )
+ return false;
+
+ return mEditBuffer->renameAttribute( index, newName );
+
+ case QgsFields::OriginJoin:
+ case QgsFields::OriginUnknown:
+ return false;
+
+ }
+
+ return false; // avoid warning
}
void QgsVectorLayer::setFieldAlias( int attIndex, const QString& aliasString )
@@ -3306,9 +3337,9 @@ QList QgsVectorLayer::getValues( const QString &fieldOrExpression, boo
}
QgsFeature f;
- QStringList lst;
+ QSet lst;
if ( expression.isNull() )
- lst.append( fieldOrExpression );
+ lst.insert( fieldOrExpression );
else
lst = expression->referencedColumns();
diff --git a/src/core/qgsvectorlayerdiagramprovider.cpp b/src/core/qgsvectorlayerdiagramprovider.cpp
index ddaf4f97e12..6e9ada148c8 100644
--- a/src/core/qgsvectorlayerdiagramprovider.cpp
+++ b/src/core/qgsvectorlayerdiagramprovider.cpp
@@ -87,7 +87,7 @@ QList QgsVectorLayerDiagramProvider::labelFeatures( QgsRenderC
return mFeatures;
}
- QStringList attributeNames;
+ QSet attributeNames;
if ( !prepare( context, attributeNames ) )
return QList();
@@ -155,7 +155,7 @@ void QgsVectorLayerDiagramProvider::drawLabel( QgsRenderContext& context, pal::L
}
-bool QgsVectorLayerDiagramProvider::prepare( const QgsRenderContext& context, QStringList& attributeNames )
+bool QgsVectorLayerDiagramProvider::prepare( const QgsRenderContext& context, QSet& attributeNames )
{
QgsDiagramLayerSettings& s2 = mSettings;
const QgsMapSettings& mapSettings = mEngine->mapSettings();
@@ -177,11 +177,7 @@ bool QgsVectorLayerDiagramProvider::prepare( const QgsRenderContext& context, QS
s2.setRenderer( mDiagRenderer );
//add attributes needed by the diagram renderer
- Q_FOREACH ( const QString& field, s2.referencedFields( context.expressionContext(), mFields ) )
- {
- if ( !attributeNames.contains( field ) )
- attributeNames << field;
- }
+ attributeNames.unite( s2.referencedFields( context.expressionContext(), mFields ) );
return true;
}
diff --git a/src/core/qgsvectorlayerdiagramprovider.h b/src/core/qgsvectorlayerdiagramprovider.h
index 7d93dcfd41d..8db71242163 100644
--- a/src/core/qgsvectorlayerdiagramprovider.h
+++ b/src/core/qgsvectorlayerdiagramprovider.h
@@ -85,7 +85,7 @@ class CORE_EXPORT QgsVectorLayerDiagramProvider : public QgsAbstractLabelProvide
* @param attributeNames list of attribute names to which additional required attributes shall be added
* @return Whether the preparation was successful - if not, the provider shall not be used
*/
- virtual bool prepare( const QgsRenderContext& context, QStringList& attributeNames );
+ virtual bool prepare( const QgsRenderContext& context, QSet& attributeNames );
/**
* Register a feature for labeling as one or more QgsLabelFeature objects stored into mFeatures
diff --git a/src/core/qgsvectorlayerlabelprovider.cpp b/src/core/qgsvectorlayerlabelprovider.cpp
index 3dedaab2520..0ce998f1ae9 100644
--- a/src/core/qgsvectorlayerlabelprovider.cpp
+++ b/src/core/qgsvectorlayerlabelprovider.cpp
@@ -128,7 +128,7 @@ QgsVectorLayerLabelProvider::~QgsVectorLayerLabelProvider()
}
-bool QgsVectorLayerLabelProvider::prepare( const QgsRenderContext& context, QStringList& attributeNames )
+bool QgsVectorLayerLabelProvider::prepare( const QgsRenderContext& context, QSet& attributeNames )
{
QgsPalLayerSettings& lyr = mSettings;
const QgsMapSettings& mapSettings = mEngine->mapSettings();
@@ -178,12 +178,12 @@ bool QgsVectorLayerLabelProvider::prepare( const QgsRenderContext& context, QStr
Q_FOREACH ( const QString& name, exp->referencedColumns() )
{
QgsDebugMsgLevel( "REFERENCED COLUMN = " + name, 4 );
- attributeNames.append( name );
+ attributeNames.insert( name );
}
}
else
{
- attributeNames.append( lyr.fieldName );
+ attributeNames.insert( lyr.fieldName );
}
// add field indices of data defined expression or field
@@ -198,12 +198,12 @@ bool QgsVectorLayerLabelProvider::prepare( const QgsRenderContext& context, QStr
// this will return columns for expressions or field name, depending upon what is set to be used
// this also prepares any expressions, too
- QStringList cols = dd->referencedColumns( context.expressionContext() );
+ QSet cols = dd->referencedColumns( context.expressionContext() );
//QgsDebugMsgLevel( QString( "Data defined referenced columns:" ) + cols.join( "," ), 4 );
Q_FOREACH ( const QString& name, cols )
{
- attributeNames.append( name );
+ attributeNames.insert( name );
}
}
}
@@ -258,7 +258,7 @@ QList QgsVectorLayerLabelProvider::labelFeatures( QgsRenderCon
return mLabels;
}
- QStringList attrNames;
+ QSet attrNames;
if ( !prepare( ctx, attrNames ) )
return QList();
diff --git a/src/core/qgsvectorlayerlabelprovider.h b/src/core/qgsvectorlayerlabelprovider.h
index c24adc42225..c3b88ca2f7f 100644
--- a/src/core/qgsvectorlayerlabelprovider.h
+++ b/src/core/qgsvectorlayerlabelprovider.h
@@ -66,7 +66,7 @@ class CORE_EXPORT QgsVectorLayerLabelProvider : public QgsAbstractLabelProvider
* @param attributeNames list of attribute names to which additional required attributes shall be added
* @return Whether the preparation was successful - if not, the provider shall not be used
*/
- virtual bool prepare( const QgsRenderContext& context, QStringList& attributeNames );
+ virtual bool prepare( const QgsRenderContext& context, QSet& attributeNames );
/**
* Register a feature for labeling as one or more QgsLabelFeature objects stored into mLabels
diff --git a/src/core/qgsvectorlayerrenderer.cpp b/src/core/qgsvectorlayerrenderer.cpp
index f07ed9fc773..9aec1cf58cb 100644
--- a/src/core/qgsvectorlayerrenderer.cpp
+++ b/src/core/qgsvectorlayerrenderer.cpp
@@ -534,7 +534,7 @@ void QgsVectorLayerRenderer::stopRenderer( QgsSingleSymbolRenderer* selRenderer
-void QgsVectorLayerRenderer::prepareLabeling( QgsVectorLayer* layer, QStringList& attributeNames )
+void QgsVectorLayerRenderer::prepareLabeling( QgsVectorLayer* layer, QSet& attributeNames )
{
if ( !mContext.labelingEngine() )
{
@@ -591,7 +591,7 @@ void QgsVectorLayerRenderer::prepareLabeling( QgsVectorLayer* layer, QStringList
}
}
-void QgsVectorLayerRenderer::prepareDiagrams( QgsVectorLayer* layer, QStringList& attributeNames )
+void QgsVectorLayerRenderer::prepareDiagrams( QgsVectorLayer* layer, QSet& attributeNames )
{
if ( !mContext.labelingEngine() )
{
diff --git a/src/core/qgsvectorlayerrenderer.h b/src/core/qgsvectorlayerrenderer.h
index 3a4ba17bf7c..a74ef62dfef 100644
--- a/src/core/qgsvectorlayerrenderer.h
+++ b/src/core/qgsvectorlayerrenderer.h
@@ -82,8 +82,8 @@ class QgsVectorLayerRenderer : public QgsMapLayerRenderer
@param layer diagram layer
@param attributeNames attributes needed for labeling and diagrams will be added to the list
*/
- void prepareLabeling( QgsVectorLayer* layer, QStringList& attributeNames );
- void prepareDiagrams( QgsVectorLayer* layer, QStringList& attributeNames );
+ void prepareLabeling( QgsVectorLayer* layer, QSet& attributeNames );
+ void prepareDiagrams( QgsVectorLayer* layer, QSet& attributeNames );
/** Draw layer with renderer V2. QgsFeatureRenderer::startRender() needs to be called before using this method
*/
@@ -122,7 +122,7 @@ class QgsVectorLayerRenderer : public QgsMapLayerRenderer
QgsWkbTypes::GeometryType mGeometryType;
- QStringList mAttrNames;
+ QSet mAttrNames;
//! used with old labeling engine (QgsPalLabeling): whether labeling is enabled
bool mLabeling;
diff --git a/src/core/symbology-ng/qgs25drenderer.cpp b/src/core/symbology-ng/qgs25drenderer.cpp
index 7f9bbcda1d3..5fc3ea2b11b 100644
--- a/src/core/symbology-ng/qgs25drenderer.cpp
+++ b/src/core/symbology-ng/qgs25drenderer.cpp
@@ -146,9 +146,9 @@ void Qgs25DRenderer::stopRender( QgsRenderContext& context )
mSymbol->stopRender( context );
}
-QList Qgs25DRenderer::usedAttributes()
+QSet Qgs25DRenderer::usedAttributes() const
{
- return mSymbol->usedAttributes().toList();
+ return mSymbol->usedAttributes();
}
QgsFeatureRenderer* Qgs25DRenderer::clone() const
diff --git a/src/core/symbology-ng/qgs25drenderer.h b/src/core/symbology-ng/qgs25drenderer.h
index 6d0a9a438d6..3708cd1da94 100644
--- a/src/core/symbology-ng/qgs25drenderer.h
+++ b/src/core/symbology-ng/qgs25drenderer.h
@@ -39,7 +39,7 @@ class CORE_EXPORT Qgs25DRenderer : public QgsFeatureRenderer
void startRender( QgsRenderContext& context, const QgsFields& fields ) override;
void stopRender( QgsRenderContext& context ) override;
- QList usedAttributes() override;
+ QSet usedAttributes() const override;
QgsFeatureRenderer* clone() const override;
virtual QgsSymbol* symbolForFeature( QgsFeature& feature, QgsRenderContext& context ) override;
diff --git a/src/core/symbology-ng/qgscategorizedsymbolrenderer.cpp b/src/core/symbology-ng/qgscategorizedsymbolrenderer.cpp
index 3e0aeccd52a..19617dc7c09 100644
--- a/src/core/symbology-ng/qgscategorizedsymbolrenderer.cpp
+++ b/src/core/symbology-ng/qgscategorizedsymbolrenderer.cpp
@@ -430,7 +430,7 @@ void QgsCategorizedSymbolRenderer::stopRender( QgsRenderContext& context )
mExpression.reset();
}
-QList QgsCategorizedSymbolRenderer::usedAttributes()
+QSet QgsCategorizedSymbolRenderer::usedAttributes() const
{
QSet attributes;
@@ -442,7 +442,7 @@ QList QgsCategorizedSymbolRenderer::usedAttributes()
QgsExpression testExpr( mAttrName );
if ( !testExpr.hasParserError() )
- attributes.unite( testExpr.referencedColumns().toSet() );
+ attributes.unite( testExpr.referencedColumns() );
QgsCategoryList::const_iterator catIt = mCategories.constBegin();
for ( ; catIt != mCategories.constEnd(); ++catIt )
@@ -453,7 +453,7 @@ QList QgsCategorizedSymbolRenderer::usedAttributes()
attributes.unite( catSymbol->usedAttributes() );
}
}
- return attributes.toList();
+ return attributes;
}
QString QgsCategorizedSymbolRenderer::dump() const
diff --git a/src/core/symbology-ng/qgscategorizedsymbolrenderer.h b/src/core/symbology-ng/qgscategorizedsymbolrenderer.h
index 2d0f02a57f4..37302a87342 100644
--- a/src/core/symbology-ng/qgscategorizedsymbolrenderer.h
+++ b/src/core/symbology-ng/qgscategorizedsymbolrenderer.h
@@ -86,7 +86,7 @@ class CORE_EXPORT QgsCategorizedSymbolRenderer : public QgsFeatureRenderer
virtual QgsSymbol* originalSymbolForFeature( QgsFeature& feature, QgsRenderContext& context ) override;
virtual void startRender( QgsRenderContext& context, const QgsFields& fields ) override;
virtual void stopRender( QgsRenderContext& context ) override;
- virtual QList usedAttributes() override;
+ virtual QSet usedAttributes() const override;
virtual QString dump() const override;
virtual QgsCategorizedSymbolRenderer* clone() const override;
virtual void toSld( QDomDocument& doc, QDomElement &element, QgsStringMap props = QgsStringMap() ) const override;
diff --git a/src/core/symbology-ng/qgsgeometrygeneratorsymbollayer.cpp b/src/core/symbology-ng/qgsgeometrygeneratorsymbollayer.cpp
index 307f515a6b8..898685dae0e 100644
--- a/src/core/symbology-ng/qgsgeometrygeneratorsymbollayer.cpp
+++ b/src/core/symbology-ng/qgsgeometrygeneratorsymbollayer.cpp
@@ -178,7 +178,7 @@ bool QgsGeometryGeneratorSymbolLayer::setSubSymbol( QgsSymbol* symbol )
QSet QgsGeometryGeneratorSymbolLayer::usedAttributes() const
{
- return mSymbol->usedAttributes() + mExpression->referencedColumns().toSet();
+ return mSymbol->usedAttributes() + mExpression->referencedColumns();
}
bool QgsGeometryGeneratorSymbolLayer::isCompatibleWithSymbol( QgsSymbol* symbol ) const
diff --git a/src/core/symbology-ng/qgsgraduatedsymbolrenderer.cpp b/src/core/symbology-ng/qgsgraduatedsymbolrenderer.cpp
index 884acdd4a0a..fb312469269 100644
--- a/src/core/symbology-ng/qgsgraduatedsymbolrenderer.cpp
+++ b/src/core/symbology-ng/qgsgraduatedsymbolrenderer.cpp
@@ -412,7 +412,7 @@ void QgsGraduatedSymbolRenderer::stopRender( QgsRenderContext& context )
}
}
-QList QgsGraduatedSymbolRenderer::usedAttributes()
+QSet QgsGraduatedSymbolRenderer::usedAttributes() const
{
QSet attributes;
@@ -424,7 +424,7 @@ QList QgsGraduatedSymbolRenderer::usedAttributes()
QgsExpression testExpr( mAttrName );
if ( !testExpr.hasParserError() )
- attributes.unite( testExpr.referencedColumns().toSet() );
+ attributes.unite( testExpr.referencedColumns() );
QgsRangeList::const_iterator range_it = mRanges.constBegin();
for ( ; range_it != mRanges.constEnd(); ++range_it )
@@ -435,7 +435,7 @@ QList QgsGraduatedSymbolRenderer::usedAttributes()
attributes.unite( symbol->usedAttributes() );
}
}
- return attributes.toList();
+ return attributes;
}
bool QgsGraduatedSymbolRenderer::updateRangeSymbol( int rangeIndex, QgsSymbol* symbol )
diff --git a/src/core/symbology-ng/qgsgraduatedsymbolrenderer.h b/src/core/symbology-ng/qgsgraduatedsymbolrenderer.h
index a0be327423d..8876567dd3b 100644
--- a/src/core/symbology-ng/qgsgraduatedsymbolrenderer.h
+++ b/src/core/symbology-ng/qgsgraduatedsymbolrenderer.h
@@ -140,7 +140,7 @@ class CORE_EXPORT QgsGraduatedSymbolRenderer : public QgsFeatureRenderer
virtual QgsSymbol* originalSymbolForFeature( QgsFeature& feature, QgsRenderContext &context ) override;
virtual void startRender( QgsRenderContext& context, const QgsFields& fields ) override;
virtual void stopRender( QgsRenderContext& context ) override;
- virtual QList usedAttributes() override;
+ virtual QSet usedAttributes() const override;
virtual QString dump() const override;
virtual QgsGraduatedSymbolRenderer* clone() const override;
virtual void toSld( QDomDocument& doc, QDomElement &element, QgsStringMap props = QgsStringMap() ) const override;
diff --git a/src/core/symbology-ng/qgsheatmaprenderer.cpp b/src/core/symbology-ng/qgsheatmaprenderer.cpp
index bc065011a25..34ba0532ef4 100644
--- a/src/core/symbology-ng/qgsheatmaprenderer.cpp
+++ b/src/core/symbology-ng/qgsheatmaprenderer.cpp
@@ -384,7 +384,7 @@ QgsSymbolList QgsHeatmapRenderer::symbols( QgsRenderContext& )
return QgsSymbolList();
}
-QList QgsHeatmapRenderer::usedAttributes()
+QSet QgsHeatmapRenderer::usedAttributes() const
{
QSet attributes;
@@ -396,9 +396,9 @@ QList QgsHeatmapRenderer::usedAttributes()
QgsExpression testExpr( mWeightExpressionString );
if ( !testExpr.hasParserError() )
- attributes.unite( testExpr.referencedColumns().toSet() );
+ attributes.unite( testExpr.referencedColumns() );
- return attributes.toList();
+ return attributes;
}
QgsHeatmapRenderer* QgsHeatmapRenderer::convertFromRenderer( const QgsFeatureRenderer *renderer )
diff --git a/src/core/symbology-ng/qgsheatmaprenderer.h b/src/core/symbology-ng/qgsheatmaprenderer.h
index 125ad362175..70cea65df7d 100644
--- a/src/core/symbology-ng/qgsheatmaprenderer.h
+++ b/src/core/symbology-ng/qgsheatmaprenderer.h
@@ -46,7 +46,7 @@ class CORE_EXPORT QgsHeatmapRenderer : public QgsFeatureRenderer
//! @note symbol2 in python bindings
virtual QgsSymbolList symbols( QgsRenderContext &context ) override;
virtual QString dump() const override;
- virtual QList usedAttributes() override;
+ virtual QSet usedAttributes() const override;
static QgsFeatureRenderer* create( QDomElement& element );
virtual QDomElement save( QDomDocument& doc ) override;
static QgsHeatmapRenderer* convertFromRenderer( const QgsFeatureRenderer* renderer );
diff --git a/src/core/symbology-ng/qgsinvertedpolygonrenderer.cpp b/src/core/symbology-ng/qgsinvertedpolygonrenderer.cpp
index b246bb52d23..1c27ea8d9e3 100644
--- a/src/core/symbology-ng/qgsinvertedpolygonrenderer.cpp
+++ b/src/core/symbology-ng/qgsinvertedpolygonrenderer.cpp
@@ -464,11 +464,11 @@ QgsFeatureRenderer::Capabilities QgsInvertedPolygonRenderer::capabilities()
return mSubRenderer->capabilities();
}
-QList QgsInvertedPolygonRenderer::usedAttributes()
+QSet QgsInvertedPolygonRenderer::usedAttributes() const
{
if ( !mSubRenderer )
{
- return QList();
+ return QSet();
}
return mSubRenderer->usedAttributes();
}
diff --git a/src/core/symbology-ng/qgsinvertedpolygonrenderer.h b/src/core/symbology-ng/qgsinvertedpolygonrenderer.h
index a33b0ab479f..a7e510acff2 100644
--- a/src/core/symbology-ng/qgsinvertedpolygonrenderer.h
+++ b/src/core/symbology-ng/qgsinvertedpolygonrenderer.h
@@ -71,7 +71,7 @@ class CORE_EXPORT QgsInvertedPolygonRenderer : public QgsFeatureRenderer
virtual QString dump() const override;
/** Proxy that will call this method on the embedded renderer. */
- virtual QList usedAttributes() override;
+ virtual QSet usedAttributes() const override;
/** Proxy that will call this method on the embedded renderer. */
virtual Capabilities capabilities() override;
/** Proxy that will call this method on the embedded renderer.
diff --git a/src/core/symbology-ng/qgsnullsymbolrenderer.cpp b/src/core/symbology-ng/qgsnullsymbolrenderer.cpp
index a013c2c5e75..5dabae67449 100644
--- a/src/core/symbology-ng/qgsnullsymbolrenderer.cpp
+++ b/src/core/symbology-ng/qgsnullsymbolrenderer.cpp
@@ -84,9 +84,9 @@ bool QgsNullSymbolRenderer::willRenderFeature( QgsFeature&, QgsRenderContext& )
return true;
}
-QList QgsNullSymbolRenderer::usedAttributes()
+QSet QgsNullSymbolRenderer::usedAttributes() const
{
- return QList();
+ return QSet();
}
QString QgsNullSymbolRenderer::dump() const
diff --git a/src/core/symbology-ng/qgsnullsymbolrenderer.h b/src/core/symbology-ng/qgsnullsymbolrenderer.h
index eae2f8d0b29..9defdf3b1b9 100644
--- a/src/core/symbology-ng/qgsnullsymbolrenderer.h
+++ b/src/core/symbology-ng/qgsnullsymbolrenderer.h
@@ -42,7 +42,7 @@ class CORE_EXPORT QgsNullSymbolRenderer : public QgsFeatureRenderer
virtual void stopRender( QgsRenderContext& context ) override;
virtual bool willRenderFeature( QgsFeature& feat, QgsRenderContext& context ) override;
- virtual QList usedAttributes() override;
+ virtual QSet usedAttributes() const override;
virtual QString dump() const override;
virtual QgsFeatureRenderer* clone() const override;
virtual QgsSymbolList symbols( QgsRenderContext& context ) override;
diff --git a/src/core/symbology-ng/qgspointclusterrenderer.cpp b/src/core/symbology-ng/qgspointclusterrenderer.cpp
index 5bd0f11a85d..d0a7f01b03b 100644
--- a/src/core/symbology-ng/qgspointclusterrenderer.cpp
+++ b/src/core/symbology-ng/qgspointclusterrenderer.cpp
@@ -157,11 +157,11 @@ QDomElement QgsPointClusterRenderer::save( QDomDocument& doc )
return rendererElement;
}
-QList QgsPointClusterRenderer::usedAttributes()
+QSet QgsPointClusterRenderer::usedAttributes() const
{
- QList attr = QgsPointDistanceRenderer::usedAttributes();
+ QSet attr = QgsPointDistanceRenderer::usedAttributes();
if ( mClusterSymbol )
- attr.append( mClusterSymbol->usedAttributes().toList() );
+ attr.unite( mClusterSymbol->usedAttributes() );
return attr;
}
diff --git a/src/core/symbology-ng/qgspointclusterrenderer.h b/src/core/symbology-ng/qgspointclusterrenderer.h
index 575f03b1ad0..600de1d8a79 100644
--- a/src/core/symbology-ng/qgspointclusterrenderer.h
+++ b/src/core/symbology-ng/qgspointclusterrenderer.h
@@ -35,7 +35,7 @@ class CORE_EXPORT QgsPointClusterRenderer: public QgsPointDistanceRenderer
virtual void startRender( QgsRenderContext& context, const QgsFields& fields ) override;
void stopRender( QgsRenderContext& context ) override;
QDomElement save( QDomDocument& doc ) override;
- virtual QList usedAttributes() override;
+ virtual QSet usedAttributes() const override;
//! Creates a renderer from XML element
static QgsFeatureRenderer* create( QDomElement& symbologyElem );
diff --git a/src/core/symbology-ng/qgspointdisplacementrenderer.cpp b/src/core/symbology-ng/qgspointdisplacementrenderer.cpp
index 74b7676341b..b189cf5db82 100644
--- a/src/core/symbology-ng/qgspointdisplacementrenderer.cpp
+++ b/src/core/symbology-ng/qgspointdisplacementrenderer.cpp
@@ -215,11 +215,11 @@ QDomElement QgsPointDisplacementRenderer::save( QDomDocument& doc )
return rendererElement;
}
-QList QgsPointDisplacementRenderer::usedAttributes()
+QSet QgsPointDisplacementRenderer::usedAttributes() const
{
- QList attr = QgsPointDistanceRenderer::usedAttributes();
+ QSet attr = QgsPointDistanceRenderer::usedAttributes();
if ( mCenterSymbol )
- attr.append( mCenterSymbol->usedAttributes().toList() );
+ attr.unite( mCenterSymbol->usedAttributes() );
return attr;
}
diff --git a/src/core/symbology-ng/qgspointdisplacementrenderer.h b/src/core/symbology-ng/qgspointdisplacementrenderer.h
index f5a4f66d46f..8a1e5cfade7 100644
--- a/src/core/symbology-ng/qgspointdisplacementrenderer.h
+++ b/src/core/symbology-ng/qgspointdisplacementrenderer.h
@@ -45,7 +45,7 @@ class CORE_EXPORT QgsPointDisplacementRenderer: public QgsPointDistanceRenderer
virtual void startRender( QgsRenderContext& context, const QgsFields& fields ) override;
void stopRender( QgsRenderContext& context ) override;
QDomElement save( QDomDocument& doc ) override;
- virtual QList usedAttributes() override;
+ virtual QSet usedAttributes() const override;
//! Create a renderer from XML element
static QgsFeatureRenderer* create( QDomElement& symbologyElem );
diff --git a/src/core/symbology-ng/qgspointdistancerenderer.cpp b/src/core/symbology-ng/qgspointdistancerenderer.cpp
index 626e1f62a7f..e67ef1dcb1b 100644
--- a/src/core/symbology-ng/qgspointdistancerenderer.cpp
+++ b/src/core/symbology-ng/qgspointdistancerenderer.cpp
@@ -204,12 +204,12 @@ QString QgsPointDistanceRenderer::filter( const QgsFields& fields )
return mRenderer->filter( fields );
}
-QList QgsPointDistanceRenderer::usedAttributes()
+QSet QgsPointDistanceRenderer::usedAttributes() const
{
- QList attributeList;
+ QSet attributeList;
if ( !mLabelAttributeName.isEmpty() )
{
- attributeList.push_back( mLabelAttributeName );
+ attributeList.insert( mLabelAttributeName );
}
if ( mRenderer )
{
diff --git a/src/core/symbology-ng/qgspointdistancerenderer.h b/src/core/symbology-ng/qgspointdistancerenderer.h
index 0dc13627468..758a9ebf7c9 100644
--- a/src/core/symbology-ng/qgspointdistancerenderer.h
+++ b/src/core/symbology-ng/qgspointdistancerenderer.h
@@ -76,7 +76,7 @@ class CORE_EXPORT QgsPointDistanceRenderer: public QgsFeatureRenderer
virtual void toSld( QDomDocument& doc, QDomElement &element, QgsStringMap props = QgsStringMap() ) const override;
bool renderFeature( QgsFeature& feature, QgsRenderContext& context, int layer = -1, bool selected = false, bool drawVertexMarker = false ) override;
- virtual QList usedAttributes() override;
+ virtual QSet usedAttributes() const override;
virtual Capabilities capabilities() override;
virtual QgsSymbolList symbols( QgsRenderContext& context ) override;
virtual QgsSymbol* symbolForFeature( QgsFeature& feature, QgsRenderContext& context ) override;
diff --git a/src/core/symbology-ng/qgsrenderer.h b/src/core/symbology-ng/qgsrenderer.h
index 55494d7598e..b333413a82d 100644
--- a/src/core/symbology-ng/qgsrenderer.h
+++ b/src/core/symbology-ng/qgsrenderer.h
@@ -148,8 +148,7 @@ class CORE_EXPORT QgsFeatureRenderer
*
* @return A set of attributes
*/
- // TODO QGIS3: Change QList to QSet
- virtual QList usedAttributes() = 0;
+ virtual QSet usedAttributes() const = 0;
/**
* Returns true if this renderer requires the geometry to apply the filter.
diff --git a/src/core/symbology-ng/qgsrulebasedrenderer.cpp b/src/core/symbology-ng/qgsrulebasedrenderer.cpp
index ec50e51184f..db7b25c6c13 100644
--- a/src/core/symbology-ng/qgsrulebasedrenderer.cpp
+++ b/src/core/symbology-ng/qgsrulebasedrenderer.cpp
@@ -185,7 +185,7 @@ QSet