[qgis] 01/06: Imported Upstream version 2.14.7+dfsg
Bas Couwenberg
sebastic at debian.org
Sat Sep 24 07:45:57 UTC 2016
This is an automated email from the git hooks/post-receive script.
sebastic pushed a commit to branch master
in repository qgis.
commit 32a1925b38832177c5c92fdceb0c46a2e907ce41
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date: Sat Sep 24 08:44:41 2016 +0200
Imported Upstream version 2.14.7+dfsg
---
CMakeLists.txt | 2 +-
ChangeLog | 826 ++++++++++++++-------
debian/changelog | 10 +-
debian/python-qgis.install.in | 1 +
debian/rules | 4 +
python/CMakeLists.txt | 12 +
python/QtWebKit/QtWebKitmod.sip | 63 ++
python/QtWebKit/__init__.py | 0
python/QtWebKit/qgraphicswebview.sip | 150 ++++
python/QtWebKit/qwebdatabase.sip | 46 ++
python/QtWebKit/qwebelement.sip | 144 ++++
python/QtWebKit/qwebframe.sip | 244 ++++++
python/QtWebKit/qwebhistory.sip | 104 +++
python/QtWebKit/qwebhistoryinterface.sip | 40 +
python/QtWebKit/qwebinspector.sip | 48 ++
python/QtWebKit/qwebkitglobal.sip | 37 +
python/QtWebKit/qwebkitversion.sip | 37 +
python/QtWebKit/qwebpage.sip | 522 +++++++++++++
python/QtWebKit/qwebpluginfactory.sip | 88 +++
python/QtWebKit/qwebsecurityorigin.sip | 56 ++
python/QtWebKit/qwebsettings.sip | 237 ++++++
python/QtWebKit/qwebview.sip | 167 +++++
python/core/geometry/qgsabstractgeometryv2.sip | 6 +
python/core/geometry/qgslinestringv2.sip | 4 +
python/core/geometry/qgsmultilinestringv2.sip | 4 +
python/core/geometry/qgsmultipolygonv2.sip | 4 +
python/core/geometry/qgspolygonv2.sip | 4 +
python/core/qgsstringutils.sip | 19 +
python/core/qgsvectordataprovider.sip | 4 +
python/gui/qgsmessagebar.sip | 4 +-
python/plugins/processing/algs/qgis/ConcaveHull.py | 4 +-
.../plugins/processing/algs/qgis/Intersection.py | 6 +-
python/plugins/processing/algs/qgis/MeanCoords.py | 11 +-
.../algs/qgis/SinglePartsToMultiparts.py | 4 +-
python/plugins/processing/core/parameters.py | 2 +-
.../plugins/processing/gui/AlgorithmDialogBase.py | 3 -
.../processing/ui/DlgGetScriptsAndModels.ui | 5 -
src/analysis/vector/qgsgeometryanalyzer.cpp | 59 +-
src/analysis/vector/qgsgeometryanalyzer.h | 10 +-
src/app/main.cpp | 94 ++-
src/app/qgsidentifyresultsdialog.cpp | 2 +
src/app/qgssnappingdialog.cpp | 2 +-
src/core/auth/qgsauthmanager.cpp | 8 +-
src/core/geometry/qgsabstractgeometryv2.h | 6 +
src/core/geometry/qgsgeometry.cpp | 5 +
src/core/geometry/qgslinestringv2.cpp | 8 +
src/core/geometry/qgslinestringv2.h | 3 +
src/core/geometry/qgsmultilinestringv2.cpp | 11 +
src/core/geometry/qgsmultilinestringv2.h | 3 +
src/core/geometry/qgsmultipolygonv2.cpp | 10 +
src/core/geometry/qgsmultipolygonv2.h | 3 +
src/core/geometry/qgspolygonv2.cpp | 12 +
src/core/geometry/qgspolygonv2.h | 3 +
src/core/qgsexpression.cpp | 14 +-
src/core/qgslegendrenderer.cpp | 46 +-
src/core/qgspallabeling.cpp | 71 +-
src/core/qgspointlocator.cpp | 1 +
src/core/qgspointlocator.h | 2 +-
src/core/qgsstringutils.cpp | 50 ++
src/core/qgsstringutils.h | 18 +
src/core/qgsvectordataprovider.cpp | 109 ++-
src/core/qgsvectordataprovider.h | 4 +
src/core/qgsvectorlayer.cpp | 7 +-
src/core/qgsvectorlayerfeatureiterator.cpp | 287 ++++---
src/core/qgsvectorlayerfeatureiterator.h | 29 +-
src/core/qgsvectorlayerlabelprovider.h | 2 +
src/core/symbology-ng/qgsvectorcolorrampv2.cpp | 5 +-
src/gui/editorwidgets/qgswebviewwidgetwrapper.cpp | 1 +
.../qgsdelimitedtextfeatureiterator.cpp | 10 +-
.../delimitedtext/qgsdelimitedtextfile.cpp | 10 +-
src/providers/ogr/qgsogrconnpool.h | 3 +-
src/providers/ogr/qgsogrfeatureiterator.cpp | 7 +
src/providers/ogr/qgsogrprovider.cpp | 177 ++++-
src/providers/ogr/qgsogrprovider.h | 8 +
src/providers/postgres/qgspostgresdataitems.cpp | 8 +-
src/providers/postgres/qgspostgresprovider.cpp | 7 +-
.../spatialite/qgsspatialitesourceselect.cpp | 4 +
.../virtual/qgsvirtuallayerqueryparser.cpp | 6 +-
.../virtual/qgsvirtuallayersqlitemodule.cpp | 19 +-
tests/src/core/testqgsexpression.cpp | 1 +
tests/src/core/testqgslabelingenginev2.cpp | 60 ++
tests/src/core/testqgslegendrenderer.cpp | 62 ++
tests/src/python/test_provider_ogr_gpkg.py | 164 ++++
tests/src/python/test_provider_virtual.py | 14 +
tests/src/python/test_qgsfeatureiterator.py | 88 ++-
.../expected_legend_2_by_2.png | Bin 0 -> 4515 bytes
.../expected_legend_2_by_2_mask.png | Bin 0 -> 1198 bytes
.../expected_legend_3_by_2.png | Bin 0 -> 5364 bytes
.../expected_legend_3_by_2_mask.png | Bin 0 -> 1491 bytes
.../expected_legend_3_by_3.png | Bin 0 -> 5800 bytes
.../expected_legend_3_by_3_mask.png | Bin 0 -> 1526 bytes
.../expected_legend_4_by_2.png | Bin 0 -> 5472 bytes
.../expected_legend_4_by_2_mask.png | Bin 0 -> 1676 bytes
.../expected_legend_4_by_3.png | Bin 0 -> 6529 bytes
.../expected_legend_4_by_3_mask.png | Bin 0 -> 1855 bytes
.../expected_legend_5_by_2.png | Bin 0 -> 6661 bytes
.../expected_legend_5_by_2_mask.png | Bin 0 -> 1964 bytes
.../expected_legend_5_by_3.png | Bin 0 -> 6870 bytes
.../expected_legend_5_by_3_mask.png | Bin 0 -> 2045 bytes
.../expected_legend_6_by_3.png | Bin 0 -> 7470 bytes
.../expected_legend_6_by_3_mask.png | Bin 0 -> 2226 bytes
.../expected_legend_7_by_3.png | Bin 0 -> 8244 bytes
.../expected_legend_7_by_3_mask.png | Bin 0 -> 2539 bytes
103 files changed, 3894 insertions(+), 561 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f945b1a..612b0f3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,6 @@
SET(CPACK_PACKAGE_VERSION_MAJOR "2")
SET(CPACK_PACKAGE_VERSION_MINOR "14")
-SET(CPACK_PACKAGE_VERSION_PATCH "6")
+SET(CPACK_PACKAGE_VERSION_PATCH "7")
SET(COMPLETE_VERSION ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH})
SET(RELEASE_NAME "Essen")
IF (POLICY CMP0048) # in CMake 3.0.0+
diff --git a/ChangeLog b/ChangeLog
index 6d0f335..1d1f2bf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,285 @@
+Even Rouault <even.rouault at spatialys.com> 2016-09-22
+
+ Fix database locking when editing GeoPackage
+
+ Concurrent read and write can lock a GeoPackage database given
+ the default journaling mode of SQLite (delete). Use WAL when
+ possible to avoid that.
+
+ Fixes #15351
+
+Martin Dobias <wonder.sk at gmail.com> 2016-09-21
+
+ [snapping] fix default advanced mode values for added layers
+
+ Backported from PR #3513
+
+ (cherry picked from commit be636c178cd527f4533f467292acd05bde4238c9)
+
+Juergen E. Fischer <jef at norbit.de> 2016-09-20
+
+ [processing] Just remove the url property from DlgGetScriptsAndModel.
+
+ (revert 7e24798, followup fad50ec)
+
+Juergen E. Fischer <jef at norbit.de> 2016-09-20
+
+ Fix fad50ec
+
+rldhont <rldhont at gmail.com> 2016-09-16
+
+ [Processing] bugfix: intersection QGIS algorithm
+
+ fixing this by testing int_com.
+ ```
+ Traceback (most recent call last):
+ File "C:/PROGRA~1/QGIS2~1.17/apps/qgis/./python/plugins\processing\core\GeoAlgorithm.py", line 203, in execute
+ self.processAlgorithm(progress)
+ File "C:/PROGRA~1/QGIS2~1.17/apps/qgis/./python/plugins\processing\algs\qgis\Intersection.py", line 100, in processAlgorithm
+ int_geom = QgsGeometry(int_com.difference(int_sym))
+ ```
+
+ AttributeError: 'NoneType' object has no attribute 'difference'
+ (cherry picked from commit 3661bc39dbee312b3a0887ca80287cbc7b2260ec)
+ (cherry picked from commit 5b573179f3d2fb94542714a4bd3fcdb28f4e3307)
+
+Juergen E. Fischer <jef at norbit.de> 2016-09-17
+
+ show command line help as message box on windows
+
+ (cherry picked from commit bd23bf1a2368fa68fe692d451f61bfe3095619bd)
+
+Alexander Bruy <alexander.bruy at gmail.com> 2016-09-16
+
+ [processing] allow all field types as unique ID field in Mean coords alg
+
+ (cherry picked from commit 75269d66b9d79c3b4a2b18bd9626c22840aa6713)
+
+arnaud.morvan at camptocamp.com <arnaud.morvan at camptocamp.com> 2016-09-08
+
+ Fix ParameterGeometryPredicate.getValueAsCommandLineParameter
+
+ (cherry picked from commit d85de7ccd8946ab3ded83abae674554d482dbcf5)
+
+Nyall Dawson <nyall.dawson at gmail.com> 2016-09-15
+
+ Catch exceptions in transform() expression function
+
+ (cherry-picked from 2a8333ef6be003b8c391a72dbed033a33373d677)
+
+Alexander Bruy <alexander.bruy at gmail.com> 2016-09-15
+
+ [processing] correct error message (fix #15511)
+
+ (cherry picked from commit d393734bd3d368f52271838414a3edbf1d4eb1a5)
+
+Juergen E. Fischer <jef at norbit.de> 2016-09-14
+
+ fix 058aa46
+
+Juergen E. Fischer <jef at norbit.de> 2016-09-14
+
+ Enable plugins (eg. to show PDFs) in webview widgets used on feature info in identify or in forms
+
+Nyall Dawson <nyall.dawson at gmail.com> 2016-09-10
+
+ Test masks
+
+ (cherry-picked from e3313fac95ea143988ea32bf162b01b4df8e6fa1)
+
+Nyall Dawson <nyall.dawson at gmail.com> 2016-09-10
+
+ Make sure items in legend always occupy the set number of columns
+
+ In some cases (eg a legend with 4 items and 3 columns) less
+ columns were being created
+
+ (cherry-picked from 52eef9006183a66d53926f33e73afa1dcd534e59)
+
+Nyall Dawson <nyall.dawson at gmail.com> 2016-09-10
+
+ Fix multi column legends with odd number of items would place
+ more items in rightmost columns instead of leftmost columns
+
+ Eg a 2 column legend with 3 items would put 1 item in
+ the first column and 2 in the second. This was ugly, and now
+ it places 2 in the first column and 1 in the second.
+
+ The legend column assigner was incorrectly adding padding above
+ the first item in a column during column size calculation
+ (padding which is not present when actually rendering the column)
+
+ (cherry-picked from a673fa8393146d9a8cd1a3bf6f0444bfa23352d7)
+
+Nyall Dawson <nyall.dawson at gmail.com> 2016-09-10
+
+ Add a bunch of tests for legend grouping into columns
+
+ (cherry-picked from 570e6936b655aef2877d2d63c9892f1df05df312)
+
+nirvn <nirvn.asia at gmail.com> 2016-09-13
+
+ [delimitertext] fix watcher check ignored and harmful watcher created for iterator
+ (fixes #15558)
+
+ (cherry-picked from b3e31087181732f7511d047b98352e97f08b0d04)
+
+Marco Bernasocchi <marco at bernawebdesign.ch> 2016-09-11
+
+ qgsmessagebar timeout is not respected in python
+
+ the default timeout is not respected in python
+
+ gui/qgsmessagebar.sip:51: void pushMessage( const QString &text, MessageLevel level = INFO, int duration = 0 );
+
+ https://qgis.org/api/qgsmessagebar_8h_source.html#l00090
+ void pushMessage( const QString &text, MessageLevel level = INFO, int duration = 5 ) { return pushMessage( QString::null, text, level, duration ); }
+
+ (cherry-picked from bb4e6b8fb800b69d28407102a4f17494a4cd5ad9)
+
+Alexander Bruy <alexander.bruy at gmail.com> 2016-09-13
+
+ [processing] fix progress reporting (fix #15521)
+
+ (cherry picked from commit b14dfa65fe8c5db852bac0899f8aac64b91faada)
+
+ Conflicts:
+ python/plugins/processing/gui/AlgorithmDialogBase.py
+
+Merge: c151724 bb4d83f
+mhugent <marco.hugentobler at sourcepole.ch> 2016-09-13
+
+ Merge pull request #3482 from mhugent/joins_over_several_tables2
+
+ Joins over several tables2
+
+Marco Hugentobler <marco.hugentobler at sourcepole.ch> 2016-09-13
+
+ Fix imports in test_qgsfeatureiterator
+
+Marco Hugentobler <marco.hugentobler at sourcepole.ch> 2016-09-12
+
+ Fix joins over several tables
+
+Nyall Dawson <nyall.dawson at gmail.com> 2016-06-10
+
+ Correctly support joins using virtual fields
+
+Merge: 4aaa6d4 9290ee3
+mhugent <marco.hugentobler at sourcepole.ch> 2016-09-12
+
+ Merge pull request #3476 from mhugent/fix_event_layer
+
+ Fix for event layer functionality in 2.4
+
+Marco Hugentobler <marco.hugentobler at sourcepole.ch> 2016-09-09
+
+ Fix event layer to work with 25d, z and zm
+
+Juergen E. Fischer <jef at norbit.de> 2016-09-06
+
+ debian packaging update: add internal QtWebKit bindings
+
+ (backported from c2f363f)
+
+Marco Hugentobler <marco.hugentobler at sourcepole.ch> 2016-09-05
+
+ Fix warning
+
+Marco Hugentobler <marco.hugentobler at sourcepole.ch> 2016-09-05
+
+ Fix bindings
+
+Merge: a528eb9 b14255c
+mhugent <marco.hugentobler at sourcepole.ch> 2016-09-05
+
+ Merge pull request #3446 from mhugent/convert_geometry_provider
+
+ Port conversion of geometry to provider type to 2.14 branch
+
+Marco Hugentobler <marco.hugentobler at sourcepole.ch> 2016-09-02
+
+ Port conversion of geometry to provider type to 2.14 branch
+
+Larry Shaffer <lshaffer at boundlessgeo.com> 2016-09-01
+
+ [auth] Fix return value for plugins that do not support an expansion
+
+ Bug not evident until there were providers with multiple credential
+ expansions (now supported in OWS providers). Lack of support for an
+ expansion should only trigger a debug message, not a failure.
+
+ (cherry-picked from 194b5adb1ed81bcfe7edd78477dfea81cae77aed)
+
+Hugo Mercier <hugo.mercier at oslandia.com> 2016-09-01
+
+ Fix virtual layer queries with accents in layer name
+
+ (cherry-picked from af0d6b93a6)
+
+Matthias Kuhn <matthias at opengis.ch> 2016-09-01
+
+ Export main() when building for android
+
+Hugo Mercier <hugo.mercier at oslandia.com> 2016-07-21
+
+ Snapping: destroy index on dataChanged signal
+
+ Snapping caches on layers that have been changed by the provider or
+ by external sources are now invalidated.
+
+ (Cherry-picked from e6fd2e25)
+
+Nyall Dawson <nyall.dawson at gmail.com> 2016-08-30
+
+ Fix Capitalize First Letter fails with curved labels (fix #14875)
+
+ Instead of using QFont's inbuilt capitalization support, which
+ applies only on rendering and accordingly fails for curved
+ labels which are drawn one character at a time, we now manually
+ capitalize label text while registering features.
+
+ The capitalize first method from Qt was reimplemented in QgsStringUtils
+ (together with what I expect is better handling of unicode characters
+ over the Qt method).
+
+ This change also makes it possible to implement other capitalization
+ methods not directly supported by Qt
+
+ (cherry-picked from 15dd295)
+
+Tim Sutton <tim at kartoza.com> 2016-08-22
+
+ Spatialite error message fix (#3416)
+
+ * Fixed issue where opening an invalid spatialite db fails and gives and poor warning message
+
+Nyall Dawson <nyall.dawson at gmail.com> 2016-08-26
+
+ [browser] Correctly refresh postgres schemas when dropping tables
+
+ (cherry-picked from 5a41748b867505784a091a882a0eb1ca187c4ba8)
+
+Nyall Dawson <nyall.dawson at gmail.com> 2016-08-26
+
+ Make QgsVectorDataProvider defaults methods more efficient
+
+ (cherry-picked from a10b8fc3e5658290dd7e18df1001e543c3a75caa)
+
+Nyall Dawson <nyall.dawson at gmail.com> 2016-08-26
+
+ Fix limited random color ramp always returns 1 less color than set
+
+ (cherry-picked from 1d98b10904884d8223372fc9248c2825c85591e9)
+
+Nyall Dawson <nyall.dawson at gmail.com> 2016-08-25
+
+ Fix potential crash
+
+Juergen E. Fischer <jef at norbit.de> 2016-08-26
+
+ Release of 2.14.6
+
rldhont <rldhont at gmail.com> 2016-08-25
fix typo 1369794 @alexbruy [processing] add missed error() method
@@ -446,7 +728,7 @@ volaya <volayaf at gmail.com> 2016-06-01
(cherry picked from commit 479ceb36b40407643764586fc5122333b7eb38eb)
Conflicts:
-python/plugins/processing/tools/dataobjects.py
+ python/plugins/processing/tools/dataobjects.py
Patrick Valsecchi <patrick.valsecchi at camptocamp.com> 2016-05-13
@@ -1443,7 +1725,7 @@ Alexander Bruy <alexander.bruy at gmail.com> 2016-06-22
(cherry picked from commit e4c1d896e97952743ea1c0c2144e33983fa5706a)
Conflicts:
-python/plugins/processing/algs/gdal/GdalUtils.py
+ python/plugins/processing/algs/gdal/GdalUtils.py
Sandro Santilli <strk at kbt.io> 2016-06-22
@@ -1463,7 +1745,7 @@ Alexander Bruy <alexander.bruy at gmail.com> 2016-06-21
(cherry picked from commit e0c9733f6482f184aeeff1339fafef210d1a0709)
Conflicts:
-python/plugins/processing/algs/qgis/HubDistance.py
+ python/plugins/processing/algs/qgis/HubDistance.py
Alexander Bruy <alexander.bruy at gmail.com> 2016-06-21
@@ -1580,11 +1862,11 @@ Alexander Bruy <alexander.bruy at gmail.com> 2016-06-13
(cherry picked from commit 0553f7b33b4a3294f9a1cfb24e8c238f9211503d)
Conflicts:
-python/plugins/processing/algs/qgis/Clip.py
-python/plugins/processing/algs/qgis/Difference.py
-python/plugins/processing/algs/qgis/Intersection.py
-python/plugins/processing/algs/qgis/SymmetricalDifference.py
-python/plugins/processing/algs/qgis/Union.py
+ python/plugins/processing/algs/qgis/Clip.py
+ python/plugins/processing/algs/qgis/Difference.py
+ python/plugins/processing/algs/qgis/Intersection.py
+ python/plugins/processing/algs/qgis/SymmetricalDifference.py
+ python/plugins/processing/algs/qgis/Union.py
rldhont <rldhont at gmail.com> 2016-06-10
@@ -2146,8 +2428,8 @@ rldhont <rldhont at gmail.com> 2016-04-26
(cherry picked from commit 793b712eb9dbd5d6d7589e7490c63d50d0038a69)
Conflicts:
-python/plugins/processing/algs/gdal/rasterize.py
-python/plugins/processing/algs/gdal/warp.py
+ python/plugins/processing/algs/gdal/rasterize.py
+ python/plugins/processing/algs/gdal/warp.py
volaya <volayaf at gmail.com> 2016-04-26
@@ -2170,7 +2452,7 @@ Alexander Bruy <alexander.bruy at gmail.com> 2016-04-11
(cherry picked from commit e873540d14cb102ffe9318063b32c323c56e5bfb)
Conflicts:
-python/plugins/processing/algs/otb/OTBUtils.py
+ python/plugins/processing/algs/otb/OTBUtils.py
Nyall Dawson <nyall.dawson at gmail.com> 2016-04-26
@@ -8682,7 +8964,7 @@ Michael Kirk <michael.john.kirk at gmail.com> 2015-11-29
- Test BooleanParameter
Conflicts:
-python/plugins/processing/core/parameters.py
+ python/plugins/processing/core/parameters.py
rldhont <rldhont at gmail.com> 2015-12-23
@@ -10791,7 +11073,7 @@ Giuseppe Sucameli <brush.tyler at gmail.com> 2015-11-30
Merge branch 'gdaltools_buildvrt_asrs' of https://github.com/giohappy/QGIS into giohappy-gdaltools_buildvrt_asrs
Conflicts:
-python/plugins/GdalTools/tools/doBuildVRT.py
+ python/plugins/GdalTools/tools/doBuildVRT.py
commit 6d3df91f0226fa71356da45b9b5ef1c9f9796ebd
Author: giohappy <giohappy at gmail.com>
@@ -13409,7 +13691,7 @@ Giuseppe Sucameli <brush.tyler at gmail.com> 2015-10-25
Merge branch 'clipper' of https://github.com/PedroVenancio/Quantum-GIS into PedroVenancio-clipper
Conflicts:
-python/plugins/processing/algs/gdal/ClipByMask.py
+ python/plugins/processing/algs/gdal/ClipByMask.py
mdouchin <mdouchin at 3liz.com> 2015-10-25
@@ -13442,7 +13724,7 @@ volaya <volayaf at gmail.com> 2015-10-22
[processing] fixed SAGA version handling
Conflicts:
-python/plugins/processing/algs/saga/SagaAlgorithmProvider.py
+ python/plugins/processing/algs/saga/SagaAlgorithmProvider.py
volaya <volayaf at gmail.com> 2015-10-22
@@ -18439,7 +18721,7 @@ Nathan Woodrow <madmanwoo at gmail.com> 2015-08-25
Merge branch 'master' of https://github.com/qgis/QGIS
Conflicts:
-src/gui/attributetable/qgsfieldconditionalformatwidget.cpp
+ src/gui/attributetable/qgsfieldconditionalformatwidget.cpp
Nyall Dawson <nyall.dawson at gmail.com> 2015-08-25
@@ -18631,13 +18913,13 @@ Nathan Woodrow <madmanwoo at gmail.com> 2015-08-23
Merge row style support for attribute table
Conflicts:
-python/core/qgsconditionalstyle.sip
-python/core/qgsfielduiproperties.sip
-src/core/qgsfielduiproperties.cpp
-src/core/qgsfielduiproperties.h
-src/gui/attributetable/qgsattributetablemodel.cpp
-src/ui/qgsfieldconditionalformatwidget.ui
-tests/src/python/test_qgsconditionalstyle.py
+ python/core/qgsconditionalstyle.sip
+ python/core/qgsfielduiproperties.sip
+ src/core/qgsfielduiproperties.cpp
+ src/core/qgsfielduiproperties.h
+ src/gui/attributetable/qgsattributetablemodel.cpp
+ src/ui/qgsfieldconditionalformatwidget.ui
+ tests/src/python/test_qgsconditionalstyle.py
Nathan Woodrow <madmanwoo at gmail.com> 2015-08-23
@@ -24131,7 +24413,7 @@ Alexander Bruy <alexander.bruy at gmail.com> 2015-05-27
Merge branch 'master' of https://github.com/scubbx/QGIS into processing-r.stat
Conflicts:
-python/plugins/processing/algs/grass7/Grass7Algorithm.py
+ python/plugins/processing/algs/grass7/Grass7Algorithm.py
Nyall Dawson <nyall.dawson at gmail.com> 2015-05-27
@@ -26888,7 +27170,7 @@ Alexander Bruy <alexander.bruy at gmail.com> 2015-04-02
Merge branch 'master' of https://github.com/gbd-consult/QGIS into ftools-enhancements
Conflicts:
-python/plugins/fTools/tools/doPointsInPolygon.py
+ python/plugins/fTools/tools/doPointsInPolygon.py
Anatoliy Golubev <darth.naihil at gmail.com> 2015-04-01
@@ -27922,7 +28204,7 @@ Alexander Bruy <alexander.bruy at gmail.com> 2015-02-24
Merge branch 'processing_import_geomless_tables_in_postgresql_2' of https://github.com/gioman/QGIS into geometry-less-import
Conflicts:
-python/plugins/processing/algs/gdal/GdalOgrAlgorithmProvider.py
+ python/plugins/processing/algs/gdal/GdalOgrAlgorithmProvider.py
Merge: 8ab014d b4f2568
Alexander Bruy <alexander.bruy at gmail.com> 2015-02-24
@@ -27953,7 +28235,7 @@ Alexander Bruy <alexander.bruy at gmail.com> 2015-02-24
Merge branch 'processing_add_gdal_raster_calc' of https://github.com/gioman/QGIS into gdal_calc
Conflicts:
-python/plugins/processing/algs/gdal/GdalOgrAlgorithmProvider.py
+ python/plugins/processing/algs/gdal/GdalOgrAlgorithmProvider.py
Merge: 33c6051 bf08b7b
alexbruy <alexander.bruy at gmail.com> 2015-02-24
@@ -29711,7 +29993,7 @@ Michael Kirk <michael.john.kirk at gmail.com> 2015-01-26
Merge remote-tracking branch 'upstream/master' into feature/export-png-first-8493
Conflicts:
-src/gui/qgisgui.h
+ src/gui/qgisgui.h
Juergen E. Fischer <jef at norbit.de> 2015-01-27
@@ -33538,7 +33820,7 @@ Martin Dobias <wonder.sk at gmail.com> 2014-11-15
Merge remote-tracking branch 'rldhont/filter_legend_displacement_point2'
Conflicts:
-src/core/qgsmaphittest.cpp
+ src/core/qgsmaphittest.cpp
Matthias Kuhn <matthias.kuhn at gmx.ch> 2014-11-14
@@ -34047,7 +34329,7 @@ elpaso <apasotti at gmail.com> 2014-10-09
response headers and body
Conflicts:
-src/mapserver/qgswmsserver.cpp
+ src/mapserver/qgswmsserver.cpp
Funded by ItOpen - http://www.itopen.it
@@ -37678,9 +37960,9 @@ Martin Dobias <wonder.sk at gmail.com> 2014-09-13
Merge remote-tracking branch 'rouault/use_geos_reentrant_api'
Conflicts:
-src/core/pal/layer.cpp
-src/core/qgsgeometry.cpp
-src/core/qgspallabeling.cpp
+ src/core/pal/layer.cpp
+ src/core/qgsgeometry.cpp
+ src/core/qgspallabeling.cpp
Martin Dobias <wonder.sk at gmail.com> 2014-09-13
@@ -38309,8 +38591,8 @@ Denis Rouzaud <denis.rouzaud at gmail.com> 2014-08-27
[map layer actions] action for group of features, rename availability to target (flags), only emit signal for defined target"
Conflicts:
-src/gui/qgsmaplayeractionregistry.cpp
-src/gui/qgsmaplayeractionregistry.h
+ src/gui/qgsmaplayeractionregistry.cpp
+ src/gui/qgsmaplayeractionregistry.h
Nyall Dawson <nyall.dawson at gmail.com> 2014-09-01
@@ -41903,7 +42185,7 @@ Martin Dobias <wonder.sk at gmail.com> 2014-06-15
Merge remote-tracking branch 'edigonzales/master'
Conflicts:
-src/core/symbology-ng/qgslinesymbollayerv2.cpp
+ src/core/symbology-ng/qgslinesymbollayerv2.cpp
Merge: 6c21262 7bec7c2
Werner Macho <werner.macho at gmail.com> 2014-06-15
@@ -42545,11 +42827,11 @@ Martin Dobias <wonder.sk at gmail.com> 2014-06-10
Fix #10355 (crash) and #10338 (overlapping polygons) in inverted polygon renderer
Conflicts:
-python/core/symbology-ng/qgsinvertedpolygonrenderer.sip
-src/core/symbology-ng/qgsinvertedpolygonrenderer.cpp
-src/core/symbology-ng/qgsinvertedpolygonrenderer.h
-src/gui/symbology-ng/qgsinvertedpolygonrendererwidget.cpp
-src/gui/symbology-ng/qgsinvertedpolygonrendererwidget.h
+ python/core/symbology-ng/qgsinvertedpolygonrenderer.sip
+ src/core/symbology-ng/qgsinvertedpolygonrenderer.cpp
+ src/core/symbology-ng/qgsinvertedpolygonrenderer.h
+ src/gui/symbology-ng/qgsinvertedpolygonrendererwidget.cpp
+ src/gui/symbology-ng/qgsinvertedpolygonrendererwidget.h
Martin Dobias <wonder.sk at gmail.com> 2014-06-10
@@ -43436,7 +43718,7 @@ Martin Dobias <wonder.sk at gmail.com> 2014-05-30
Merge remote-tracking branch 'alvaro/Simplification_MTR'
Conflicts:
-python/core/qgsmapsettings.sip
+ python/core/qgsmapsettings.sip
Martin Dobias <wonder.sk at gmail.com> 2014-05-30
@@ -44364,7 +44646,7 @@ Martin Dobias <wonder.sk at gmail.com> 2014-05-21
- controlling of map canvas: QgsLayerTreeCanvasBridge
Conflicts:
-src/ui/qgisapp.ui
+ src/ui/qgisapp.ui
Martin Dobias <wonder.sk at gmail.com> 2014-05-21
@@ -46926,7 +47208,7 @@ Marcel Dancak <marcel.dancak at gista.sk> 2014-04-07
Merge remote-tracking branch 'origin/master'
Conflicts:
-src/mapserver/qgswmsserver.cpp
+ src/mapserver/qgswmsserver.cpp
Merge: 3e4b568 1399c6e
mhugent <marco.hugentobler at sourcepole.ch> 2014-04-07
@@ -49009,13 +49291,13 @@ Martin Dobias <wonder.sk at gmail.com> 2014-02-23
Merge remote-tracking branch 'origin/master' into threading-revival
Conflicts:
-src/core/qgspallabeling.cpp
-src/core/qgsrenderchecker.h
-src/core/qgsvectorlayer.cpp
-src/core/symbology-ng/qgslinesymbollayerv2.cpp
-src/core/symbology-ng/qgssymbollayerv2.cpp
-src/providers/wms/qgswmsdataitems.cpp
-tests/src/core/testqgsblendmodes.cpp
+ src/core/qgspallabeling.cpp
+ src/core/qgsrenderchecker.h
+ src/core/qgsvectorlayer.cpp
+ src/core/symbology-ng/qgslinesymbollayerv2.cpp
+ src/core/symbology-ng/qgssymbollayerv2.cpp
+ src/providers/wms/qgswmsdataitems.cpp
+ tests/src/core/testqgsblendmodes.cpp
Matthias Kuhn <matthias.kuhn at gmx.ch> 2014-02-23
@@ -49741,75 +50023,75 @@ Martin Dobias <wonder.sk at gmail.com> 2014-02-18
Some features are still disabled - will be fixed later
Conflicts:
-python/core/composer/qgscomposition.sip
-python/core/diagram/qgsdiagram.sip
-python/core/diagram/qgshistogramdiagram.sip
-python/core/diagram/qgspiediagram.sip
-python/core/diagram/qgstextdiagram.sip
-python/core/qgsdiagramrendererv2.sip
-python/core/qgsfield.sip
-python/core/qgslabelsearchtree.sip
-python/core/qgsmaprenderer.sip
-python/core/qgsrenderchecker.sip
-python/core/symbology-ng/qgssymbollayerv2.sip
-python/gui/qgsmapcanvas.sip
-src/app/composer/qgscomposerlegendwidget.cpp
-src/app/qgisapp.cpp
-src/core/composer/qgsatlascomposition.cpp
-src/core/composer/qgscomposerattributetable.cpp
-src/core/composer/qgscomposermap.cpp
-src/core/composer/qgscomposition.cpp
-src/core/composer/qgscomposition.h
-src/core/diagram/qgsdiagram.h
-src/core/diagram/qgshistogramdiagram.cpp
-src/core/diagram/qgshistogramdiagram.h
-src/core/diagram/qgspiediagram.cpp
-src/core/diagram/qgspiediagram.h
-src/core/diagram/qgstextdiagram.cpp
-src/core/diagram/qgstextdiagram.h
-src/core/qgsdiagramrendererv2.cpp
-src/core/qgsdiagramrendererv2.h
-src/core/qgsmaprenderer.cpp
-src/core/qgsmaprenderer.h
-src/core/qgsnetworkaccessmanager.h
-src/core/qgspallabeling.cpp
-src/core/qgsrenderchecker.h
-src/core/qgsvectorlayer.cpp
-src/core/qgsvectorlayer.h
-src/core/qgsvectorlayerfeatureiterator.cpp
-src/core/qgsvectorlayerfeatureiterator.h
-src/core/raster/qgsrasterlayer.cpp
-src/core/symbology-ng/qgscategorizedsymbolrendererv2.cpp
-src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp
-src/core/symbology-ng/qgsmarkersymbollayerv2.cpp
-src/core/symbology-ng/qgssinglesymbolrendererv2.cpp
-src/core/symbology-ng/qgssymbollayerv2.cpp
-src/core/symbology-ng/qgssymbollayerv2.h
-src/core/symbology-ng/qgssymbolv2.cpp
-src/gui/qgshighlight.cpp
-src/gui/qgsmapcanvas.cpp
-src/gui/qgsmapcanvas.h
-src/gui/qgsmapcanvasitem.cpp
-src/gui/qgsmaptoolidentify.cpp
-src/plugins/georeferencer/qgsgeorefplugingui.cpp
-src/providers/memory/qgsmemoryfeatureiterator.cpp
-src/providers/ogr/qgsogrfeatureiterator.cpp
-src/providers/ogr/qgsogrfeatureiterator.h
-src/providers/ogr/qgsogrprovider.cpp
-src/providers/oracle/qgsoraclefeatureiterator.cpp
-src/providers/oracle/qgsoracleprovider.cpp
-src/providers/postgres/qgspostgresconn.cpp
-src/providers/postgres/qgspostgresfeatureiterator.cpp
-src/providers/postgres/qgspostgresfeatureiterator.h
-src/providers/wfs/qgswfsfeatureiterator.cpp
-src/providers/wms/qgswmsprovider.cpp
-src/providers/wms/qgswmsprovider.h
-src/ui/qgsoptionsbase.ui
-tests/src/core/CMakeLists.txt
-tests/src/core/testqgscomposereffects.cpp
-tests/src/core/testqgscomposerhtml.cpp
-tests/src/core/testqgscomposerscalebar.cpp
-tests/src/core/testqgscomposershapes.cpp
+ python/core/composer/qgscomposition.sip
+ python/core/diagram/qgsdiagram.sip
+ python/core/diagram/qgshistogramdiagram.sip
+ python/core/diagram/qgspiediagram.sip
+ python/core/diagram/qgstextdiagram.sip
+ python/core/qgsdiagramrendererv2.sip
+ python/core/qgsfield.sip
+ python/core/qgslabelsearchtree.sip
+ python/core/qgsmaprenderer.sip
+ python/core/qgsrenderchecker.sip
+ python/core/symbology-ng/qgssymbollayerv2.sip
+ python/gui/qgsmapcanvas.sip
+ src/app/composer/qgscomposerlegendwidget.cpp
+ src/app/qgisapp.cpp
+ src/core/composer/qgsatlascomposition.cpp
+ src/core/composer/qgscomposerattributetable.cpp
+ src/core/composer/qgscomposermap.cpp
+ src/core/composer/qgscomposition.cpp
+ src/core/composer/qgscomposition.h
+ src/core/diagram/qgsdiagram.h
+ src/core/diagram/qgshistogramdiagram.cpp
+ src/core/diagram/qgshistogramdiagram.h
+ src/core/diagram/qgspiediagram.cpp
+ src/core/diagram/qgspiediagram.h
+ src/core/diagram/qgstextdiagram.cpp
+ src/core/diagram/qgstextdiagram.h
+ src/core/qgsdiagramrendererv2.cpp
+ src/core/qgsdiagramrendererv2.h
+ src/core/qgsmaprenderer.cpp
+ src/core/qgsmaprenderer.h
+ src/core/qgsnetworkaccessmanager.h
+ src/core/qgspallabeling.cpp
+ src/core/qgsrenderchecker.h
+ src/core/qgsvectorlayer.cpp
+ src/core/qgsvectorlayer.h
+ src/core/qgsvectorlayerfeatureiterator.cpp
+ src/core/qgsvectorlayerfeatureiterator.h
+ src/core/raster/qgsrasterlayer.cpp
+ src/core/symbology-ng/qgscategorizedsymbolrendererv2.cpp
+ src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp
+ src/core/symbology-ng/qgsmarkersymbollayerv2.cpp
+ src/core/symbology-ng/qgssinglesymbolrendererv2.cpp
+ src/core/symbology-ng/qgssymbollayerv2.cpp
+ src/core/symbology-ng/qgssymbollayerv2.h
+ src/core/symbology-ng/qgssymbolv2.cpp
+ src/gui/qgshighlight.cpp
+ src/gui/qgsmapcanvas.cpp
+ src/gui/qgsmapcanvas.h
+ src/gui/qgsmapcanvasitem.cpp
+ src/gui/qgsmaptoolidentify.cpp
+ src/plugins/georeferencer/qgsgeorefplugingui.cpp
+ src/providers/memory/qgsmemoryfeatureiterator.cpp
+ src/providers/ogr/qgsogrfeatureiterator.cpp
+ src/providers/ogr/qgsogrfeatureiterator.h
+ src/providers/ogr/qgsogrprovider.cpp
+ src/providers/oracle/qgsoraclefeatureiterator.cpp
+ src/providers/oracle/qgsoracleprovider.cpp
+ src/providers/postgres/qgspostgresconn.cpp
+ src/providers/postgres/qgspostgresfeatureiterator.cpp
+ src/providers/postgres/qgspostgresfeatureiterator.h
+ src/providers/wfs/qgswfsfeatureiterator.cpp
+ src/providers/wms/qgswmsprovider.cpp
+ src/providers/wms/qgswmsprovider.h
+ src/ui/qgsoptionsbase.ui
+ tests/src/core/CMakeLists.txt
+ tests/src/core/testqgscomposereffects.cpp
+ tests/src/core/testqgscomposerhtml.cpp
+ tests/src/core/testqgscomposerscalebar.cpp
+ tests/src/core/testqgscomposershapes.cpp
Merge: 49fbfba f4f450f
Martin Dobias <wonder.sk at gmail.com> 2014-02-18
@@ -53209,10 +53491,10 @@ Nathan Woodrow <nathan.woodrow at mapsolutions.com.au> 2014-01-03
Update to new style side bar style for dialogs.
-- New blue-grey with white text style dialog
-- Side panel runs top to bottom
-- Icon size is read from settings
-- Option to disable in options dialog
+ - New blue-grey with white text style dialog
+ - Side panel runs top to bottom
+ - Icon size is read from settings
+ - Option to disable in options dialog
elpaso <apasotti at gmail.com> 2014-01-06
@@ -53915,9 +54197,9 @@ Alvaro Huarte <ahuarte47 at yahoo.es> 2013-12-17
Merge branch 'Issue_8725-OGR' of https://github.com/ahuarte47/QGIS into Issue_8725-OGR
Conflicts:
-src/app/qgsoptions.cpp
-src/app/qgsoptions.h
-src/core/symbology-ng/qgssymbollayerv2.cpp
+ src/app/qgsoptions.cpp
+ src/app/qgsoptions.h
+ src/core/symbology-ng/qgssymbollayerv2.cpp
ahuarte47 <ahuarte47 at yahoo.es> 2013-12-12
@@ -58292,7 +58574,7 @@ Marco Bernasocchi <marco at opengis.ch> 2013-05-18
Marco Bernasocchi <marco at opengis.ch> 2013-05-03
-#7752 for android sip generation issue fix
+ sip generation issue fix #7752 for android
Larry Shaffer <larrys at dakotacarto.com> 2013-09-09
@@ -61167,7 +61449,7 @@ Victor Olaya <volayaf at gmail.com> 2013-07-15
This reverts commit 1c2e49ed249a89480c1195f50c96614dc72700d3.
Conflicts:
-python/plugins/sextante/saga/SagaAlgorithm.py
+ python/plugins/sextante/saga/SagaAlgorithm.py
pcav <cavallini at faunalia.it> 2013-07-18
@@ -62501,7 +62783,7 @@ yoichigmf <yoichi.kayama at gmail.com> 2013-07-02
Merge branch 'master' of https://github.com/qgis/Quantum-GIS into make_pull_req_from_ja
Conflicts:
-i18n/qgis_ja.ts
+ i18n/qgis_ja.ts
Matthias Kuhn <matthias.kuhn at gmx.ch> 2013-07-02
@@ -64471,8 +64753,8 @@ Ivan Mincik <ivan.mincik at gmail.com> 2013-06-03
Ivan Mincik <ivan.mincik at gmail.com> 2013-06-03
First batch of Slovak translation for version 2.0.
-- translation
-- merge with 4b76600 (adding function_help, context_help)
+ - translation
+ - merge with 4b76600 (adding function_help, context_help)
Merge: 21a884b d4945db
Ivan Mincik <ivan.mincik at gmail.com> 2013-06-03
@@ -66648,7 +66930,7 @@ Emilio Loi <loi at faunalia.it> 2013-04-30
Merge branch 'styles_to_db' of https://github.com/el1073/Quantum-GIS into styles_to_db
Conflicts:
-src/core/qgsvectordataprovider.h
+ src/core/qgsvectordataprovider.h
Emilio Loi <loi at faunalia.it> 2013-04-30
@@ -66660,9 +66942,9 @@ Emilio Loi <loi at faunalia.it> 2013-04-30
Merge branch 'master' of https://github.com/qgis/Quantum-GIS into styles_to_db
Conflicts:
-python/console/console_editor.py
-src/core/qgsvectordataprovider.h
-src/core/qgsvectorfilewriter.cpp
+ python/console/console_editor.py
+ src/core/qgsvectordataprovider.h
+ src/core/qgsvectorfilewriter.cpp
Merge: c499df7 009ba1b
Emilio Loi <loi at faunalia.it> 2013-04-30
@@ -66670,9 +66952,9 @@ Emilio Loi <loi at faunalia.it> 2013-04-30
Merge branch 'master' of https://github.com/qgis/Quantum-GIS into styles_to_db
Conflicts:
-python/console/console_editor.py
-src/core/qgsvectordataprovider.h
-src/core/qgsvectorfilewriter.cpp
+ python/console/console_editor.py
+ src/core/qgsvectordataprovider.h
+ src/core/qgsvectorfilewriter.cpp
Merge: 7dc0e51 2f9cb93
Matthias Kuhn <matthias.kuhn at gmx.ch> 2013-04-30
@@ -66738,42 +67020,42 @@ olivierdalang <olivier.dalang at gmail.com> 2013-04-24
SVG : clean arrows
Conflicts:
-images/svg/north_arrows/NorthArrow1.svg
-images/svg/north_arrows/NorthArrow10.svg
-images/svg/north_arrows/NorthArrow11.svg
-images/svg/north_arrows/NorthArrow12.svg
-images/svg/north_arrows/NorthArrow13.svg
-images/svg/north_arrows/NorthArrow14.svg
-images/svg/north_arrows/NorthArrow15.svg
-images/svg/north_arrows/NorthArrow16.svg
-images/svg/north_arrows/NorthArrow2.svg
-images/svg/north_arrows/NorthArrow4.svg
-images/svg/north_arrows/NorthArrow5.svg
-images/svg/north_arrows/NorthArrow6.svg
-images/svg/north_arrows/NorthArrow_blackgreenblack.svg
-images/svg/north_arrows/NorthArrow_blackwhiteblack.svg
-images/svg/north_arrows/NorthArrow_blackyellowblack.svg
-images/svg/north_arrows/NorthArrow_bluegreenblue.svg
-images/svg/north_arrows/NorthArrow_source.svg
-images/svg/north_arrows/default.svg
-images/svg/north_arrows/north-arrow_0_qgis_decoration.svg
-images/svg/north_arrows/north-arrow_10_with_map_layers.svg
-images/svg/north_arrows/north-arrow_11_simple_corner.svg
-images/svg/north_arrows/north-arrow_12_triangular_arrows_with_worldmap.svg
-images/svg/north_arrows/north-arrow_13_checkerboard_earth.svg
-images/svg/north_arrows/north-arrow_14_steering_wheel.svg
-images/svg/north_arrows/north-arrow_15_checkerboard_corner_arrows.svg
-images/svg/north_arrows/north-arrow_16_corner_arrows_unfilled_with_circle.svg
-images/svg/north_arrows/north-arrow_17_corner_n_e.svg
-images/svg/north_arrows/north-arrow_1_simple_half_arrow.svg
-images/svg/north_arrows/north-arrow_2_simple_half_arrow.svg
-images/svg/north_arrows/north-arrow_3_simple_symmetric_triangular.svg
-images/svg/north_arrows/north-arrow_4_double_arrow.svg
-images/svg/north_arrows/north-arrow_5_arrow_in_circle_small_n.svg
-images/svg/north_arrows/north-arrow_6_unfilled_big_arrow_symmetric.svg
-images/svg/north_arrows/north-arrow_7_big_circle_with_small_arrow_unfilled_n.svg
-images/svg/north_arrows/north-arrow_8_checkered.svg
-images/svg/north_arrows/north-arrow_9_half_arrow_unfilled.svg
+ images/svg/north_arrows/NorthArrow1.svg
+ images/svg/north_arrows/NorthArrow10.svg
+ images/svg/north_arrows/NorthArrow11.svg
+ images/svg/north_arrows/NorthArrow12.svg
+ images/svg/north_arrows/NorthArrow13.svg
+ images/svg/north_arrows/NorthArrow14.svg
+ images/svg/north_arrows/NorthArrow15.svg
+ images/svg/north_arrows/NorthArrow16.svg
+ images/svg/north_arrows/NorthArrow2.svg
+ images/svg/north_arrows/NorthArrow4.svg
+ images/svg/north_arrows/NorthArrow5.svg
+ images/svg/north_arrows/NorthArrow6.svg
+ images/svg/north_arrows/NorthArrow_blackgreenblack.svg
+ images/svg/north_arrows/NorthArrow_blackwhiteblack.svg
+ images/svg/north_arrows/NorthArrow_blackyellowblack.svg
+ images/svg/north_arrows/NorthArrow_bluegreenblue.svg
+ images/svg/north_arrows/NorthArrow_source.svg
+ images/svg/north_arrows/default.svg
+ images/svg/north_arrows/north-arrow_0_qgis_decoration.svg
+ images/svg/north_arrows/north-arrow_10_with_map_layers.svg
+ images/svg/north_arrows/north-arrow_11_simple_corner.svg
+ images/svg/north_arrows/north-arrow_12_triangular_arrows_with_worldmap.svg
+ images/svg/north_arrows/north-arrow_13_checkerboard_earth.svg
+ images/svg/north_arrows/north-arrow_14_steering_wheel.svg
+ images/svg/north_arrows/north-arrow_15_checkerboard_corner_arrows.svg
+ images/svg/north_arrows/north-arrow_16_corner_arrows_unfilled_with_circle.svg
+ images/svg/north_arrows/north-arrow_17_corner_n_e.svg
+ images/svg/north_arrows/north-arrow_1_simple_half_arrow.svg
+ images/svg/north_arrows/north-arrow_2_simple_half_arrow.svg
+ images/svg/north_arrows/north-arrow_3_simple_symmetric_triangular.svg
+ images/svg/north_arrows/north-arrow_4_double_arrow.svg
+ images/svg/north_arrows/north-arrow_5_arrow_in_circle_small_n.svg
+ images/svg/north_arrows/north-arrow_6_unfilled_big_arrow_symmetric.svg
+ images/svg/north_arrows/north-arrow_7_big_circle_with_small_arrow_unfilled_n.svg
+ images/svg/north_arrows/north-arrow_8_checkered.svg
+ images/svg/north_arrows/north-arrow_9_half_arrow_unfilled.svg
olivierdalang <olivier.dalang at gmail.com> 2013-04-23
@@ -66853,7 +67135,7 @@ Emilio Loi <loi at faunalia.it> 2013-04-29
Merge branch 'master' of https://github.com/qgis/Quantum-GIS into styles_to_db
Conflicts:
-python/console/console_editor.py
+ python/console/console_editor.py
Merge: 2232c3d 1959182
Chris Crook <ccrook at linz.govt.nz> 2013-04-29
@@ -67007,9 +67289,9 @@ Emilio Loi <loi at faunalia.it> 2013-04-26
Merge branch 'master' of https://github.com/qgis/Quantum-GIS into styles_to_db
Conflicts:
-python/console/console_editor.py
-src/core/qgsvectordataprovider.h
-src/core/qgsvectorfilewriter.cpp
+ python/console/console_editor.py
+ src/core/qgsvectordataprovider.h
+ src/core/qgsvectorfilewriter.cpp
Merge: 02fa729 f7cce9c
Borys Jurgiel <info at borysjurgiel.pl> 2013-04-26
@@ -67142,7 +67424,7 @@ Nathan Woodrow <nathan.woodrow at mapsolutions.com.au> 2013-04-26
Add workaround for loading forms with custom widgets from PyQt4
-More information: qt-project.org/forums/viewthread/27098/
+ More information: qt-project.org/forums/viewthread/27098/
Matthias Kuhn <matthias.kuhn at gmx.ch> 2013-04-14
@@ -67330,7 +67612,7 @@ Emilio Loi <loi at faunalia.it> 2013-04-22
Merge branch 'master' of git://github.com/qgis/Quantum-GIS into styles_to_db
Conflicts:
-src/ui/qgsvectorlayerpropertiesbase.ui
+ src/ui/qgsvectorlayerpropertiesbase.ui
Minoru Akagi <akaginch at gmail.com> 2013-04-22
@@ -69332,9 +69614,9 @@ Nathan Woodrow <woodrow.nathan at gmail.com> 2013-04-01
Data defined symbol UI clean up
-- Reduce margins
-- Remove cell selection
-- Adjust first column width
+ - Reduce margins
+ - Remove cell selection
+ - Adjust first column width
Merge: 6c3f418 7b6e322
Tim Sutton <tim at linfiniti.com> 2013-04-01
@@ -69895,7 +70177,7 @@ vinayan <vinayan at vinayan-MS-7623.(none)> 2012-12-12
Conflicts:
-src/plugins/CMakeLists.txt
+ src/plugins/CMakeLists.txt
fixed issues in duplicate rule where zooming was not possible..renamed 'Test' to 'Rule'
@@ -72804,14 +73086,14 @@ Martin Dobias <wonder.sk at gmail.com> 2013-01-24
Merge remote-tracking branch 'jef/oraclespatial-nva' into new_vector_api
Conflicts:
-doc/TRANSLATORS
-i18n/qgis_de.ts
-src/app/qgisapp.cpp
-src/core/qgis.cpp
-src/core/qgsvectorlayerimport.cpp
-src/providers/oracle/CMakeLists.txt
-src/providers/oracle/qgsoracleprovider.cpp
-src/providers/oracle/qgsoracleprovider.h
+ doc/TRANSLATORS
+ i18n/qgis_de.ts
+ src/app/qgisapp.cpp
+ src/core/qgis.cpp
+ src/core/qgsvectorlayerimport.cpp
+ src/providers/oracle/CMakeLists.txt
+ src/providers/oracle/qgsoracleprovider.cpp
+ src/providers/oracle/qgsoracleprovider.h
Merge: dda51c6 5f70a68
Martin Dobias <wonder.sk at gmail.com> 2013-01-23
@@ -72819,16 +73101,16 @@ Martin Dobias <wonder.sk at gmail.com> 2013-01-23
Merge remote-tracking branch 'origin/master' into new_vector_api
Conflicts:
-python/core/qgsvectordataprovider.sip
-src/app/legend/qgslegendlayer.cpp
-src/app/qgisapp.cpp
-src/app/qgsmergeattributesdialog.cpp
-src/core/qgsvectordataprovider.cpp
-src/core/qgsvectordataprovider.h
-src/core/qgsvectorlayer.cpp
-src/gui/qgssearchquerybuilder.cpp
-src/providers/postgres/qgspostgresprovider.cpp
-src/providers/wfs/CMakeLists.txt
+ python/core/qgsvectordataprovider.sip
+ src/app/legend/qgslegendlayer.cpp
+ src/app/qgisapp.cpp
+ src/app/qgsmergeattributesdialog.cpp
+ src/core/qgsvectordataprovider.cpp
+ src/core/qgsvectordataprovider.h
+ src/core/qgsvectorlayer.cpp
+ src/gui/qgssearchquerybuilder.cpp
+ src/providers/postgres/qgspostgresprovider.cpp
+ src/providers/wfs/CMakeLists.txt
Tim Sutton <tim at linfiniti.com> 2013-01-24
@@ -72979,9 +73261,9 @@ Victor Olaya <volayaf at gmail.com> 2013-01-21
Merge branch 'master' of https://github.com/qgis/Quantum-GIS
Conflicts:
-python/plugins/sextante/algs/ftools/Difference.py
-python/plugins/sextante/algs/ftools/Intersection.py
-python/plugins/sextante/outputs/OutputTable.py
+ python/plugins/sextante/algs/ftools/Difference.py
+ python/plugins/sextante/algs/ftools/Intersection.py
+ python/plugins/sextante/outputs/OutputTable.py
Victor Olaya <volayaf at gmail.com> 2013-01-21
@@ -73678,27 +73960,27 @@ Martin Dobias <wonder.sk at gmail.com> 2012-12-18
Fixed tests.
Conflicts:
-src/app/legend/qgslegendlayer.cpp
-src/app/qgsattributedialog.cpp
-src/app/qgsattributedialog.h
-src/app/qgslabelpropertydialog.cpp
-src/app/qgsmaptoollabel.cpp
-src/app/qgsvectorlayerproperties.cpp
-src/core/CMakeLists.txt
-src/core/composer/qgsatlascomposition.cpp
-src/core/qgsexpression.cpp
-src/core/qgspallabeling.cpp
-src/core/qgsvectorlayer.cpp
-src/core/qgsvectorlayer.h
-src/core/qgsvectorlayerimport.cpp
-src/mapserver/qgsprojectparser.cpp
-src/mapserver/qgswfsserver.cpp
-src/mapserver/qgswfsserver.h
-src/mapserver/qgswmsserver.cpp
-src/providers/postgres/qgspostgresprovider.cpp
-src/providers/spatialite/qgsspatialiteprovider.h
-tests/src/core/testqgsexpression.cpp
-tests/src/python/test_qgsmemoryprovider.py
+ src/app/legend/qgslegendlayer.cpp
+ src/app/qgsattributedialog.cpp
+ src/app/qgsattributedialog.h
+ src/app/qgslabelpropertydialog.cpp
+ src/app/qgsmaptoollabel.cpp
+ src/app/qgsvectorlayerproperties.cpp
+ src/core/CMakeLists.txt
+ src/core/composer/qgsatlascomposition.cpp
+ src/core/qgsexpression.cpp
+ src/core/qgspallabeling.cpp
+ src/core/qgsvectorlayer.cpp
+ src/core/qgsvectorlayer.h
+ src/core/qgsvectorlayerimport.cpp
+ src/mapserver/qgsprojectparser.cpp
+ src/mapserver/qgswfsserver.cpp
+ src/mapserver/qgswfsserver.h
+ src/mapserver/qgswmsserver.cpp
+ src/providers/postgres/qgspostgresprovider.cpp
+ src/providers/spatialite/qgsspatialiteprovider.h
+ tests/src/core/testqgsexpression.cpp
+ tests/src/python/test_qgsmemoryprovider.py
Martin Dobias <wonder.sk at gmail.com> 2012-12-17
@@ -74494,7 +74776,7 @@ Victor Olaya <volayaf at gmail.com> 2012-12-15
Merge branch 'master' of https://github.com/qgis/Quantum-GIS
Conflicts:
-python/plugins/sextante/grass/ext/CMakeLists.txt
+ python/plugins/sextante/grass/ext/CMakeLists.txt
Victor Olaya <volayaf at gmail.com> 2012-12-15
@@ -74673,7 +74955,7 @@ Victor Olaya <volayaf at gmail.com> 2012-12-12
Merge branch 'master' of https://github.com/qgis/Quantum-GIS
Conflicts:
-python/plugins/sextante/grass/GrassAlgorithm.py
+ python/plugins/sextante/grass/GrassAlgorithm.py
Victor Olaya <volayaf at gmail.com> 2012-12-12
@@ -74704,7 +74986,7 @@ Hugo Mercier <hugo.mercier at oslandia.com> 2012-12-11
Merge branch 'master' of https://github.com/qgis/Quantum-GIS
Conflicts:
-src/core/composer/qgsatlascomposition.cpp
+ src/core/composer/qgsatlascomposition.cpp
Hugo Mercier <hugo.mercier at oslandia.com> 2012-12-11
@@ -78535,8 +78817,8 @@ Hugo Mercier <hugo.mercier at oslandia.com> 2012-10-04
Merge branch 'atlas' into atlas2
Conflicts:
-python/core/composer/qgscomposition.sip
-tests/src/python/CMakeLists.txt
+ python/core/composer/qgscomposition.sip
+ tests/src/python/CMakeLists.txt
Hugo Mercier <hugo.mercier at oslandia.com> 2012-10-04
@@ -78946,7 +79228,7 @@ Hugo Mercier <hugo.mercier at oslandia.com> 2012-09-28
Merge branch 'master' of https://github.com/qgis/Quantum-GIS into atlas
Conflicts:
-src/core/composer/qgscomposition.cpp
+ src/core/composer/qgscomposition.cpp
Hugo Mercier <hugo.mercier at oslandia.com> 2012-09-28
@@ -79130,7 +79412,7 @@ Hugo Mercier <hugo.mercier at oslandia.com> 2012-09-26
Merge branch 'master' of https://github.com/qgis/Quantum-GIS into atlas
Conflicts:
-python/core/qgsexpression.sip
+ python/core/qgsexpression.sip
Add a missing function to QgsExpression
@@ -81123,7 +81405,7 @@ Matthias Kuhn <matthias.kuhn at gmx.ch> 2012-08-29
Merge branch 'master' of https://github.com/matthias-kuhn/Quantum-GIS
Conflicts:
-src/app/qgsdiagramproperties.cpp
+ src/app/qgsdiagramproperties.cpp
Merge: c8a3321 b97f2fc
Matthias Kuhn <matthias.kuhn at gmx.ch> 2012-08-29
@@ -81874,7 +82156,7 @@ Matthias Kuhn <matthias.kuhn at gmx.ch> 2012-08-16
Merge diagram icons
Conflicts:
-src/app/qgsdiagramproperties.cpp
+ src/app/qgsdiagramproperties.cpp
Matthias Kuhn <matthias.kuhn at gmx.ch> 2012-08-16
@@ -81986,7 +82268,7 @@ Martin Dobias <wonder.sk at gmail.com> 2012-08-14
Merge remote-tracking branch 'arun/gsoc'
Conflicts:
-src/gui/symbology-ng/qgssymbolv2selectordialog.cpp
+ src/gui/symbology-ng/qgssymbolv2selectordialog.cpp
Radim Blazek <radim.blazek at gmail.com> 2012-08-14
@@ -83383,7 +83665,7 @@ Hugo Mercier <hugo.mercier at oslandia.com> 2012-07-25
Merge branch 'master' of git://github.com/qgis/Quantum-GIS
Conflicts:
-src/core/symbology-ng/qgsrulebasedrendererv2.cpp
+ src/core/symbology-ng/qgsrulebasedrendererv2.cpp
Merge: d039c3f 1bcd947
Marco Hugentobler <marco.hugentobler at sourcepole.ch> 2012-07-25
@@ -91637,7 +91919,7 @@ Martin Dobias <wonder.sk at gmail.com> 2012-01-24
[FEATURE] Merge branch 'rules' - new rule-based rendering
Conflicts:
-src/gui/symbology-ng/qgsgraduatedsymbolrendererv2widget.cpp
+ src/gui/symbology-ng/qgsgraduatedsymbolrendererv2widget.cpp
Martin Dobias <wonder.sk at gmail.com> 2012-01-24
@@ -92450,7 +92732,7 @@ Marco Bernasocchi <marco at bernawebdesign.ch> 2012-01-05
Merge branch 'master' of https://github.com/qgis/Quantum-GIS into android
Conflicts:
-src/ui/qgsnewspatialitelayerdialogbase.ui
+ src/ui/qgsnewspatialitelayerdialogbase.ui
Marco Hugentobler <marco.hugentobler at sourcepole.ch> 2012-01-05
@@ -94671,8 +94953,8 @@ Nathan Woodrow <madmanwoo at gmail.com> 2011-10-18
Merge remote-tracking branch 'upstream/master' into expression-labels
Conflicts:
-src/core/qgsexpression.cpp
-src/gui/CMakeLists.txt
+ src/core/qgsexpression.cpp
+ src/gui/CMakeLists.txt
Nathan Woodrow <madmanwoo at gmail.com> 2011-10-18
@@ -94903,7 +95185,7 @@ Giuseppe Sucameli <brush.tyler at gmail.com> 2011-10-07
Merge remote-tracking branch 'brushtyler/master'
Conflicts:
-src/providers/postgres/qgspostgresprovider.cpp
+ src/providers/postgres/qgspostgresprovider.cpp
Giuseppe Sucameli <brush.tyler at gmail.com> 2011-10-07
@@ -94940,7 +95222,7 @@ Sergey Yakushevs <yakushevs at list.ru> 2011-10-04
Merge remote branch 'pb/master'
Conflicts:
-src/plugins/roadgraph/linevectorlayerdirector.cpp
+ src/plugins/roadgraph/linevectorlayerdirector.cpp
Martin Dobias <wonder.sk at gmail.com> 2011-10-03
@@ -95081,13 +95363,13 @@ Sergey Yakushevs <yakushevs at list.ru> 2011-09-27
Merge remote branch 'pb/master' into network-analysis
Conflicts:
-python/CMakeLists.txt
-src/analysis/network/qgsgraphbuilder.h
-src/plugins/roadgraph/graphbuilder.h
-src/plugins/roadgraph/linevectorlayerdirector.cpp
-src/plugins/roadgraph/simplegraphbuilder.cpp
-src/plugins/roadgraph/utils.cpp
-src/plugins/roadgraph/utils.h
+ python/CMakeLists.txt
+ src/analysis/network/qgsgraphbuilder.h
+ src/plugins/roadgraph/graphbuilder.h
+ src/plugins/roadgraph/linevectorlayerdirector.cpp
+ src/plugins/roadgraph/simplegraphbuilder.cpp
+ src/plugins/roadgraph/utils.cpp
+ src/plugins/roadgraph/utils.h
Nathan Woodrow <madmanwoo at gmail.com> 2011-09-26
@@ -95425,7 +95707,7 @@ Martin Dobias <wonder.sk at gmail.com> 2011-08-30
Merge remote-tracking branch 'remotes/giuseppe/dataitems' into dataitems
Conflicts:
-src/app/CMakeLists.txt
+ src/app/CMakeLists.txt
Martin Dobias <wonder.sk at gmail.com> 2011-08-30
@@ -95892,9 +96174,9 @@ NathanW <woodrow.nathan at gmail.com> 2011-08-08
Merge remote branch 'upstream/master' into expression-labels
Conflicts:
-src/core/qgspallabeling.cpp
-src/gui/CMakeLists.txt
-src/ui/qgslabelingguibase.ui
+ src/core/qgspallabeling.cpp
+ src/gui/CMakeLists.txt
+ src/ui/qgslabelingguibase.ui
marco <marco at marco-laptop.(none)> 2011-08-08
@@ -97099,7 +97381,7 @@ NathanW <woodrow.nathan at gmail.com> 2011-07-03
Fixed merge conflict in pallabeling
Conflicts:
-src/core/qgspallabeling.cpp
+ src/core/qgspallabeling.cpp
Marco Hugentobler <marco.hugentobler at sourcepole.ch> 2011-07-02
@@ -97959,13 +98241,13 @@ Sergey Yakushevs <yakushevs at list.ru> 2011-05-31
Merge remote branch 'pb/master' into network-analysis
Conflicts:
-src/analysis/network/qgsdistanceedgeproperter.cpp
-src/analysis/network/qgsgraphbuilder.h
-src/plugins/roadgraph/graphbuilder.h
-src/plugins/roadgraph/linevectorlayerdirector.cpp
-src/plugins/roadgraph/roadgraphplugin.cpp
-src/plugins/roadgraph/shortestpathwidget.cpp
-src/plugins/roadgraph/simplegraphbuilder.cpp
+ src/analysis/network/qgsdistanceedgeproperter.cpp
+ src/analysis/network/qgsgraphbuilder.h
+ src/plugins/roadgraph/graphbuilder.h
+ src/plugins/roadgraph/linevectorlayerdirector.cpp
+ src/plugins/roadgraph/roadgraphplugin.cpp
+ src/plugins/roadgraph/shortestpathwidget.cpp
+ src/plugins/roadgraph/simplegraphbuilder.cpp
Merge: 8bbdde6 c8dd587
Sergey Yakushevs <yakushevs at list.ru> 2011-05-31
@@ -97973,7 +98255,7 @@ Sergey Yakushevs <yakushevs at list.ru> 2011-05-31
Merge remote branch 'pb/master'
Conflicts:
-src/plugins/roadgraph/linevectorlayerdirector.cpp
+ src/plugins/roadgraph/linevectorlayerdirector.cpp
Marco Hugentobler <marco.hugentobler at sourcepole.ch> 2011-05-31
@@ -98424,12 +98706,12 @@ Martin Dobias <wonder.sk at gmail.com> 2011-05-13
Merge branch 'master' into dbl
Conflicts:
-images/splash/splash.png
-src/CMakeLists.txt
-src/app/main.cpp
-src/app/qgsvectorlayerproperties.cpp
-src/core/qgsvectorlayer.cpp
-src/providers/wms/qgswmssourceselect.cpp
+ images/splash/splash.png
+ src/CMakeLists.txt
+ src/app/main.cpp
+ src/app/qgsvectorlayerproperties.cpp
+ src/core/qgsvectorlayer.cpp
+ src/providers/wms/qgswmssourceselect.cpp
Martin Dobias <wonder.sk at gmail.com> 2011-05-13
@@ -104210,7 +104492,7 @@ gsherman <gsherman at c8812cc2-4d05-0410-92ff-de0c093fc19c> 2010-12-11
Merge branch 'master' of github.com:qgis/qgis
Conflicts:
-README
+ README
git-svn-id: http://svn.osgeo.org/qgis/trunk@14888 c8812cc2-4d05-0410-92ff-de0c093fc19c
@@ -173245,7 +173527,7 @@ gsherman <gsherman at c8812cc2-4d05-0410-92ff-de0c093fc19c> 2004-03-01
1. Added bounds checking for selecting features.
2. Created wkbPoint structure for building WKB (well known binary) representation
- of the point.
+ of the point.
3. Implementation is not complete.
diff --git a/debian/changelog b/debian/changelog
index 4941a01..97463cb 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,8 +1,14 @@
-qgis (2.14.6) UNRELEASED; urgency=medium
+qgis (2.14.7) UNRELEASED; urgency=medium
+
+ * Release of 2.14.7
+
+ -- Jürgen E. Fischer <jef at norbit.de> Fri, 23 Sep 2016 20:23:30 +0200
+
+qgis (2.14.6) unstable; urgency=medium
* Release of 2.14.6
- -- Jürgen E. Fischer <jef at norbit.de> Fri, 26 Aug 2016 13:57:14 +0200
+ -- Jürgen E. Fischer <jef at norbit.de> Fri, 23 Sep 2016 20:23:29 +0200
qgis (2.14.5) unstable; urgency=medium
diff --git a/debian/python-qgis.install.in b/debian/python-qgis.install.in
index 87920d8..a5d64e1 100644
--- a/debian/python-qgis.install.in
+++ b/debian/python-qgis.install.in
@@ -9,3 +9,4 @@ usr/lib/python*/*-packages/qgis/server/*
usr/lib/python*/*-packages/qgis/testing/*
#wheezy precise#usr/lib/python*/*-packages/pyspatialite/*.py
#wheezy precise#usr/lib/python*/*-packages/pyspatialite/*.so
+#sid stretch#usr/lib/python*/*-packages/PyQt4/*.so
diff --git a/debian/rules b/debian/rules
index 1d87840..508e06c 100755
--- a/debian/rules
+++ b/debian/rules
@@ -110,6 +110,10 @@ ifneq (,$(findstring $(DISTRIBUTION),"sid stretch"))
CMAKE_OPTS += -DPOSTGRES_LIBRARY=/usr/lib/$(DEB_BUILD_MULTIARCH)/libpq.so
endif
+ifneq (,$(findstring $(DISTRIBUTION),"sid stretch"))
+ CMAKE_OPTS += -DWITH_INTERNAL_WEBKIT_BINDINGS=TRUE
+endif
+
ifneq (,$(findstring $(DISTRIBUTION),"sid"))
CMAKE_OPTS += -DGEOS_LIBRARY=/usr/lib/$(DEB_BUILD_MULTIARCH)/libgeos_c.so
endif
diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt
index 1d04545..df06f1d 100644
--- a/python/CMakeLists.txt
+++ b/python/CMakeLists.txt
@@ -307,3 +307,15 @@ FOREACH(module ${PY_MODULES})
ENDFOREACH(pyfile)
PY_COMPILE(py${module} "${QGIS_PYTHON_OUTPUT_DIRECTORY}/${module}")
ENDFOREACH(module)
+
+SET (WITH_INTERNAL_WEBKIT_BINDINGS FALSE CACHE BOOL "Build internal QtWebKit bindings")
+IF(WITH_INTERNAL_WEBKIT_BINDINGS)
+ INCLUDE_DIRECTORIES(${QT_QTWEBKIT_INCLUDE_DIR})
+ FILE(GLOB_RECURSE sip_files_qtwebkit QtWebKit/*.sip)
+ SET(SIP_EXTRA_FILES_DEPEND ${sip_files_qtwebkit})
+ SET(SIP_EXTRA_OPTIONS ${PYQT_SIP_FLAGS} -o -a ${CMAKE_BINARY_DIR}/python/PyQt4.QtWebKit.api)
+
+ SET (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PYTHON_OUTPUT_DIRECTORY}/PyQt4)
+ SET (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PYTHON_OUTPUT_DIRECTORY}/PyQt4)
+ ADD_SIP_PYTHON_MODULE(PyQt4.QtWebKit QtWebKit/QtWebKitmod.sip QtWebKit QtCore QtGui QtNetwork)
+ENDIF(WITH_INTERNAL_WEBKIT_BINDINGS)
diff --git a/python/QtWebKit/QtWebKitmod.sip b/python/QtWebKit/QtWebKitmod.sip
new file mode 100644
index 0000000..dbb17f3
--- /dev/null
+++ b/python/QtWebKit/QtWebKitmod.sip
@@ -0,0 +1,63 @@
+// QtWebKitmod.sip generated by MetaSIP
+//
+// This file is part of the QtWebKit Python extension module.
+//
+// Copyright (c) 2015 Riverbank Computing Limited <info at riverbankcomputing.com>
+//
+// This file is part of PyQt4.
+//
+// This file may be used under the terms of the GNU General Public License
+// version 3.0 as published by the Free Software Foundation and appearing in
+// the file LICENSE included in the packaging of this file. Please review the
+// following information to ensure the GNU General Public License version 3.0
+// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+//
+// If you do not wish to use this file under the terms of the GPL version 3.0
+// then you may purchase a commercial license. For more information contact
+// info at riverbankcomputing.com.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+
+%Module(name=PyQt4.QtWebKit, keyword_arguments="Optional")
+
+%Import QtCore/QtCoremod.sip
+%Import QtGui/QtGuimod.sip
+%Import QtNetwork/QtNetworkmod.sip
+
+%Copying
+Copyright (c) 2015 Riverbank Computing Limited <info at riverbankcomputing.com>
+
+This file is part of PyQt4.
+
+This file may be used under the terms of the GNU General Public License
+version 3.0 as published by the Free Software Foundation and appearing in
+the file LICENSE included in the packaging of this file. Please review the
+following information to ensure the GNU General Public License version 3.0
+requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+
+If you do not wish to use this file under the terms of the GPL version 3.0
+then you may purchase a commercial license. For more information contact
+info at riverbankcomputing.com.
+
+This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+%End
+
+%DefaultSupertype sip.simplewrapper
+
+%Include qgraphicswebview.sip
+%Include qwebdatabase.sip
+%Include qwebelement.sip
+%Include qwebframe.sip
+%Include qwebkitglobal.sip
+%Include qwebhistory.sip
+%Include qwebhistoryinterface.sip
+%Include qwebinspector.sip
+%Include qwebkitversion.sip
+%Include qwebpage.sip
+%Include qwebpluginfactory.sip
+%Include qwebsecurityorigin.sip
+%Include qwebsettings.sip
+%Include qwebview.sip
diff --git a/python/QtWebKit/__init__.py b/python/QtWebKit/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/python/QtWebKit/qgraphicswebview.sip b/python/QtWebKit/qgraphicswebview.sip
new file mode 100644
index 0000000..e006416
--- /dev/null
+++ b/python/QtWebKit/qgraphicswebview.sip
@@ -0,0 +1,150 @@
+// qgraphicswebview.sip generated by MetaSIP
+//
+// This file is part of the QtWebKit Python extension module.
+//
+// Copyright (c) 2015 Riverbank Computing Limited <info at riverbankcomputing.com>
+//
+// This file is part of PyQt4.
+//
+// This file may be used under the terms of the GNU General Public License
+// version 3.0 as published by the Free Software Foundation and appearing in
+// the file LICENSE included in the packaging of this file. Please review the
+// following information to ensure the GNU General Public License version 3.0
+// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+//
+// If you do not wish to use this file under the terms of the GPL version 3.0
+// then you may purchase a commercial license. For more information contact
+// info at riverbankcomputing.com.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+
+%If (Qt_4_6_0 -)
+
+class QGraphicsWebView : QGraphicsWidget
+{
+%TypeHeaderCode
+#include <qgraphicswebview.h>
+%End
+
+%ConvertToSubClassCode
+ sipType = 0;
+
+ // For some reason Qt doesn't allocate a new type for this so we have to test
+ // the numeric and QObject types.
+ if (sipCpp->type() == 11)
+ {
+ QGraphicsWidget *gw = static_cast<QGraphicsWidget *>(sipCpp);
+
+ if (gw->inherits("QGraphicsWebView"))
+ {
+ *sipCppRet = static_cast<QGraphicsWebView *>(gw);
+ sipType = sipType_QGraphicsWebView;
+ }
+ }
+%End
+
+public:
+ explicit QGraphicsWebView(QGraphicsItem *parent /TransferThis/ = 0);
+ virtual ~QGraphicsWebView();
+ QWebPage *page() const;
+ void setPage(QWebPage * /KeepReference/);
+ QUrl url() const;
+ void setUrl(const QUrl &);
+ QString title() const;
+ QIcon icon() const;
+ qreal zoomFactor() const;
+ void setZoomFactor(qreal);
+ bool isModified() const;
+ void load(const QUrl &url) /ReleaseGIL/;
+ void load(const QNetworkRequest &request, QNetworkAccessManager::Operation operation = QNetworkAccessManager::GetOperation, const QByteArray &body = QByteArray()) /ReleaseGIL/;
+ void setHtml(const QString &html, const QUrl &baseUrl = QUrl());
+ void setContent(const QByteArray &data, const QString &mimeType = QString(), const QUrl &baseUrl = QUrl());
+ QWebHistory *history() const;
+ QWebSettings *settings() const;
+ QAction *pageAction(QWebPage::WebAction action) const;
+ void triggerPageAction(QWebPage::WebAction action, bool checked = false);
+ bool findText(const QString &subString, QFlags<QWebPage::FindFlag> options = 0);
+ virtual void setGeometry(const QRectF &rect);
+ virtual void updateGeometry();
+ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+ virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value);
+ virtual bool event(QEvent *);
+ virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint) const;
+ virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
+
+public slots:
+ void stop();
+ void back();
+ void forward();
+ void reload();
+
+signals:
+ void loadStarted();
+ void loadFinished(bool);
+ void loadProgress(int progress);
+ void urlChanged(const QUrl &);
+ void titleChanged(const QString &);
+ void iconChanged();
+ void statusBarMessage(const QString &message);
+ void linkClicked(const QUrl &);
+
+protected:
+ virtual void mousePressEvent(QGraphicsSceneMouseEvent *);
+ virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *);
+ virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
+ virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *);
+ virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *);
+ virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *);
+ virtual void wheelEvent(QGraphicsSceneWheelEvent *);
+ virtual void keyPressEvent(QKeyEvent *);
+ virtual void keyReleaseEvent(QKeyEvent *);
+ virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *);
+ virtual void dragEnterEvent(QGraphicsSceneDragDropEvent *);
+ virtual void dragLeaveEvent(QGraphicsSceneDragDropEvent *);
+ virtual void dragMoveEvent(QGraphicsSceneDragDropEvent *);
+ virtual void dropEvent(QGraphicsSceneDragDropEvent *);
+ virtual void focusInEvent(QFocusEvent *);
+ virtual void focusOutEvent(QFocusEvent *);
+ virtual void inputMethodEvent(QInputMethodEvent *);
+ virtual bool focusNextPrevChild(bool next);
+ virtual bool sceneEvent(QEvent *);
+
+public:
+%If (Qt_4_7_0 -)
+ bool resizesToContents() const;
+%End
+%If (Qt_4_7_0 -)
+ void setResizesToContents(bool enabled);
+%End
+%If (Qt_4_7_0 -)
+ bool isTiledBackingStoreFrozen() const;
+%End
+%If (Qt_4_7_0 -)
+ void setTiledBackingStoreFrozen(bool frozen);
+%End
+%If (Qt_4_8_0 -)
+ QFlags<QPainter::RenderHint> renderHints() const;
+%End
+%If (Qt_4_8_0 -)
+ void setRenderHints(QFlags<QPainter::RenderHint> hints);
+%End
+%If (Qt_4_8_0 -)
+ void setRenderHint(QPainter::RenderHint hint, bool enabled = true);
+%End
+};
+
+%End
+
+%ModuleHeaderCode
+#if QT_VERSION >= 0x040600
+// This is needed by the %ConvertSubClassCode.
+#include <QGraphicsWebView>
+#endif
+
+// This is needed for Qt v5.0.0.
+#if defined(B0)
+#undef B0
+#endif
+%End
diff --git a/python/QtWebKit/qwebdatabase.sip b/python/QtWebKit/qwebdatabase.sip
new file mode 100644
index 0000000..5da7c2e
--- /dev/null
+++ b/python/QtWebKit/qwebdatabase.sip
@@ -0,0 +1,46 @@
+// qwebdatabase.sip generated by MetaSIP
+//
+// This file is part of the QtWebKit Python extension module.
+//
+// Copyright (c) 2015 Riverbank Computing Limited <info at riverbankcomputing.com>
+//
+// This file is part of PyQt4.
+//
+// This file may be used under the terms of the GNU General Public License
+// version 3.0 as published by the Free Software Foundation and appearing in
+// the file LICENSE included in the packaging of this file. Please review the
+// following information to ensure the GNU General Public License version 3.0
+// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+//
+// If you do not wish to use this file under the terms of the GPL version 3.0
+// then you may purchase a commercial license. For more information contact
+// info at riverbankcomputing.com.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+
+%If (Qt_4_5_0 -)
+
+class QWebDatabase
+{
+%TypeHeaderCode
+#include <qwebdatabase.h>
+%End
+
+public:
+ QWebDatabase(const QWebDatabase &other);
+ ~QWebDatabase();
+ QString name() const;
+ QString displayName() const;
+ qint64 expectedSize() const;
+ qint64 size() const;
+ QString fileName() const;
+ QWebSecurityOrigin origin() const;
+ static void removeDatabase(const QWebDatabase &db);
+%If (Qt_4_6_0 -)
+ static void removeAllDatabases();
+%End
+};
+
+%End
diff --git a/python/QtWebKit/qwebelement.sip b/python/QtWebKit/qwebelement.sip
new file mode 100644
index 0000000..bd158c5
--- /dev/null
+++ b/python/QtWebKit/qwebelement.sip
@@ -0,0 +1,144 @@
+// qwebelement.sip generated by MetaSIP
+//
+// This file is part of the QtWebKit Python extension module.
+//
+// Copyright (c) 2015 Riverbank Computing Limited <info at riverbankcomputing.com>
+//
+// This file is part of PyQt4.
+//
+// This file may be used under the terms of the GNU General Public License
+// version 3.0 as published by the Free Software Foundation and appearing in
+// the file LICENSE included in the packaging of this file. Please review the
+// following information to ensure the GNU General Public License version 3.0
+// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+//
+// If you do not wish to use this file under the terms of the GPL version 3.0
+// then you may purchase a commercial license. For more information contact
+// info at riverbankcomputing.com.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+
+%If (Qt_4_6_0 -)
+
+class QWebElement
+{
+%TypeHeaderCode
+#include <qwebelement.h>
+%End
+
+public:
+ QWebElement();
+ QWebElement(const QWebElement &);
+ ~QWebElement();
+ bool operator==(const QWebElement &o) const;
+ bool operator!=(const QWebElement &o) const;
+ bool isNull() const;
+ QWebElementCollection findAll(const QString &selectorQuery) const;
+ QWebElement findFirst(const QString &selectorQuery) const;
+ void setPlainText(const QString &text);
+ QString toPlainText() const;
+ void setOuterXml(const QString &markup);
+ QString toOuterXml() const;
+ void setInnerXml(const QString &markup);
+ QString toInnerXml() const;
+ void setAttribute(const QString &name, const QString &value);
+ void setAttributeNS(const QString &namespaceUri, const QString &name, const QString &value);
+ QString attribute(const QString &name, const QString &defaultValue = QString()) const;
+ QString attributeNS(const QString &namespaceUri, const QString &name, const QString &defaultValue = QString()) const;
+ bool hasAttribute(const QString &name) const;
+ bool hasAttributeNS(const QString &namespaceUri, const QString &name) const;
+ void removeAttribute(const QString &name);
+ void removeAttributeNS(const QString &namespaceUri, const QString &name);
+ bool hasAttributes() const;
+ QStringList attributeNames(const QString &namespaceUri = QString()) const;
+ QStringList classes() const;
+ bool hasClass(const QString &name) const;
+ void addClass(const QString &name);
+ void removeClass(const QString &name);
+ void toggleClass(const QString &name);
+ bool hasFocus() const;
+ void setFocus();
+ QRect geometry() const;
+ QString tagName() const;
+ QString prefix() const;
+ QString localName() const;
+ QString namespaceUri() const;
+ QWebElement parent() const;
+ QWebElement firstChild() const;
+ QWebElement lastChild() const;
+ QWebElement nextSibling() const;
+ QWebElement previousSibling() const;
+ QWebElement document() const;
+ QWebFrame *webFrame() const;
+ void appendInside(const QString &markup);
+ void appendInside(const QWebElement &element);
+ void prependInside(const QString &markup);
+ void prependInside(const QWebElement &element);
+ void appendOutside(const QString &markup);
+ void appendOutside(const QWebElement &element);
+ void prependOutside(const QString &markup);
+ void prependOutside(const QWebElement &element);
+ void encloseContentsWith(const QWebElement &element);
+ void encloseContentsWith(const QString &markup);
+ void encloseWith(const QString &markup);
+ void encloseWith(const QWebElement &element);
+ void replace(const QString &markup);
+ void replace(const QWebElement &element);
+ QWebElement clone() const;
+ QWebElement &takeFromDocument();
+ void removeFromDocument();
+ void removeAllChildren();
+ QVariant evaluateJavaScript(const QString &scriptSource);
+
+ enum StyleResolveStrategy
+ {
+ InlineStyle,
+ CascadedStyle,
+ ComputedStyle,
+ };
+
+ QString styleProperty(const QString &name, QWebElement::StyleResolveStrategy strategy) const;
+ void setStyleProperty(const QString &name, const QString &value);
+ void render(QPainter *painter);
+%If (Qt_4_8_0 -)
+ void render(QPainter *painter, const QRect &clip);
+%End
+};
+
+%End
+%If (Qt_4_6_0 -)
+
+class QWebElementCollection
+{
+%TypeHeaderCode
+#include <qwebelement.h>
+%End
+
+public:
+ QWebElementCollection();
+ QWebElementCollection(const QWebElement &contextElement, const QString &query);
+ QWebElementCollection(const QWebElementCollection &);
+ ~QWebElementCollection();
+ QWebElementCollection operator+(const QWebElementCollection &other) const;
+ QWebElementCollection &operator+=(const QWebElementCollection &other);
+ void append(const QWebElementCollection &collection);
+ int count() const /__len__/;
+ QWebElement at(int i) const;
+ QWebElement operator[](int i) const;
+%MethodCode
+ SIP_SSIZE_T idx = sipConvertFromSequenceIndex(a0, sipCpp->count());
+
+ if (idx < 0)
+ sipIsErr = 1;
+ else
+ sipRes = new QWebElement(sipCpp->operator[]((int)idx));
+%End
+
+ QWebElement first() const;
+ QWebElement last() const;
+ QList<QWebElement> toList() const;
+};
+
+%End
diff --git a/python/QtWebKit/qwebframe.sip b/python/QtWebKit/qwebframe.sip
new file mode 100644
index 0000000..30768a2
--- /dev/null
+++ b/python/QtWebKit/qwebframe.sip
@@ -0,0 +1,244 @@
+// qwebframe.sip generated by MetaSIP
+//
+// This file is part of the QtWebKit Python extension module.
+//
+// Copyright (c) 2015 Riverbank Computing Limited <info at riverbankcomputing.com>
+//
+// This file is part of PyQt4.
+//
+// This file may be used under the terms of the GNU General Public License
+// version 3.0 as published by the Free Software Foundation and appearing in
+// the file LICENSE included in the packaging of this file. Please review the
+// following information to ensure the GNU General Public License version 3.0
+// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+//
+// If you do not wish to use this file under the terms of the GPL version 3.0
+// then you may purchase a commercial license. For more information contact
+// info at riverbankcomputing.com.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+
+%If (Qt_4_4_0 -)
+%ModuleCode
+#include <qwebframe.h>
+%End
+%End
+
+%If (Qt_4_4_0 -)
+
+class QWebHitTestResult
+{
+%TypeHeaderCode
+#include <qwebframe.h>
+%End
+
+public:
+ QWebHitTestResult();
+ QWebHitTestResult(const QWebHitTestResult &other);
+ ~QWebHitTestResult();
+ bool isNull() const;
+ QPoint pos() const;
+ QString title() const;
+ QString linkText() const;
+ QUrl linkUrl() const;
+ QUrl linkTitle() const;
+ QWebFrame *linkTargetFrame() const;
+ QString alternateText() const;
+ QUrl imageUrl() const;
+ QPixmap pixmap() const;
+ bool isContentEditable() const;
+ bool isContentSelected() const;
+ QWebFrame *frame() const;
+%If (Qt_4_5_0 -)
+ QRect boundingRect() const;
+%End
+%If (Qt_4_6_0 -)
+ QWebElement enclosingBlockElement() const;
+%End
+%If (Qt_4_6_0 -)
+ QWebElement linkElement() const;
+%End
+%If (Qt_4_6_0 -)
+ QWebElement element() const;
+%End
+};
+
+%End
+%If (Qt_4_4_0 -)
+
+class QWebFrame : QObject /NoDefaultCtors/
+{
+%TypeHeaderCode
+#include <qwebframe.h>
+%End
+
+ virtual ~QWebFrame();
+
+public:
+ QWebPage *page() const;
+ void load(const QUrl &url);
+ void load(const QNetworkRequest &request, QNetworkAccessManager::Operation operation = QNetworkAccessManager::GetOperation, const QByteArray &body = QByteArray());
+ void setHtml(const QString &html, const QUrl &baseUrl = QUrl());
+ void setContent(const QByteArray &data, const QString &mimeType /DocValue="Py_v3:''"/ = QString(), const QUrl &baseUrl = QUrl());
+%If (Qt_5_0_0 -)
+
+ enum ValueOwnership
+ {
+ QtOwnership,
+ ScriptOwnership,
+ AutoOwnership,
+ };
+
+%End
+%If (Qt_5_0_0 -)
+ void addToJavaScriptWindowObject(const QString &name, QObject *object, QWebFrame::ValueOwnership ownership = QWebFrame::QtOwnership);
+%End
+%If (- Qt_5_0_0)
+ void addToJavaScriptWindowObject(const QString &name, QObject *object);
+%End
+ QString toHtml() const;
+ QString toPlainText() const;
+%If (- Qt_5_0_0)
+ QString renderTreeDump() const;
+%End
+ QString title() const;
+ void setUrl(const QUrl &url);
+ QUrl url() const;
+ QIcon icon() const;
+ QString frameName() const;
+ QWebFrame *parentFrame() const;
+ QList<QWebFrame*> childFrames() const;
+ Qt::ScrollBarPolicy scrollBarPolicy(Qt::Orientation orientation) const;
+ void setScrollBarPolicy(Qt::Orientation orientation, Qt::ScrollBarPolicy policy);
+ void setScrollBarValue(Qt::Orientation orientation, int value);
+ int scrollBarValue(Qt::Orientation orientation) const;
+ int scrollBarMinimum(Qt::Orientation orientation) const;
+ int scrollBarMaximum(Qt::Orientation orientation) const;
+%If (- Qt_5_0_0)
+ void render(QPainter *painter, const QRegion &clip);
+%End
+%If (- Qt_5_0_0)
+ void render(QPainter *painter);
+%End
+ void setTextSizeMultiplier(qreal factor);
+ qreal textSizeMultiplier() const;
+ QPoint pos() const;
+ QRect geometry() const;
+ QSize contentsSize() const;
+ QWebHitTestResult hitTestContent(const QPoint &pos) const;
+ virtual bool event(QEvent *);
+
+public slots:
+ QVariant evaluateJavaScript(const QString &scriptSource);
+%If (PyQt_Printer)
+ void print(QPrinter *printer) const /PyName=print_/;
+%End
+%If (Py_v3)
+%If (PyQt_Printer)
+ void print(QPrinter *printer) const;
+%End
+%End
+
+signals:
+ void javaScriptWindowObjectCleared();
+ void titleChanged(const QString &title);
+ void urlChanged(const QUrl &url);
+ void initialLayoutCompleted();
+ void iconChanged();
+
+public:
+%If (Qt_4_5_0 -)
+ QMultiMap<QString, QString> metaData() const;
+%End
+%If (Qt_4_5_0 -)
+ void scroll(int, int);
+%End
+%If (Qt_4_5_0 -)
+ QPoint scrollPosition() const;
+%End
+%If (Qt_4_5_0 -)
+ void setScrollPosition(const QPoint &pos);
+%End
+%If (Qt_4_5_0 -)
+ qreal zoomFactor() const;
+%End
+%If (Qt_4_5_0 -)
+ void setZoomFactor(qreal factor);
+%End
+%If (Qt_4_5_0 -)
+ QWebSecurityOrigin securityOrigin() const;
+%End
+%If (Qt_4_6_0 -)
+ QUrl requestedUrl() const;
+%End
+%If (Qt_4_6_0 -)
+ QUrl baseUrl() const;
+%End
+%If (Qt_4_6_0 -)
+ QRect scrollBarGeometry(Qt::Orientation orientation) const;
+%End
+%If (Qt_4_6_0 -)
+
+ enum RenderLayer
+ {
+ ContentsLayer,
+ ScrollBarLayer,
+ PanIconLayer,
+ AllLayers,
+ };
+
+%End
+%If (Qt_5_0_0 -)
+ typedef QFlags<QWebFrame::RenderLayer> RenderLayers;
+%End
+%If (Qt_4_6_0 - Qt_5_0_0)
+ void render(QPainter *, QWebFrame::RenderLayer layer, const QRegion &clip = QRegion());
+%End
+%If (Qt_5_0_0 -)
+ void render(QPainter *, const QRegion &clip = QRegion());
+%End
+%If (Qt_5_0_0 -)
+ void render(QPainter *, QFlags<QWebFrame::RenderLayer> layer, const QRegion &clip = QRegion());
+%End
+%If (Qt_4_6_0 -)
+ bool hasFocus() const;
+%End
+%If (Qt_4_6_0 -)
+ void setFocus();
+%End
+%If (Qt_4_6_0 -)
+ QWebElement documentElement() const;
+%End
+%If (Qt_4_6_0 -)
+ QWebElementCollection findAllElements(const QString &selectorQuery) const;
+%End
+%If (Qt_4_6_0 -)
+ QWebElement findFirstElement(const QString &selectorQuery) const;
+%End
+
+signals:
+%If (Qt_4_6_0 -)
+ void contentsSizeChanged(const QSize &size);
+%End
+%If (Qt_4_6_0 -)
+ void loadStarted();
+%End
+%If (Qt_4_6_0 -)
+ void loadFinished(bool ok);
+%End
+%If (Qt_4_7_0 -)
+ void pageChanged();
+%End
+
+public:
+%If (Qt_4_7_0 -)
+ void scrollToAnchor(const QString &anchor);
+%End
+};
+
+%End
+%If (Qt_5_0_0 -)
+QFlags<QWebFrame::RenderLayer> operator|(QWebFrame::RenderLayer f1, QFlags<QWebFrame::RenderLayer> f2);
+%End
diff --git a/python/QtWebKit/qwebhistory.sip b/python/QtWebKit/qwebhistory.sip
new file mode 100644
index 0000000..59ddb3a
--- /dev/null
+++ b/python/QtWebKit/qwebhistory.sip
@@ -0,0 +1,104 @@
+// qwebhistory.sip generated by MetaSIP
+//
+// This file is part of the QtWebKit Python extension module.
+//
+// Copyright (c) 2015 Riverbank Computing Limited <info at riverbankcomputing.com>
+//
+// This file is part of PyQt4.
+//
+// This file may be used under the terms of the GNU General Public License
+// version 3.0 as published by the Free Software Foundation and appearing in
+// the file LICENSE included in the packaging of this file. Please review the
+// following information to ensure the GNU General Public License version 3.0
+// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+//
+// If you do not wish to use this file under the terms of the GPL version 3.0
+// then you may purchase a commercial license. For more information contact
+// info at riverbankcomputing.com.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+
+%If (Qt_4_4_0 -)
+%ModuleCode
+#include <qwebhistory.h>
+%End
+%End
+
+%If (Qt_4_4_0 -)
+
+class QWebHistoryItem
+{
+%TypeHeaderCode
+#include <qwebhistory.h>
+%End
+
+public:
+ QWebHistoryItem(const QWebHistoryItem &other);
+ ~QWebHistoryItem();
+ QUrl originalUrl() const;
+ QUrl url() const;
+ QString title() const;
+ QDateTime lastVisited() const;
+ QIcon icon() const;
+%If (Qt_4_5_0 -)
+ QVariant userData() const;
+%End
+%If (Qt_4_5_0 -)
+ void setUserData(const QVariant &userData);
+%End
+%If (Qt_4_5_0 -)
+ bool isValid() const;
+%End
+};
+
+%End
+%If (Qt_4_4_0 -)
+
+class QWebHistory
+{
+%TypeHeaderCode
+#include <qwebhistory.h>
+%End
+
+public:
+ void clear();
+ QList<QWebHistoryItem> items() const;
+ QList<QWebHistoryItem> backItems(int maxItems) const;
+ QList<QWebHistoryItem> forwardItems(int maxItems) const;
+ bool canGoBack() const;
+ bool canGoForward() const;
+ void back();
+ void forward();
+ void goToItem(const QWebHistoryItem &item);
+ QWebHistoryItem backItem() const;
+ QWebHistoryItem currentItem() const;
+ QWebHistoryItem forwardItem() const;
+ QWebHistoryItem itemAt(int i) const;
+ int count() const /__len__/;
+
+private:
+ QWebHistory();
+ QWebHistory(const QWebHistory &);
+ ~QWebHistory();
+
+public:
+%If (Qt_4_5_0 -)
+ int currentItemIndex() const;
+%End
+%If (Qt_4_5_0 -)
+ int maximumItemCount() const;
+%End
+%If (Qt_4_5_0 -)
+ void setMaximumItemCount(int count);
+%End
+};
+
+%End
+%If (Qt_4_6_0 -)
+QDataStream &operator<<(QDataStream &, const QWebHistory & /Constrained/);
+%End
+%If (Qt_4_6_0 -)
+QDataStream &operator>>(QDataStream &, QWebHistory & /Constrained/);
+%End
diff --git a/python/QtWebKit/qwebhistoryinterface.sip b/python/QtWebKit/qwebhistoryinterface.sip
new file mode 100644
index 0000000..7493a10
--- /dev/null
+++ b/python/QtWebKit/qwebhistoryinterface.sip
@@ -0,0 +1,40 @@
+// qwebhistoryinterface.sip generated by MetaSIP
+//
+// This file is part of the QtWebKit Python extension module.
+//
+// Copyright (c) 2015 Riverbank Computing Limited <info at riverbankcomputing.com>
+//
+// This file is part of PyQt4.
+//
+// This file may be used under the terms of the GNU General Public License
+// version 3.0 as published by the Free Software Foundation and appearing in
+// the file LICENSE included in the packaging of this file. Please review the
+// following information to ensure the GNU General Public License version 3.0
+// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+//
+// If you do not wish to use this file under the terms of the GPL version 3.0
+// then you may purchase a commercial license. For more information contact
+// info at riverbankcomputing.com.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+
+%If (Qt_4_4_0 -)
+
+class QWebHistoryInterface : QObject
+{
+%TypeHeaderCode
+#include <qwebhistoryinterface.h>
+%End
+
+public:
+ QWebHistoryInterface(QObject *parent /TransferThis/ = 0);
+ virtual ~QWebHistoryInterface();
+ static void setDefaultInterface(QWebHistoryInterface *defaultInterface /KeepReference/);
+ static QWebHistoryInterface *defaultInterface();
+ virtual bool historyContains(const QString &url) const = 0;
+ virtual void addHistoryEntry(const QString &url) = 0;
+};
+
+%End
diff --git a/python/QtWebKit/qwebinspector.sip b/python/QtWebKit/qwebinspector.sip
new file mode 100644
index 0000000..50405ed
--- /dev/null
+++ b/python/QtWebKit/qwebinspector.sip
@@ -0,0 +1,48 @@
+// qwebinspector.sip generated by MetaSIP
+//
+// This file is part of the QtWebKit Python extension module.
+//
+// Copyright (c) 2015 Riverbank Computing Limited <info at riverbankcomputing.com>
+//
+// This file is part of PyQt4.
+//
+// This file may be used under the terms of the GNU General Public License
+// version 3.0 as published by the Free Software Foundation and appearing in
+// the file LICENSE included in the packaging of this file. Please review the
+// following information to ensure the GNU General Public License version 3.0
+// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+//
+// If you do not wish to use this file under the terms of the GPL version 3.0
+// then you may purchase a commercial license. For more information contact
+// info at riverbankcomputing.com.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+
+%If (Qt_4_6_0 -)
+
+class QWebInspector : QWidget
+{
+%TypeHeaderCode
+#include <qwebinspector.h>
+%End
+
+public:
+ QWebInspector(QWidget *parent /TransferThis/ = 0);
+ virtual ~QWebInspector();
+ void setPage(QWebPage *page /KeepReference/);
+ QWebPage *page() const;
+ virtual QSize sizeHint() const;
+ virtual bool event(QEvent *);
+
+protected:
+ virtual void resizeEvent(QResizeEvent *event);
+ virtual void showEvent(QShowEvent *event);
+ virtual void hideEvent(QHideEvent *event);
+%If (Qt_4_7_0 -)
+ virtual void closeEvent(QCloseEvent *event);
+%End
+};
+
+%End
diff --git a/python/QtWebKit/qwebkitglobal.sip b/python/QtWebKit/qwebkitglobal.sip
new file mode 100644
index 0000000..f7dad16
--- /dev/null
+++ b/python/QtWebKit/qwebkitglobal.sip
@@ -0,0 +1,37 @@
+// qwebkitglobal.sip generated by MetaSIP
+//
+// This file is part of the QtWebKit Python extension module.
+//
+// Copyright (c) 2015 Riverbank Computing Limited <info at riverbankcomputing.com>
+//
+// This file is part of PyQt4.
+//
+// This file may be used under the terms of the GNU General Public License
+// version 3.0 as published by the Free Software Foundation and appearing in
+// the file LICENSE included in the packaging of this file. Please review the
+// following information to ensure the GNU General Public License version 3.0
+// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+//
+// If you do not wish to use this file under the terms of the GPL version 3.0
+// then you may purchase a commercial license. For more information contact
+// info at riverbankcomputing.com.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+
+%If (Qt_5_0_0 -)
+%ModuleCode
+#include <qwebkitglobal.h>
+%End
+%End
+
+%If (Qt_5_0_0 -)
+QString qWebKitVersion();
+%End
+%If (Qt_5_0_0 -)
+int qWebKitMajorVersion();
+%End
+%If (Qt_5_0_0 -)
+int qWebKitMinorVersion();
+%End
diff --git a/python/QtWebKit/qwebkitversion.sip b/python/QtWebKit/qwebkitversion.sip
new file mode 100644
index 0000000..63729ba
--- /dev/null
+++ b/python/QtWebKit/qwebkitversion.sip
@@ -0,0 +1,37 @@
+// qwebkitversion.sip generated by MetaSIP
+//
+// This file is part of the QtWebKit Python extension module.
+//
+// Copyright (c) 2015 Riverbank Computing Limited <info at riverbankcomputing.com>
+//
+// This file is part of PyQt4.
+//
+// This file may be used under the terms of the GNU General Public License
+// version 3.0 as published by the Free Software Foundation and appearing in
+// the file LICENSE included in the packaging of this file. Please review the
+// following information to ensure the GNU General Public License version 3.0
+// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+//
+// If you do not wish to use this file under the terms of the GPL version 3.0
+// then you may purchase a commercial license. For more information contact
+// info at riverbankcomputing.com.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+
+%If (Qt_4_6_0 - Qt_5_0_0)
+%ModuleCode
+#include <qwebkitversion.h>
+%End
+%End
+
+%If (Qt_4_6_0 - Qt_5_0_0)
+QString qWebKitVersion();
+%End
+%If (Qt_4_6_0 - Qt_5_0_0)
+int qWebKitMajorVersion();
+%End
+%If (Qt_4_6_0 - Qt_5_0_0)
+int qWebKitMinorVersion();
+%End
diff --git a/python/QtWebKit/qwebpage.sip b/python/QtWebKit/qwebpage.sip
new file mode 100644
index 0000000..88ddfd1
--- /dev/null
+++ b/python/QtWebKit/qwebpage.sip
@@ -0,0 +1,522 @@
+// qwebpage.sip generated by MetaSIP
+//
+// This file is part of the QtWebKit Python extension module.
+//
+// Copyright (c) 2015 Riverbank Computing Limited <info at riverbankcomputing.com>
+//
+// This file is part of PyQt4.
+//
+// This file may be used under the terms of the GNU General Public License
+// version 3.0 as published by the Free Software Foundation and appearing in
+// the file LICENSE included in the packaging of this file. Please review the
+// following information to ensure the GNU General Public License version 3.0
+// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+//
+// If you do not wish to use this file under the terms of the GPL version 3.0
+// then you may purchase a commercial license. For more information contact
+// info at riverbankcomputing.com.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+
+%If (Qt_4_4_0 -)
+%ModuleCode
+#include <qwebpage.h>
+%End
+%End
+
+%If (Qt_4_4_0 -)
+
+class QWebPage : QObject
+{
+%TypeHeaderCode
+#include <qwebpage.h>
+%End
+
+public:
+ enum NavigationType
+ {
+ NavigationTypeLinkClicked,
+ NavigationTypeFormSubmitted,
+ NavigationTypeBackOrForward,
+ NavigationTypeReload,
+ NavigationTypeFormResubmitted,
+ NavigationTypeOther,
+ };
+
+ enum WebAction
+ {
+ NoWebAction,
+ OpenLink,
+ OpenLinkInNewWindow,
+ OpenFrameInNewWindow,
+ DownloadLinkToDisk,
+ CopyLinkToClipboard,
+ OpenImageInNewWindow,
+ DownloadImageToDisk,
+ CopyImageToClipboard,
+ Back,
+ Forward,
+ Stop,
+ Reload,
+ Cut,
+ Copy,
+ Paste,
+ Undo,
+ Redo,
+ MoveToNextChar,
+ MoveToPreviousChar,
+ MoveToNextWord,
+ MoveToPreviousWord,
+ MoveToNextLine,
+ MoveToPreviousLine,
+ MoveToStartOfLine,
+ MoveToEndOfLine,
+ MoveToStartOfBlock,
+ MoveToEndOfBlock,
+ MoveToStartOfDocument,
+ MoveToEndOfDocument,
+ SelectNextChar,
+ SelectPreviousChar,
+ SelectNextWord,
+ SelectPreviousWord,
+ SelectNextLine,
+ SelectPreviousLine,
+ SelectStartOfLine,
+ SelectEndOfLine,
+ SelectStartOfBlock,
+ SelectEndOfBlock,
+ SelectStartOfDocument,
+ SelectEndOfDocument,
+ DeleteStartOfWord,
+ DeleteEndOfWord,
+ SetTextDirectionDefault,
+ SetTextDirectionLeftToRight,
+ SetTextDirectionRightToLeft,
+ ToggleBold,
+ ToggleItalic,
+ ToggleUnderline,
+ InspectElement,
+%If (Qt_4_5_0 -)
+ InsertParagraphSeparator,
+%End
+%If (Qt_4_5_0 -)
+ InsertLineSeparator,
+%End
+%If (Qt_4_5_0 -)
+ SelectAll,
+%End
+%If (Qt_4_6_0 -)
+ ReloadAndBypassCache,
+%End
+%If (Qt_4_6_0 -)
+ PasteAndMatchStyle,
+%End
+%If (Qt_4_6_0 -)
+ RemoveFormat,
+%End
+%If (Qt_4_6_0 -)
+ ToggleStrikethrough,
+%End
+%If (Qt_4_6_0 -)
+ ToggleSubscript,
+%End
+%If (Qt_4_6_0 -)
+ ToggleSuperscript,
+%End
+%If (Qt_4_6_0 -)
+ InsertUnorderedList,
+%End
+%If (Qt_4_6_0 -)
+ InsertOrderedList,
+%End
+%If (Qt_4_6_0 -)
+ Indent,
+%End
+%If (Qt_4_6_0 -)
+ Outdent,
+%End
+%If (Qt_4_6_0 -)
+ AlignCenter,
+%End
+%If (Qt_4_6_0 -)
+ AlignJustified,
+%End
+%If (Qt_4_6_0 -)
+ AlignLeft,
+%End
+%If (Qt_4_6_0 -)
+ AlignRight,
+%End
+%If (Qt_4_7_0 -)
+ StopScheduledPageRefresh,
+%End
+%If (Qt_4_8_0 -)
+ CopyImageUrlToClipboard,
+%End
+%If (Qt_5_0_0 -)
+ OpenLinkInThisWindow,
+%End
+ };
+
+ enum FindFlag
+ {
+ FindBackward,
+ FindCaseSensitively,
+ FindWrapsAroundDocument,
+%If (Qt_4_6_0 -)
+ HighlightAllOccurrences,
+%End
+ };
+
+ typedef QFlags<QWebPage::FindFlag> FindFlags;
+
+ enum LinkDelegationPolicy
+ {
+ DontDelegateLinks,
+ DelegateExternalLinks,
+ DelegateAllLinks,
+ };
+
+ enum WebWindowType
+ {
+ WebBrowserWindow,
+ WebModalDialog,
+ };
+
+ explicit QWebPage(QObject *parent /TransferThis/ = 0);
+ virtual ~QWebPage();
+ QWebFrame *mainFrame() const;
+ QWebFrame *currentFrame() const;
+ QWebHistory *history() const;
+ QWebSettings *settings() const;
+ void setView(QWidget *view /KeepReference/);
+ QWidget *view() const;
+ bool isModified() const;
+ QUndoStack *undoStack() const;
+ void setNetworkAccessManager(QNetworkAccessManager *manager /KeepReference/);
+ QNetworkAccessManager *networkAccessManager() const;
+ void setPluginFactory(QWebPluginFactory *factory /KeepReference/);
+ QWebPluginFactory *pluginFactory() const;
+ quint64 totalBytes() const;
+ quint64 bytesReceived() const;
+ QString selectedText() const;
+ QAction *action(QWebPage::WebAction action) const;
+ virtual void triggerAction(QWebPage::WebAction action, bool checked = false);
+ QSize viewportSize() const;
+ void setViewportSize(const QSize &size) const;
+ virtual bool event(QEvent *);
+ bool focusNextPrevChild(bool next);
+ QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
+ bool findText(const QString &subString, QFlags<QWebPage::FindFlag> options = 0);
+ void setForwardUnsupportedContent(bool forward);
+ bool forwardUnsupportedContent() const;
+ void setLinkDelegationPolicy(QWebPage::LinkDelegationPolicy policy);
+ QWebPage::LinkDelegationPolicy linkDelegationPolicy() const;
+ void setPalette(const QPalette &palette);
+ QPalette palette() const;
+ bool swallowContextMenuEvent(QContextMenuEvent *event);
+ void updatePositionDependentActions(const QPoint &pos);
+
+ enum Extension
+ {
+%If (Qt_4_5_0 -)
+ ChooseMultipleFilesExtension,
+%End
+%If (Qt_4_6_0 -)
+ ErrorPageExtension,
+%End
+ };
+
+ class ExtensionOption
+ {
+%TypeHeaderCode
+#include <qwebpage.h>
+%End
+ };
+
+ class ExtensionReturn
+ {
+%TypeHeaderCode
+#include <qwebpage.h>
+%End
+ };
+
+ virtual bool extension(QWebPage::Extension extension, const QWebPage::ExtensionOption *option = 0, QWebPage::ExtensionReturn *output = 0);
+%VirtualCatcherCode
+ const sipTypeDef *option_type = sipType_QWebPage_ExtensionOption;
+ const sipTypeDef *return_type = sipType_QWebPage_ExtensionReturn;
+
+ #if QT_VERSION >= 0x040500
+ if (a0 == QWebPage::ChooseMultipleFilesExtension)
+ {
+ option_type = sipType_QWebPage_ChooseMultipleFilesExtensionOption;
+ return_type = sipType_QWebPage_ChooseMultipleFilesExtensionReturn;
+ }
+ #if QT_VERSION >= 0x040600
+ else if (a0 == QWebPage::ErrorPageExtension)
+ {
+ option_type = sipType_QWebPage_ErrorPageExtensionOption;
+ return_type = sipType_QWebPage_ErrorPageExtensionReturn;
+ }
+ #endif
+ #endif
+
+ PyObject *res_obj = sipCallMethod(&sipIsErr, sipMethod, "FDD",
+ a0, sipType_QWebPage_Extension,
+ a1, option_type, NULL,
+ a2, return_type, NULL);
+
+ if (res_obj)
+ {
+ sipParseResult(&sipIsErr, sipMethod, res_obj, "b", &sipRes);
+ Py_DECREF(res_obj);
+ }
+ else
+ {
+ sipIsErr = 1;
+ }
+%End
+
+ virtual bool supportsExtension(QWebPage::Extension extension) const;
+
+signals:
+ void loadFinished(bool ok);
+ void loadProgress(int progress);
+ void loadStarted();
+ void linkHovered(const QString &link, const QString &title, const QString &textContent);
+ void statusBarMessage(const QString &text);
+ void selectionChanged();
+ void frameCreated(QWebFrame *frame);
+ void geometryChangeRequested(const QRect &geom);
+ void repaintRequested(const QRect &dirtyRect);
+ void scrollRequested(int dx, int dy, const QRect &scrollViewRect);
+ void windowCloseRequested();
+ void printRequested(QWebFrame *frame);
+ void linkClicked(const QUrl &url);
+ void toolBarVisibilityChangeRequested(bool visible);
+ void statusBarVisibilityChangeRequested(bool visible);
+ void menuBarVisibilityChangeRequested(bool visible);
+ void unsupportedContent(QNetworkReply *reply);
+ void downloadRequested(const QNetworkRequest &request);
+ void microFocusChanged();
+
+protected:
+ virtual QWebPage *createWindow(QWebPage::WebWindowType type);
+ virtual QObject *createPlugin(const QString &classid, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues);
+ virtual bool acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type);
+ virtual QString chooseFile(QWebFrame *originatingFrame, const QString &oldFile);
+ virtual void javaScriptAlert(QWebFrame *originatingFrame, const QString &msg);
+ virtual bool javaScriptConfirm(QWebFrame *originatingFrame, const QString &msg);
+ virtual bool javaScriptPrompt(QWebFrame *originatingFrame, const QString &msg, const QString &defaultValue, QString *result /Out/) /API=QString:2 - /;
+ virtual bool javaScriptPrompt(QWebFrame *originatingFrame, const QString &msg, const QString &defaultValue, QString *result /Constrained/) /API=QString: - 2/;
+ virtual void javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID);
+ virtual QString userAgentForUrl(const QUrl &url) const;
+
+public:
+%If (Qt_4_5_0 -)
+ void setContentEditable(bool editable);
+%End
+%If (Qt_4_5_0 -)
+ bool isContentEditable() const;
+%End
+%If (Qt_4_5_0 -)
+ QMenu *createStandardContextMenu() /Factory/;
+%End
+%If (Qt_4_5_0 -)
+
+ class ChooseMultipleFilesExtensionOption : QWebPage::ExtensionOption
+ {
+%TypeHeaderCode
+#include <qwebpage.h>
+%End
+
+ public:
+ QWebFrame *parentFrame;
+ QStringList suggestedFileNames;
+ };
+
+%End
+%If (Qt_4_5_0 -)
+
+ class ChooseMultipleFilesExtensionReturn : QWebPage::ExtensionReturn
+ {
+%TypeHeaderCode
+#include <qwebpage.h>
+%End
+
+ public:
+ QStringList fileNames;
+ };
+
+%End
+
+signals:
+%If (Qt_4_5_0 -)
+ void contentsChanged();
+%End
+%If (Qt_4_5_0 -)
+ void databaseQuotaExceeded(QWebFrame *frame, QString databaseName);
+%End
+%If (Qt_4_5_0 -)
+ void saveFrameStateRequested(QWebFrame *frame, QWebHistoryItem *item);
+%End
+%If (Qt_4_5_0 -)
+ void restoreFrameStateRequested(QWebFrame *frame);
+%End
+
+public:
+%If (Qt_4_6_0 -)
+ QWebFrame *frameAt(const QPoint &pos) const;
+%End
+%If (Qt_4_6_0 -)
+ QSize preferredContentsSize() const;
+%End
+%If (Qt_4_6_0 -)
+ void setPreferredContentsSize(const QSize &size) const;
+%End
+%If (Qt_4_6_0 -)
+
+ enum ErrorDomain
+ {
+ QtNetwork,
+ Http,
+ WebKit,
+ };
+
+%End
+%If (Qt_4_6_0 -)
+
+ class ErrorPageExtensionOption : QWebPage::ExtensionOption
+ {
+%TypeHeaderCode
+#include <qwebpage.h>
+%End
+
+ public:
+ QUrl url;
+ QWebFrame *frame;
+ QWebPage::ErrorDomain domain;
+ int error;
+ QString errorString;
+ };
+
+%End
+%If (Qt_4_6_0 -)
+
+ class ErrorPageExtensionReturn : QWebPage::ExtensionReturn
+ {
+%TypeHeaderCode
+#include <qwebpage.h>
+%End
+
+ public:
+ ErrorPageExtensionReturn();
+ QString contentType;
+ QString encoding;
+ QUrl baseUrl;
+ QByteArray content;
+ };
+
+%End
+%If (Qt_5_0_0 -)
+ virtual bool shouldInterruptJavaScript();
+%End
+
+public slots:
+%If (Qt_4_6_0 - Qt_5_0_0)
+ bool shouldInterruptJavaScript();
+%End
+
+public:
+%If (Qt_4_8_0 -)
+
+ enum PermissionPolicy
+ {
+ PermissionUnknown,
+ PermissionGrantedByUser,
+ PermissionDeniedByUser,
+ };
+
+%End
+%If (Qt_4_8_0 -)
+
+ enum Feature
+ {
+ Notifications,
+ Geolocation,
+ };
+
+%End
+%If (Qt_4_8_0 -)
+
+ class ViewportAttributes
+ {
+%TypeHeaderCode
+#include <qwebpage.h>
+%End
+
+ public:
+ ViewportAttributes();
+ ViewportAttributes(const QWebPage::ViewportAttributes &other);
+ ~ViewportAttributes();
+ qreal initialScaleFactor() const;
+ qreal minimumScaleFactor() const;
+ qreal maximumScaleFactor() const;
+ qreal devicePixelRatio() const;
+ bool isUserScalable() const;
+ bool isValid() const;
+%If (Qt_5_0_0 -)
+ QSizeF size() const;
+%End
+%If (- Qt_5_0_0)
+ QSize size() const;
+%End
+ };
+
+%End
+%If (Qt_4_8_0 -)
+ bool hasSelection() const;
+%End
+%If (Qt_4_8_0 -)
+ QString selectedHtml() const;
+%End
+%If (Qt_4_8_0 -)
+ QWebPage::ViewportAttributes viewportAttributesForSize(const QSize &availableSize) const;
+%End
+%If (Qt_4_8_0 -)
+ void setActualVisibleContentRect(const QRect &rect) const;
+%End
+%If (Qt_4_8_0 -)
+ void setFeaturePermission(QWebFrame *frame, QWebPage::Feature feature, QWebPage::PermissionPolicy policy);
+%End
+%If (Qt_4_8_0 -)
+ QStringList supportedContentTypes() const;
+%End
+%If (Qt_4_8_0 -)
+ bool supportsContentType(const QString &mimeType) const;
+%End
+
+signals:
+%If (Qt_5_0_0 -)
+ void applicationCacheQuotaExceeded(QWebSecurityOrigin *origin, quint64 defaultOriginQuota, quint64 totalSpaceNeeded);
+%End
+%If (Qt_4_8_0 - Qt_5_0_0)
+ void applicationCacheQuotaExceeded(QWebSecurityOrigin *origin, quint64 defaultOriginQuota);
+%End
+%If (Qt_4_8_0 -)
+ void viewportChangeRequested();
+%End
+%If (Qt_4_8_0 -)
+ void featurePermissionRequested(QWebFrame *frame, QWebPage::Feature feature);
+%End
+%If (Qt_4_8_0 -)
+ void featurePermissionRequestCanceled(QWebFrame *frame, QWebPage::Feature feature);
+%End
+};
+
+%End
+%If (Qt_4_4_0 -)
+QFlags<QWebPage::FindFlag> operator|(QWebPage::FindFlag f1, QFlags<QWebPage::FindFlag> f2);
+%End
diff --git a/python/QtWebKit/qwebpluginfactory.sip b/python/QtWebKit/qwebpluginfactory.sip
new file mode 100644
index 0000000..d6e9795
--- /dev/null
+++ b/python/QtWebKit/qwebpluginfactory.sip
@@ -0,0 +1,88 @@
+// qwebpluginfactory.sip generated by MetaSIP
+//
+// This file is part of the QtWebKit Python extension module.
+//
+// Copyright (c) 2015 Riverbank Computing Limited <info at riverbankcomputing.com>
+//
+// This file is part of PyQt4.
+//
+// This file may be used under the terms of the GNU General Public License
+// version 3.0 as published by the Free Software Foundation and appearing in
+// the file LICENSE included in the packaging of this file. Please review the
+// following information to ensure the GNU General Public License version 3.0
+// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+//
+// If you do not wish to use this file under the terms of the GPL version 3.0
+// then you may purchase a commercial license. For more information contact
+// info at riverbankcomputing.com.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+
+%If (Qt_4_4_0 -)
+
+class QWebPluginFactory : QObject
+{
+%TypeHeaderCode
+#include <qwebpluginfactory.h>
+%End
+
+public:
+ struct MimeType
+ {
+%TypeHeaderCode
+#include <qwebpluginfactory.h>
+%End
+
+ QString name;
+ QString description;
+ QStringList fileExtensions;
+%If (Qt_4_6_0 -)
+ bool operator==(const QWebPluginFactory::MimeType &other) const;
+%End
+%If (Qt_4_6_0 -)
+ bool operator!=(const QWebPluginFactory::MimeType &other) const;
+%End
+ };
+
+ struct Plugin
+ {
+%TypeHeaderCode
+#include <qwebpluginfactory.h>
+%End
+
+ QString name;
+ QString description;
+ QList<QWebPluginFactory::MimeType> mimeTypes;
+ };
+
+ explicit QWebPluginFactory(QObject *parent /TransferThis/ = 0);
+ virtual ~QWebPluginFactory();
+ virtual QList<QWebPluginFactory::Plugin> plugins() const = 0;
+ virtual void refreshPlugins();
+ virtual QObject *create(const QString &mimeType, const QUrl &url, const QStringList &argumentNames, const QStringList &argumentValues) const = 0 /Factory/;
+
+ enum Extension
+ {
+ };
+
+ class ExtensionOption
+ {
+%TypeHeaderCode
+#include <qwebpluginfactory.h>
+%End
+ };
+
+ class ExtensionReturn
+ {
+%TypeHeaderCode
+#include <qwebpluginfactory.h>
+%End
+ };
+
+ virtual bool extension(QWebPluginFactory::Extension extension, const QWebPluginFactory::ExtensionOption *option = 0, QWebPluginFactory::ExtensionReturn *output = 0);
+ virtual bool supportsExtension(QWebPluginFactory::Extension extension) const;
+};
+
+%End
diff --git a/python/QtWebKit/qwebsecurityorigin.sip b/python/QtWebKit/qwebsecurityorigin.sip
new file mode 100644
index 0000000..b5eca42
--- /dev/null
+++ b/python/QtWebKit/qwebsecurityorigin.sip
@@ -0,0 +1,56 @@
+// qwebsecurityorigin.sip generated by MetaSIP
+//
+// This file is part of the QtWebKit Python extension module.
+//
+// Copyright (c) 2015 Riverbank Computing Limited <info at riverbankcomputing.com>
+//
+// This file is part of PyQt4.
+//
+// This file may be used under the terms of the GNU General Public License
+// version 3.0 as published by the Free Software Foundation and appearing in
+// the file LICENSE included in the packaging of this file. Please review the
+// following information to ensure the GNU General Public License version 3.0
+// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+//
+// If you do not wish to use this file under the terms of the GPL version 3.0
+// then you may purchase a commercial license. For more information contact
+// info at riverbankcomputing.com.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+
+%If (Qt_4_5_0 -)
+
+class QWebSecurityOrigin
+{
+%TypeHeaderCode
+#include <qwebsecurityorigin.h>
+%End
+
+public:
+ QWebSecurityOrigin(const QWebSecurityOrigin &other);
+ ~QWebSecurityOrigin();
+ static QList<QWebSecurityOrigin> allOrigins();
+ QString scheme() const;
+ QString host() const;
+ int port() const;
+ qint64 databaseUsage() const;
+ qint64 databaseQuota() const;
+ void setDatabaseQuota(qint64 quota);
+ QList<QWebDatabase> databases() const;
+%If (Qt_4_6_0 -)
+ static void addLocalScheme(const QString &scheme);
+%End
+%If (Qt_4_6_0 -)
+ static void removeLocalScheme(const QString &scheme);
+%End
+%If (Qt_4_6_0 -)
+ static QStringList localSchemes();
+%End
+%If (Qt_4_8_0 -)
+ void setApplicationCacheQuota(qint64 quota);
+%End
+};
+
+%End
diff --git a/python/QtWebKit/qwebsettings.sip b/python/QtWebKit/qwebsettings.sip
new file mode 100644
index 0000000..1aa3e17
--- /dev/null
+++ b/python/QtWebKit/qwebsettings.sip
@@ -0,0 +1,237 @@
+// qwebsettings.sip generated by MetaSIP
+//
+// This file is part of the QtWebKit Python extension module.
+//
+// Copyright (c) 2015 Riverbank Computing Limited <info at riverbankcomputing.com>
+//
+// This file is part of PyQt4.
+//
+// This file may be used under the terms of the GNU General Public License
+// version 3.0 as published by the Free Software Foundation and appearing in
+// the file LICENSE included in the packaging of this file. Please review the
+// following information to ensure the GNU General Public License version 3.0
+// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+//
+// If you do not wish to use this file under the terms of the GPL version 3.0
+// then you may purchase a commercial license. For more information contact
+// info at riverbankcomputing.com.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+
+%If (Qt_4_4_0 -)
+
+class QWebSettings
+{
+%TypeHeaderCode
+#include <qwebsettings.h>
+%End
+
+public:
+ enum FontFamily
+ {
+ StandardFont,
+ FixedFont,
+ SerifFont,
+ SansSerifFont,
+ CursiveFont,
+ FantasyFont,
+ };
+
+ enum WebAttribute
+ {
+ AutoLoadImages,
+ JavascriptEnabled,
+ JavaEnabled,
+ PluginsEnabled,
+ PrivateBrowsingEnabled,
+ JavascriptCanOpenWindows,
+%If (Qt_4_8_0 -)
+ JavascriptCanCloseWindows,
+%End
+ JavascriptCanAccessClipboard,
+ DeveloperExtrasEnabled,
+ LinksIncludedInFocusChain,
+%If (Qt_4_5_0 -)
+ ZoomTextOnly,
+%End
+%If (Qt_4_5_0 -)
+ PrintElementBackgrounds,
+%End
+%If (Qt_4_5_0 -)
+ OfflineStorageDatabaseEnabled,
+%End
+%If (Qt_4_5_0 -)
+ OfflineWebApplicationCacheEnabled,
+%End
+%If (Qt_4_5_0 -)
+ LocalStorageDatabaseEnabled,
+%End
+%If (Qt_4_6_0 -)
+ LocalStorageEnabled,
+%End
+%If (Qt_4_6_0 -)
+ LocalContentCanAccessRemoteUrls,
+%End
+%If (Qt_4_6_0 -)
+ DnsPrefetchEnabled,
+%End
+%If (Qt_4_7_0 -)
+ XSSAuditingEnabled,
+%End
+%If (Qt_4_7_0 -)
+ AcceleratedCompositingEnabled,
+%End
+%If (Qt_4_7_0 -)
+ SpatialNavigationEnabled,
+%End
+%If (Qt_4_7_0 -)
+ LocalContentCanAccessFileUrls,
+%End
+%If (Qt_4_7_0 -)
+ TiledBackingStoreEnabled,
+%End
+%If (Qt_4_7_0 -)
+ FrameFlatteningEnabled,
+%End
+%If (Qt_4_7_0 -)
+ SiteSpecificQuirksEnabled,
+%End
+%If (Qt_4_8_0 -)
+ WebGLEnabled,
+%End
+%If (Qt_4_8_0 -)
+ HyperlinkAuditingEnabled,
+%End
+%If (Qt_5_0_0 -)
+ CSSRegionsEnabled,
+%End
+%If (Qt_5_0_0 -)
+ CSSGridLayoutEnabled,
+%End
+%If (Qt_5_0_0 -)
+ ScrollAnimatorEnabled,
+%End
+%If (Qt_5_0_0 -)
+ CaretBrowsingEnabled,
+%End
+%If (Qt_5_0_0 -)
+ NotificationsEnabled,
+%End
+ };
+
+ enum WebGraphic
+ {
+ MissingImageGraphic,
+ MissingPluginGraphic,
+ DefaultFrameIconGraphic,
+ TextAreaSizeGripCornerGraphic,
+%If (Qt_4_8_0 -)
+ InputSpeechButtonGraphic,
+%End
+%If (Qt_4_8_0 -)
+ SearchCancelButtonGraphic,
+%End
+%If (Qt_4_8_0 -)
+ SearchCancelButtonPressedGraphic,
+%End
+ };
+
+ enum FontSize
+ {
+ MinimumFontSize,
+ MinimumLogicalFontSize,
+ DefaultFontSize,
+ DefaultFixedFontSize,
+ };
+
+ static QWebSettings *globalSettings();
+ void setFontFamily(QWebSettings::FontFamily which, const QString &family);
+ QString fontFamily(QWebSettings::FontFamily which) const;
+ void resetFontFamily(QWebSettings::FontFamily which);
+ void setFontSize(QWebSettings::FontSize type, int size);
+ int fontSize(QWebSettings::FontSize type) const;
+ void resetFontSize(QWebSettings::FontSize type);
+ void setAttribute(QWebSettings::WebAttribute attr, bool on);
+ bool testAttribute(QWebSettings::WebAttribute attr) const;
+ void resetAttribute(QWebSettings::WebAttribute attr);
+ void setUserStyleSheetUrl(const QUrl &location);
+ QUrl userStyleSheetUrl() const;
+ static void setIconDatabasePath(const QString &location);
+ static QString iconDatabasePath();
+ static void clearIconDatabase();
+ static QIcon iconForUrl(const QUrl &url);
+ static void setWebGraphic(QWebSettings::WebGraphic type, const QPixmap &graphic);
+ static QPixmap webGraphic(QWebSettings::WebGraphic type);
+ static void setMaximumPagesInCache(int pages);
+ static int maximumPagesInCache();
+ static void setObjectCacheCapacities(int cacheMinDeadCapacity, int cacheMaxDead, int totalCapacity);
+
+private:
+ QWebSettings();
+ QWebSettings(const QWebSettings &);
+ ~QWebSettings();
+
+public:
+%If (Qt_4_5_0 -)
+ static void setOfflineStoragePath(const QString &path);
+%End
+%If (Qt_4_5_0 -)
+ static QString offlineStoragePath();
+%End
+%If (Qt_4_5_0 -)
+ static void setOfflineStorageDefaultQuota(qint64 maximumSize);
+%End
+%If (Qt_4_5_0 -)
+ static qint64 offlineStorageDefaultQuota();
+%End
+%If (Qt_4_6_0 -)
+ void setDefaultTextEncoding(const QString &encoding);
+%End
+%If (Qt_4_6_0 -)
+ QString defaultTextEncoding() const;
+%End
+%If (Qt_4_6_0 -)
+ static void setOfflineWebApplicationCachePath(const QString &path);
+%End
+%If (Qt_4_6_0 -)
+ static QString offlineWebApplicationCachePath();
+%End
+%If (Qt_4_6_0 -)
+ static void setOfflineWebApplicationCacheQuota(qint64 maximumSize);
+%End
+%If (Qt_4_6_0 -)
+ static qint64 offlineWebApplicationCacheQuota();
+%End
+%If (Qt_4_6_0 -)
+ void setLocalStoragePath(const QString &path);
+%End
+%If (Qt_4_6_0 -)
+ QString localStoragePath() const;
+%End
+%If (Qt_4_6_0 -)
+ static void clearMemoryCaches();
+%End
+%If (Qt_4_6_0 -)
+ static void enablePersistentStorage(const QString &path = QString());
+%End
+%If (Qt_5_0_0 -)
+
+ enum ThirdPartyCookiePolicy
+ {
+ AlwaysAllowThirdPartyCookies,
+ AlwaysBlockThirdPartyCookies,
+ AllowThirdPartyWithExistingCookies,
+ };
+
+%End
+%If (Qt_5_0_0 -)
+ void setThirdPartyCookiePolicy(QWebSettings::ThirdPartyCookiePolicy);
+%End
+%If (Qt_5_0_0 -)
+ QWebSettings::ThirdPartyCookiePolicy thirdPartyCookiePolicy() const;
+%End
+};
+
+%End
diff --git a/python/QtWebKit/qwebview.sip b/python/QtWebKit/qwebview.sip
new file mode 100644
index 0000000..80318d4
--- /dev/null
+++ b/python/QtWebKit/qwebview.sip
@@ -0,0 +1,167 @@
+// qwebview.sip generated by MetaSIP
+//
+// This file is part of the QtWebKit Python extension module.
+//
+// Copyright (c) 2015 Riverbank Computing Limited <info at riverbankcomputing.com>
+//
+// This file is part of PyQt4.
+//
+// This file may be used under the terms of the GNU General Public License
+// version 3.0 as published by the Free Software Foundation and appearing in
+// the file LICENSE included in the packaging of this file. Please review the
+// following information to ensure the GNU General Public License version 3.0
+// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+//
+// If you do not wish to use this file under the terms of the GPL version 3.0
+// then you may purchase a commercial license. For more information contact
+// info at riverbankcomputing.com.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+
+%If (Qt_4_4_0 -)
+
+class QWebView : QWidget
+{
+%TypeHeaderCode
+#include <qwebview.h>
+%End
+
+%ConvertToSubClassCode
+ static struct class_graph {
+ const char *name;
+ sipTypeDef **type;
+ int yes, no;
+ } graph[] = {
+ {sipName_QWebPluginFactory, &sipType_QWebPluginFactory, -1, 1},
+ {sipName_QWebFrame, &sipType_QWebFrame, -1, 2},
+ {sipName_QWebPage, &sipType_QWebPage, -1, 3},
+ {sipName_QWebHistoryInterface, &sipType_QWebHistoryInterface, -1, 4},
+ {sipName_QWebView, &sipType_QWebView, -1, 5},
+ #if QT_VERSION >= 0x040600
+ {sipName_QWebInspector, &sipType_QWebInspector, -1, 6},
+ {sipName_QGraphicsWebView, &sipType_QGraphicsWebView, -1, -1},
+ #else
+ {0, 0, -1, 6},
+ {0, 0, -1, -1},
+ #endif
+ };
+
+ int i = 0;
+
+ sipType = 0;
+
+ do
+ {
+ struct class_graph *cg = &graph[i];
+
+ if (cg->name != NULL && sipCpp->inherits(cg->name))
+ {
+ sipType = *cg->type;
+ i = cg->yes;
+ }
+ else
+ i = cg->no;
+ }
+ while (i >= 0);
+%End
+
+public:
+ explicit QWebView(QWidget *parent /TransferThis/ = 0);
+ virtual ~QWebView();
+ QWebPage *page() const;
+ void setPage(QWebPage *page /KeepReference/);
+ void load(const QUrl &url) /ReleaseGIL/;
+ void load(const QNetworkRequest &request, QNetworkAccessManager::Operation operation = QNetworkAccessManager::GetOperation, const QByteArray &body = QByteArray()) /ReleaseGIL/;
+ void setHtml(const QString &html, const QUrl &baseUrl = QUrl());
+ void setContent(const QByteArray &data, const QString &mimeType /DocValue="Py_v3:''"/ = QString(), const QUrl &baseUrl = QUrl());
+ QWebHistory *history() const;
+ QWebSettings *settings() const;
+ QString title() const;
+ void setUrl(const QUrl &url);
+ QUrl url() const;
+ QIcon icon() const;
+ QString selectedText() const;
+ QAction *pageAction(QWebPage::WebAction action) const;
+ void triggerPageAction(QWebPage::WebAction action, bool checked = false);
+ bool isModified() const;
+ virtual QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
+ virtual QSize sizeHint() const;
+ void setTextSizeMultiplier(qreal factor);
+ qreal textSizeMultiplier() const;
+ bool findText(const QString &subString, QFlags<QWebPage::FindFlag> options = 0);
+ virtual bool event(QEvent *);
+
+public slots:
+ void stop();
+ void back();
+ void forward();
+ void reload();
+%If (PyQt_Printer)
+ void print(QPrinter *printer) const /PyName=print_/;
+%End
+%If (Py_v3)
+%If (PyQt_Printer)
+ void print(QPrinter *printer) const;
+%End
+%End
+
+signals:
+ void loadStarted();
+ void loadProgress(int progress);
+ void loadFinished(bool);
+ void titleChanged(const QString &title);
+ void statusBarMessage(const QString &text);
+ void linkClicked(const QUrl &url);
+ void selectionChanged();
+ void iconChanged();
+ void urlChanged(const QUrl &url);
+
+protected:
+ virtual QWebView *createWindow(QWebPage::WebWindowType type);
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void paintEvent(QPaintEvent *ev);
+ virtual void changeEvent(QEvent *);
+ virtual void mouseMoveEvent(QMouseEvent *);
+ virtual void mousePressEvent(QMouseEvent *);
+ virtual void mouseDoubleClickEvent(QMouseEvent *);
+ virtual void mouseReleaseEvent(QMouseEvent *);
+ virtual void contextMenuEvent(QContextMenuEvent *);
+ virtual void wheelEvent(QWheelEvent *);
+ virtual void keyPressEvent(QKeyEvent *);
+ virtual void keyReleaseEvent(QKeyEvent *);
+ virtual void dragEnterEvent(QDragEnterEvent *);
+ virtual void dragLeaveEvent(QDragLeaveEvent *);
+ virtual void dragMoveEvent(QDragMoveEvent *);
+ virtual void dropEvent(QDropEvent *);
+ virtual void focusInEvent(QFocusEvent *);
+ virtual void focusOutEvent(QFocusEvent *);
+ virtual void inputMethodEvent(QInputMethodEvent *);
+ virtual bool focusNextPrevChild(bool next);
+
+public:
+%If (Qt_4_5_0 -)
+ qreal zoomFactor() const;
+%End
+%If (Qt_4_5_0 -)
+ void setZoomFactor(qreal factor);
+%End
+%If (Qt_4_6_0 -)
+ QFlags<QPainter::RenderHint> renderHints() const;
+%End
+%If (Qt_4_6_0 -)
+ void setRenderHints(QFlags<QPainter::RenderHint> hints);
+%End
+%If (Qt_4_6_0 -)
+ void setRenderHint(QPainter::RenderHint hint, bool enabled = true);
+%End
+%If (Qt_4_8_0 -)
+ bool hasSelection() const;
+%End
+%If (Qt_4_8_0 -)
+ QString selectedHtml() const;
+%End
+};
+
+%End
diff --git a/python/core/geometry/qgsabstractgeometryv2.sip b/python/core/geometry/qgsabstractgeometryv2.sip
index 3cd3ab5..2264423 100644
--- a/python/core/geometry/qgsabstractgeometryv2.sip
+++ b/python/core/geometry/qgsabstractgeometryv2.sip
@@ -306,6 +306,12 @@ class QgsAbstractGeometryV2
*/
virtual QgsAbstractGeometryV2* segmentize() const /Factory/;
+ /** Returns the geometry converted to the more generic curve type.
+ E.g. QgsLineString -> QgsCompoundCurve, QgsPolygonV2 -> QgsCurvePolygon,
+ QgsMultiLineString -> QgsMultiCurve, QgsMultiPolygonV2 -> QgsMultiSurface
+ @return the converted geometry. Caller takes ownership*/
+ virtual QgsAbstractGeometryV2* toCurveType() const /Factory/;
+
/** Returns approximate angle at a vertex. This is usually the average angle between adjacent
* segments, and can be pictured as the orientation of a line following the curvature of the
* geometry at the specified vertex.
diff --git a/python/core/geometry/qgslinestringv2.sip b/python/core/geometry/qgslinestringv2.sip
index fad5fca..319a811 100644
--- a/python/core/geometry/qgslinestringv2.sip
+++ b/python/core/geometry/qgslinestringv2.sip
@@ -102,6 +102,10 @@ class QgsLineStringV2: public QgsCurveV2
/** Closes the line string by appending the first point to the end of the line, if it is not already closed.*/
void close();
+ /** Returns the geometry converted to the more generic curve type QgsCompoundCurve
+ @return the converted geometry. Caller takes ownership*/
+ QgsAbstractGeometryV2* toCurveType() const /Factory/;
+
/** Returns a QPolygonF representing the line string.
*/
QPolygonF asQPolygonF() const;
diff --git a/python/core/geometry/qgsmultilinestringv2.sip b/python/core/geometry/qgsmultilinestringv2.sip
index c1833e7..a3853cc 100644
--- a/python/core/geometry/qgsmultilinestringv2.sip
+++ b/python/core/geometry/qgsmultilinestringv2.sip
@@ -20,6 +20,10 @@ class QgsMultiLineStringV2: public QgsMultiCurveV2
/** Adds a geometry and takes ownership. Returns true in case of success*/
virtual bool addGeometry( QgsAbstractGeometryV2* g );
+ /** Returns the geometry converted to the more generic curve type QgsMultiCurve
+ @return the converted geometry. Caller takes ownership*/
+ QgsAbstractGeometryV2* toCurveType() const /Factory/;
+
protected:
virtual bool wktOmitChildType() const;
diff --git a/python/core/geometry/qgsmultipolygonv2.sip b/python/core/geometry/qgsmultipolygonv2.sip
index 26392e2..66d080f 100644
--- a/python/core/geometry/qgsmultipolygonv2.sip
+++ b/python/core/geometry/qgsmultipolygonv2.sip
@@ -20,6 +20,10 @@ class QgsMultiPolygonV2: public QgsMultiSurfaceV2
/** Adds a geometry and takes ownership. Returns true in case of success*/
virtual bool addGeometry( QgsAbstractGeometryV2* g );
+ /** Returns the geometry converted to the more generic curve type QgsMultiSurface
+ @return the converted geometry. Caller takes ownership*/
+ QgsAbstractGeometryV2* toCurveType() const /Factory/;
+
protected:
virtual bool wktOmitChildType() const;
diff --git a/python/core/geometry/qgspolygonv2.sip b/python/core/geometry/qgspolygonv2.sip
index f52273e..7416804 100644
--- a/python/core/geometry/qgspolygonv2.sip
+++ b/python/core/geometry/qgspolygonv2.sip
@@ -26,6 +26,10 @@ class QgsPolygonV2: public QgsCurvePolygonV2
QgsPolygonV2* surfaceToPolygon() const;
+ /** Returns the geometry converted to the more generic curve type QgsCurvePolygon
+ @return the converted geometry. Caller takes ownership*/
+ QgsAbstractGeometryV2* toCurveType() const /Factory/;
+
void addInteriorRing( QgsCurveV2* ring /Transfer/ );
//overridden to handle LineString25D rings
virtual void setExteriorRing( QgsCurveV2* ring /Transfer/ );
diff --git a/python/core/qgsstringutils.sip b/python/core/qgsstringutils.sip
index a030161..7c133c7 100644
--- a/python/core/qgsstringutils.sip
+++ b/python/core/qgsstringutils.sip
@@ -10,6 +10,25 @@ class QgsStringUtils
#include <qgsstringutils.h>
%End
public:
+
+
+ //! Capitalization options
+ enum Capitalization
+ {
+ MixedCase, //!< Mixed case, ie no change
+ AllUppercase, //!< Convert all characters to uppercase
+ AllLowercase, //!< Convert all characters to lowercase
+ ForceFirstLetterToCapital, //!< Convert just the first letter of each word to uppercase, leave the rest untouched
+ };
+
+ /** Converts a string by applying capitalization rules to the string.
+ * @param string input string
+ * @param capitalization capitalization type to apply
+ * @return capitalized string
+ * @note added in QGIS 3.0
+ */
+ static QString capitalize( const QString& string, Capitalization capitalization );
+
/** Returns the Levenshtein edit distance between two strings. This equates to the minimum
* number of character edits (insertions, deletions or substitutions) required to change
* one string to another.
diff --git a/python/core/qgsvectordataprovider.sip b/python/core/qgsvectordataprovider.sip
index 3755723..d5ca5ac 100644
--- a/python/core/qgsvectordataprovider.sip
+++ b/python/core/qgsvectordataprovider.sip
@@ -361,4 +361,8 @@ class QgsVectorDataProvider : QgsDataProvider
void fillMinMaxCache();
void pushError( const QString& msg );
+
+ /** Converts the geometry to the provider type if possible / necessary
+ @return the converted geometry or nullptr if no conversion was necessary or possible*/
+ QgsGeometry* convertToProviderType( const QgsGeometry& geom ) const /Factory/;
};
diff --git a/python/gui/qgsmessagebar.sip b/python/gui/qgsmessagebar.sip
index ad3ba32..0d74447 100644
--- a/python/gui/qgsmessagebar.sip
+++ b/python/gui/qgsmessagebar.sip
@@ -48,9 +48,9 @@ class QgsMessageBar: QFrame
static QgsMessageBarItem* createMessage( QWidget *widget, QWidget *parent = 0 ) /Factory/;
//! convenience method for pushing a message to the bar
- void pushMessage( const QString &text, MessageLevel level = INFO, int duration = 0 );
+ void pushMessage( const QString &text, MessageLevel level = INFO, int duration = 5 );
//! convenience method for pushing a message with title to the bar
- void pushMessage( const QString &title, const QString &text, MessageLevel level = INFO, int duration = 0 );
+ void pushMessage( const QString &title, const QString &text, MessageLevel level = INFO, int duration = 5 );
QgsMessageBarItem *currentItem();
diff --git a/python/plugins/processing/algs/qgis/ConcaveHull.py b/python/plugins/processing/algs/qgis/ConcaveHull.py
index 36df1eb..73be49f 100644
--- a/python/plugins/processing/algs/qgis/ConcaveHull.py
+++ b/python/plugins/processing/algs/qgis/ConcaveHull.py
@@ -66,7 +66,7 @@ class ConcaveHull(GeoAlgorithm):
# Delaunay triangulation from input point layer
progress.setText(self.tr('Creating Delaunay triangles...'))
- delone_triangles = processing.runalg("qgis:delaunaytriangulation", layer, None, progress=None)['OUTPUT']
+ delone_triangles = processing.runalg("qgis:delaunaytriangulation", layer, None)['OUTPUT']
delaunay_layer = processing.getObject(delone_triangles)
# Get max edge length from Delaunay triangles
@@ -103,7 +103,7 @@ class ConcaveHull(GeoAlgorithm):
# Dissolve all Delaunay triangles
progress.setText(self.tr('Dissolving Delaunay triangles...'))
dissolved = processing.runalg("qgis:dissolve", delaunay_layer,
- True, None, None, progress=None)['OUTPUT']
+ True, None, None)['OUTPUT']
dissolved_layer = processing.getObject(dissolved)
# Save result
diff --git a/python/plugins/processing/algs/qgis/Intersection.py b/python/plugins/processing/algs/qgis/Intersection.py
index dc182e0..6310bca 100644
--- a/python/plugins/processing/algs/qgis/Intersection.py
+++ b/python/plugins/processing/algs/qgis/Intersection.py
@@ -87,8 +87,10 @@ class Intersection(GeoAlgorithm):
int_geom = QgsGeometry(geom.intersection(tmpGeom))
if int_geom.wkbType() == QGis.WKBUnknown or QgsWKBTypes.flatType(int_geom.geometry().wkbType()) == QgsWKBTypes.GeometryCollection:
int_com = geom.combine(tmpGeom)
- int_sym = geom.symDifference(tmpGeom)
- int_geom = QgsGeometry(int_com.difference(int_sym))
+ int_geom = QgsGeometry()
+ if int_com is not None:
+ int_sym = geom.symDifference(tmpGeom)
+ int_geom = QgsGeometry(int_com.difference(int_sym))
if int_geom.isGeosEmpty() or not int_geom.isGeosValid():
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
self.tr('GEOS geoprocessing error: One or '
diff --git a/python/plugins/processing/algs/qgis/MeanCoords.py b/python/plugins/processing/algs/qgis/MeanCoords.py
index 58fa89f..fe28b9f 100644
--- a/python/plugins/processing/algs/qgis/MeanCoords.py
+++ b/python/plugins/processing/algs/qgis/MeanCoords.py
@@ -49,11 +49,14 @@ class MeanCoords(GeoAlgorithm):
self.addParameter(ParameterVector(self.POINTS,
self.tr('Input layer'), [ParameterVector.VECTOR_TYPE_ANY]))
self.addParameter(ParameterTableField(self.WEIGHT,
- self.tr('Weight field'), MeanCoords.POINTS,
- ParameterTableField.DATA_TYPE_NUMBER, optional=True))
+ self.tr('Weight field'),
+ MeanCoords.POINTS,
+ ParameterTableField.DATA_TYPE_NUMBER,
+ optional=True))
self.addParameter(ParameterTableField(self.UID,
- self.tr('Unique ID field'), MeanCoords.POINTS,
- ParameterTableField.DATA_TYPE_NUMBER, optional=True))
+ self.tr('Unique ID field'),
+ MeanCoords.POINTS,
+ optional=True))
self.addOutput(OutputVector(MeanCoords.OUTPUT, self.tr('Mean coordinates')))
diff --git a/python/plugins/processing/algs/qgis/SinglePartsToMultiparts.py b/python/plugins/processing/algs/qgis/SinglePartsToMultiparts.py
index 355b138..e28b263 100644
--- a/python/plugins/processing/algs/qgis/SinglePartsToMultiparts.py
+++ b/python/plugins/processing/algs/qgis/SinglePartsToMultiparts.py
@@ -98,7 +98,9 @@ class SinglePartsToMultiparts(GeoAlgorithm):
del writer
else:
- raise GeoAlgorithmExecutionException(self.tr('Invalid unique ID field'))
+ raise GeoAlgorithmExecutionException(
+ self.tr('At least two features must have same attribute '
+ 'value! Please choose another field...'))
def singleToMultiGeom(self, wkbType):
try:
diff --git a/python/plugins/processing/core/parameters.py b/python/plugins/processing/core/parameters.py
index 75621a1..5126f66 100644
--- a/python/plugins/processing/core/parameters.py
+++ b/python/plugins/processing/core/parameters.py
@@ -885,7 +885,7 @@ class ParameterGeometryPredicate(Parameter):
self.enabledPredicates = self.predicates
def getValueAsCommandLineParameter(self):
- return '"' + unicode(self.value) + '"'
+ return unicode(self.value)
def setValue(self, value):
if value is None:
diff --git a/python/plugins/processing/gui/AlgorithmDialogBase.py b/python/plugins/processing/gui/AlgorithmDialogBase.py
index 69c282d..4dd1ad5 100644
--- a/python/plugins/processing/gui/AlgorithmDialogBase.py
+++ b/python/plugins/processing/gui/AlgorithmDialogBase.py
@@ -172,9 +172,6 @@ class AlgorithmDialogBase(BASE, WIDGET):
self.setInfo(text, False)
QCoreApplication.processEvents()
- def error(self, msg):
- self.setInfo(msg, error=True)
-
def setParamValues(self):
pass
diff --git a/python/plugins/processing/ui/DlgGetScriptsAndModels.ui b/python/plugins/processing/ui/DlgGetScriptsAndModels.ui
index 62a0372..fec3be0 100644
--- a/python/plugins/processing/ui/DlgGetScriptsAndModels.ui
+++ b/python/plugins/processing/ui/DlgGetScriptsAndModels.ui
@@ -81,11 +81,6 @@
<height>10000</height>
</size>
</property>
- <property name="url">
- <url>
- <string>about:blank</string>
- </url>
- </property>
</widget>
</item>
</layout>
diff --git a/src/analysis/vector/qgsgeometryanalyzer.cpp b/src/analysis/vector/qgsgeometryanalyzer.cpp
index 245efdf..10eee32 100644
--- a/src/analysis/vector/qgsgeometryanalyzer.cpp
+++ b/src/analysis/vector/qgsgeometryanalyzer.cpp
@@ -1178,29 +1178,32 @@ QgsGeometry* QgsGeometryAnalyzer::locateBetweenMeasures( double fromMeasure, dou
}
QgsMultiPolyline resultGeom;
+ QgsWKBTypes::Type wkbType = lineGeom->geometry()->wkbType();
- //need to go with WKB and z coordinate until QgsGeometry supports M values
- QgsConstWkbPtr wkbPtr( lineGeom->asWkb(), lineGeom->wkbSize() );
- wkbPtr.readHeader();
-
- QGis::WkbType wkbType = lineGeom->wkbType();
- if ( wkbType != QGis::WKBLineString25D && wkbType != QGis::WKBMultiLineString25D )
+ //only linestring / multilinestring types supported at the moment
+ if ( QgsWKBTypes::singleType( QgsWKBTypes::flatType( wkbType ) ) != QgsWKBTypes::LineString || QgsWKBTypes::coordDimensions( wkbType ) < 3 )
{
return nullptr;
}
- if ( wkbType == QGis::WKBLineString25D )
+ bool hasZM = QgsWKBTypes::hasZ( wkbType ) && QgsWKBTypes::hasM( wkbType );
+
+
+ QgsConstWkbPtr wkbPtr( lineGeom->asWkb(), lineGeom->wkbSize() );
+ wkbPtr.readHeader();
+
+ if ( QgsWKBTypes::flatType( wkbType ) == QgsWKBTypes::LineString )
{
- locateBetweenWkbString( wkbPtr, resultGeom, fromMeasure, toMeasure );
+ locateBetweenWkbString( wkbPtr, resultGeom, fromMeasure, toMeasure, hasZM );
}
- else if ( wkbType == QGis::WKBMultiLineString25D )
+ else if ( QgsWKBTypes::flatType( wkbType ) == QgsWKBTypes::MultiLineString )
{
int nLines;
wkbPtr >> nLines;
for ( int i = 0; i < nLines; ++i )
{
wkbPtr.readHeader();
- wkbPtr = locateBetweenWkbString( wkbPtr, resultGeom, fromMeasure, toMeasure );
+ wkbPtr = locateBetweenWkbString( wkbPtr, resultGeom, fromMeasure, toMeasure, hasZM );
}
}
@@ -1213,7 +1216,7 @@ QgsGeometry* QgsGeometryAnalyzer::locateBetweenMeasures( double fromMeasure, dou
QgsGeometry* QgsGeometryAnalyzer::locateAlongMeasure( double measure, const QgsGeometry *lineGeom )
{
- if ( !lineGeom )
+ if ( !lineGeom || !lineGeom->geometry() )
{
return nullptr;
}
@@ -1222,25 +1225,29 @@ QgsGeometry* QgsGeometryAnalyzer::locateAlongMeasure( double measure, const QgsG
//need to go with WKB and z coordinate until QgsGeometry supports M values
QgsConstWkbPtr wkbPtr( lineGeom->asWkb(), lineGeom->wkbSize() );
- QGis::WkbType wkbType = lineGeom->wkbType();
+ wkbPtr.readHeader();
+ QgsWKBTypes::Type wkbType = lineGeom->geometry()->wkbType();
- if ( wkbType != QGis::WKBLineString25D && wkbType != QGis::WKBMultiLineString25D )
+ //only linestring / multilinestring types supported at the moment
+ if ( QgsWKBTypes::singleType( QgsWKBTypes::flatType( wkbType ) ) != QgsWKBTypes::LineString || QgsWKBTypes::coordDimensions( wkbType ) < 3 )
{
return nullptr;
}
- if ( wkbType == QGis::WKBLineString25D )
+ bool hasZM = QgsWKBTypes::hasZ( wkbType ) && QgsWKBTypes::hasM( wkbType );
+
+ if ( QgsWKBTypes::flatType( wkbType ) == QgsWKBTypes::LineString )
{
- locateAlongWkbString( wkbPtr, resultGeom, measure );
+ locateAlongWkbString( wkbPtr, resultGeom, measure, hasZM );
}
- else if ( wkbType == QGis::WKBMultiLineString25D )
+ else if ( QgsWKBTypes::flatType( wkbType ) == QgsWKBTypes::MultiLineString )
{
int nLines;
wkbPtr >> nLines;
for ( int i = 0; i < nLines; ++i )
{
wkbPtr.readHeader();
- wkbPtr = locateAlongWkbString( wkbPtr, resultGeom, measure );
+ wkbPtr = locateAlongWkbString( wkbPtr, resultGeom, measure, hasZM );
}
}
@@ -1252,7 +1259,7 @@ QgsGeometry* QgsGeometryAnalyzer::locateAlongMeasure( double measure, const QgsG
return QgsGeometry::fromMultiPoint( resultGeom );
}
-QgsConstWkbPtr QgsGeometryAnalyzer::locateBetweenWkbString( QgsConstWkbPtr wkbPtr, QgsMultiPolyline& result, double fromMeasure, double toMeasure )
+QgsConstWkbPtr QgsGeometryAnalyzer::locateBetweenWkbString( QgsConstWkbPtr wkbPtr, QgsMultiPolyline& result, double fromMeasure, double toMeasure, bool zm )
{
int nPoints;
wkbPtr >> nPoints;
@@ -1262,7 +1269,12 @@ QgsConstWkbPtr QgsGeometryAnalyzer::locateBetweenWkbString( QgsConstWkbPtr wkbPt
for ( int i = 0; i < nPoints; ++i )
{
double x, y, z;
- wkbPtr >> x >> y >> z;
+ wkbPtr >> x >> y;
+ if ( zm )
+ {
+ wkbPtr += sizeof( double );
+ }
+ wkbPtr >> z;
if ( i > 0 )
{
@@ -1299,7 +1311,7 @@ QgsConstWkbPtr QgsGeometryAnalyzer::locateBetweenWkbString( QgsConstWkbPtr wkbPt
return wkbPtr;
}
-QgsConstWkbPtr QgsGeometryAnalyzer::locateAlongWkbString( QgsConstWkbPtr wkbPtr, QgsMultiPoint& result, double measure )
+QgsConstWkbPtr QgsGeometryAnalyzer::locateAlongWkbString( QgsConstWkbPtr wkbPtr, QgsMultiPoint& result, double measure, bool zm )
{
int nPoints;
wkbPtr >> nPoints;
@@ -1308,7 +1320,12 @@ QgsConstWkbPtr QgsGeometryAnalyzer::locateAlongWkbString( QgsConstWkbPtr wkbPtr,
double prevx = 0.0, prevy = 0.0, prevz = 0.0;
for ( int i = 0; i < nPoints; ++i )
{
- wkbPtr >> x >> y >> z;
+ wkbPtr >> x >> y;
+ if ( zm )
+ {
+ wkbPtr += sizeof( double );
+ }
+ wkbPtr >> z;
if ( i > 0 )
{
diff --git a/src/analysis/vector/qgsgeometryanalyzer.h b/src/analysis/vector/qgsgeometryanalyzer.h
index cbd50e8..f886a47 100644
--- a/src/analysis/vector/qgsgeometryanalyzer.h
+++ b/src/analysis/vector/qgsgeometryanalyzer.h
@@ -100,7 +100,7 @@ class ANALYSIS_EXPORT QgsGeometryAnalyzer
int uniqueIdField = -1, QProgressDialog* p = nullptr );
/** Creates an event layer (multipoint or multiline) by locating features from a (non-spatial) event table along the features of a line layer.
- * Note that currently (until QgsGeometry supports m-values) the z-coordinate of the line layer is used for linear referencing
+ * Note that this function only supports linestring / multilinestring 25D/Z/M/ZM types as input
* @param lineLayer layer with the line geometry
* @param eventLayer layer with features and location field
* @param lineField join index in line layer
@@ -120,10 +120,10 @@ class ANALYSIS_EXPORT QgsGeometryAnalyzer
const QString& outputFormat, int locationField1, int locationField2 = -1, int offsetField = -1, double offsetScale = 1.0,
bool forceSingleGeometry = false, QgsVectorDataProvider* memoryProvider = nullptr, QProgressDialog* p = nullptr );
- /** Returns linear reference geometry as a multiline (or 0 if no match). Currently, the z-coordinates are considered to be the measures (no support for m-values in QGIS)*/
+ /** Returns linear reference geometry as a multiline (or 0 if no match). This function only supports linestring/multilinestring 25D/Z/M/ZM types*/
QgsGeometry* locateBetweenMeasures( double fromMeasure, double toMeasure, const QgsGeometry *lineGeom );
/** Returns linear reference geometry. Unlike the PostGIS function, this method always returns multipoint or 0 if no match (not geometry collection).
- * Currently, the z-coordinates are considered to be the measures (no support for m-values in QGIS)
+ * Note that this function only supports linestring / multilinestring 25D/Z/M/ZM types as input
*/
QgsGeometry* locateAlongMeasure( double measure, const QgsGeometry* lineGeom );
@@ -152,8 +152,8 @@ class ANALYSIS_EXPORT QgsGeometryAnalyzer
@param offset the offset value in layer unit. Negative values mean offset towards left, positive values offset to the right side*/
bool createOffsetGeometry( QgsGeometry* geom, QgsGeometry* lineGeom, double offset );
QgsPoint createPointOffset( double x, double y, double dist, QgsGeometry* lineGeom ) const;
- QgsConstWkbPtr locateBetweenWkbString( QgsConstWkbPtr ptr, QgsMultiPolyline& result, double fromMeasure, double toMeasure );
- QgsConstWkbPtr locateAlongWkbString( QgsConstWkbPtr ptr, QgsMultiPoint& result, double measure );
+ QgsConstWkbPtr locateBetweenWkbString( QgsConstWkbPtr ptr, QgsMultiPolyline& result, double fromMeasure, double toMeasure, bool zm );
+ QgsConstWkbPtr locateAlongWkbString( QgsConstWkbPtr ptr, QgsMultiPoint& result, double measure, bool zm );
static bool clipSegmentByRange( double x1, double y1, double m1, double x2, double y2, double m2, double range1, double range2, QgsPoint& pt1, QgsPoint& pt2, bool& secondPointClipped );
static void locateAlongSegment( double x1, double y1, double m1, double x2, double y2, double m2, double measure, bool& pt1Ok, QgsPoint& pt1, bool& pt2Ok, QgsPoint& pt2 );
};
diff --git a/src/app/main.cpp b/src/app/main.cpp
index 1882ecd..1bdd275 100644
--- a/src/app/main.cpp
+++ b/src/app/main.cpp
@@ -105,46 +105,57 @@ typedef SInt32 SRefCon;
/** Print usage text
*/
-void usage( std::string const & appName )
+void usage( QString appName )
{
- std::cerr << "QGIS - " << VERSION << " '" << RELEASE_NAME << "' ("
- << QGSVERSION << ")\n"
- << "QGIS is a user friendly Open Source Geographic Information System.\n"
- << "Usage: " << appName << " [OPTION] [FILE]\n"
- << " OPTION:\n"
- << "\t[--snapshot filename]\temit snapshot of loaded datasets to given file\n"
- << "\t[--width width]\twidth of snapshot to emit\n"
- << "\t[--height height]\theight of snapshot to emit\n"
- << "\t[--lang language]\tuse language for interface text\n"
- << "\t[--project projectfile]\tload the given QGIS project\n"
- << "\t[--extent xmin,ymin,xmax,ymax]\tset initial map extent\n"
- << "\t[--nologo]\thide splash screen\n"
- << "\t[--noversioncheck]\tdon't check for new version of QGIS at startup"
- << "\t[--noplugins]\tdon't restore plugins on startup\n"
- << "\t[--nocustomization]\tdon't apply GUI customization\n"
- << "\t[--customizationfile]\tuse the given ini file as GUI customization\n"
- << "\t[--optionspath path]\tuse the given QSettings path\n"
- << "\t[--configpath path]\tuse the given path for all user configuration\n"
- << "\t[--authdbdirectory path] use the given directory for authentication database\n"
- << "\t[--code path]\trun the given python file on load\n"
- << "\t[--defaultui]\tstart by resetting user ui settings to default\n"
- << "\t[--dxf-export filename.dxf]\temit dxf output of loaded datasets to given file\n"
- << "\t[--dxf-extent xmin,ymin,xmax,ymax]\tset extent to export to dxf\n"
- << "\t[--dxf-symbology-mode none|symbollayer|feature]\tsymbology mode for dxf output\n"
- << "\t[--dxf-scale-denom scale]\tscale for dxf output\n"
- << "\t[--dxf-encoding encoding]\tencoding to use for dxf output\n"
- << "\t[--dxf-preset visiblity-preset]\tlayer visibility preset to use for dxf output\n"
- << "\t[--help]\t\tthis text\n"
- << "\t[--]\t\ttreat all following arguments as FILEs\n\n"
- << " FILE:\n"
- << " Files specified on the command line can include rasters,\n"
- << " vectors, and QGIS project files (.qgs): \n"
- << " 1. Rasters - supported formats include GeoTiff, DEM \n"
- << " and others supported by GDAL\n"
- << " 2. Vectors - supported formats include ESRI Shapefiles\n"
- << " and others supported by OGR and PostgreSQL layers using\n"
- << " the PostGIS extension\n" ; // OK
+ QStringList msg;
+
+ msg
+ << "QGIS - " << VERSION << " '" << RELEASE_NAME << "' ("
+ << QGSVERSION << ")\n"
+ << "QGIS is a user friendly Open Source Geographic Information System.\n"
+ << "Usage: " << appName << " [OPTION] [FILE]\n"
+ << " OPTION:\n"
+ << "\t[--snapshot filename]\temit snapshot of loaded datasets to given file\n"
+ << "\t[--width width]\twidth of snapshot to emit\n"
+ << "\t[--height height]\theight of snapshot to emit\n"
+ << "\t[--lang language]\tuse language for interface text\n"
+ << "\t[--project projectfile]\tload the given QGIS project\n"
+ << "\t[--extent xmin,ymin,xmax,ymax]\tset initial map extent\n"
+ << "\t[--nologo]\thide splash screen\n"
+ << "\t[--noversioncheck]\tdon't check for new version of QGIS at startup\n"
+ << "\t[--noplugins]\tdon't restore plugins on startup\n"
+ << "\t[--nocustomization]\tdon't apply GUI customization\n"
+ << "\t[--customizationfile]\tuse the given ini file as GUI customization\n"
+ << "\t[--optionspath path]\tuse the given QSettings path\n"
+ << "\t[--configpath path]\tuse the given path for all user configuration\n"
+ << "\t[--authdbdirectory path] use the given directory for authentication database\n"
+ << "\t[--code path]\trun the given python file on load\n"
+ << "\t[--defaultui]\tstart by resetting user ui settings to default\n"
+ << "\t[--dxf-export filename.dxf]\temit dxf output of loaded datasets to given file\n"
+ << "\t[--dxf-extent xmin,ymin,xmax,ymax]\tset extent to export to dxf\n"
+ << "\t[--dxf-symbology-mode none|symbollayer|feature]\tsymbology mode for dxf output\n"
+ << "\t[--dxf-scale-denom scale]\tscale for dxf output\n"
+ << "\t[--dxf-encoding encoding]\tencoding to use for dxf output\n"
+ << "\t[--dxf-preset visiblity-preset]\tlayer visibility preset to use for dxf output\n"
+ << "\t[--help]\t\tthis text\n"
+ << "\t[--]\t\ttreat all following arguments as FILEs\n\n"
+ << " FILE:\n"
+ << " Files specified on the command line can include rasters,\n"
+ << " vectors, and QGIS project files (.qgs): \n"
+ << " 1. Rasters - supported formats include GeoTiff, DEM \n"
+ << " and others supported by GDAL\n"
+ << " 2. Vectors - supported formats include ESRI Shapefiles\n"
+ << " and others supported by OGR and PostgreSQL layers using\n"
+ << " the PostGIS extension\n" ; // OK
+#ifdef Q_OS_WIN
+ MessageBox( nullptr,
+ msg.join( QString() ).toLocal8Bit().constData(),
+ "QGIS command line options",
+ MB_OK );
+#else
+ std::cerr << msg.join( QString() ).toLocal8Bit().constData();
+#endif
} // usage()
@@ -400,6 +411,11 @@ void myMessageOutput( QtMsgType type, const char *msg )
}
}
+#if(ANDROID)
+// On Android, there there is a libqgis.so instead of a qgis executable.
+// The main method symbol of this library needs to be exported so it can be called by java
+APP_EXPORT
+#endif
int main( int argc, char *argv[] )
{
#ifdef Q_OS_MACX
@@ -549,7 +565,7 @@ int main( int argc, char *argv[] )
if ( arg == "--help" || arg == "-?" )
{
- usage( args[0].toStdString() );
+ usage( args[0] );
return 2;
}
else if ( arg == "--nologo" || arg == "-n" )
diff --git a/src/app/qgsidentifyresultsdialog.cpp b/src/app/qgsidentifyresultsdialog.cpp
index d2416ae..fe0557a 100644
--- a/src/app/qgsidentifyresultsdialog.cpp
+++ b/src/app/qgsidentifyresultsdialog.cpp
@@ -69,6 +69,7 @@ QgsIdentifyResultsWebView::QgsIdentifyResultsWebView( QWidget *parent ) : QgsWeb
page()->setLinkDelegationPolicy( QWebPage::DontDelegateLinks );
settings()->setAttribute( QWebSettings::LocalContentCanAccessRemoteUrls, true );
settings()->setAttribute( QWebSettings::JavascriptCanOpenWindows, true );
+ settings()->setAttribute( QWebSettings::PluginsEnabled, true );
#ifdef QGISDEBUG
settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled, true );
#endif
@@ -109,6 +110,7 @@ QgsWebView *QgsIdentifyResultsWebView::createWindow( QWebPage::WebWindowType typ
wv->page()->setNetworkAccessManager( QgsNetworkAccessManager::instance() );
wv->settings()->setAttribute( QWebSettings::LocalContentCanAccessRemoteUrls, true );
wv->settings()->setAttribute( QWebSettings::JavascriptCanOpenWindows, true );
+ wv->settings()->setAttribute( QWebSettings::PluginsEnabled, true );
#ifdef QGISDEBUG
wv->settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled, true );
#endif
diff --git a/src/app/qgssnappingdialog.cpp b/src/app/qgssnappingdialog.cpp
index b288c2b..41d0b86 100644
--- a/src/app/qgssnappingdialog.cpp
+++ b/src/app/qgssnappingdialog.cpp
@@ -310,7 +310,7 @@ void QgsSnappingDialog::addLayer( QgsMapLayer *theMapLayer )
bool myDockFlag = myQsettings.value( "/qgis/dockSnapping", false ).toBool();
double defaultSnappingTolerance = myQsettings.value( "/qgis/digitizing/default_snapping_tolerance", 0 ).toDouble();
int defaultSnappingUnit = myQsettings.value( "/qgis/digitizing/default_snapping_tolerance_unit", QgsTolerance::ProjectUnits ).toInt();
- QString defaultSnappingString = myQsettings.value( "/qgis/digitizing/default_snap_mode", "to vertex" ).toString();
+ QString defaultSnappingString = myQsettings.value( "/qgis/digitizing/default_snap_mode", "off" ).toString();
int defaultSnappingStringIdx = 0;
if ( defaultSnappingString == "to vertex" )
diff --git a/src/core/auth/qgsauthmanager.cpp b/src/core/auth/qgsauthmanager.cpp
index cb7ec4b..7ee1cb3 100644
--- a/src/core/auth/qgsauthmanager.cpp
+++ b/src/core/auth/qgsauthmanager.cpp
@@ -1365,8 +1365,8 @@ bool QgsAuthManager::updateNetworkRequest( QNetworkRequest &request, const QStri
{
if ( !( authmethod->supportedExpansions() & QgsAuthMethod::NetworkRequest ) )
{
- QgsDebugMsg( QString( "Data source URI updating not supported by authcfg: %1" ).arg( authcfg ) );
- return false;
+ QgsDebugMsg( QString( "Network request updating not supported by authcfg: %1" ).arg( authcfg ) );
+ return true;
}
if ( !authmethod->updateNetworkRequest( request, authcfg, dataprovider.toLower() ) )
@@ -1392,7 +1392,7 @@ bool QgsAuthManager::updateNetworkReply( QNetworkReply *reply, const QString& au
if ( !( authmethod->supportedExpansions() & QgsAuthMethod::NetworkReply ) )
{
QgsDebugMsg( QString( "Network reply updating not supported by authcfg: %1" ).arg( authcfg ) );
- return false;
+ return true;
}
if ( !authmethod->updateNetworkReply( reply, authcfg, dataprovider.toLower() ) )
@@ -1418,7 +1418,7 @@ bool QgsAuthManager::updateDataSourceUriItems( QStringList &connectionItems, con
if ( !( authmethod->supportedExpansions() & QgsAuthMethod::DataSourceURI ) )
{
QgsDebugMsg( QString( "Data source URI updating not supported by authcfg: %1" ).arg( authcfg ) );
- return false;
+ return true;
}
if ( !authmethod->updateDataSourceUriItems( connectionItems, authcfg, dataprovider.toLower() ) )
diff --git a/src/core/geometry/qgsabstractgeometryv2.h b/src/core/geometry/qgsabstractgeometryv2.h
index e6f72d6..f5493f9 100644
--- a/src/core/geometry/qgsabstractgeometryv2.h
+++ b/src/core/geometry/qgsabstractgeometryv2.h
@@ -292,6 +292,12 @@ class CORE_EXPORT QgsAbstractGeometryV2
*/
virtual QgsAbstractGeometryV2* segmentize() const { return clone(); }
+ /** Returns the geometry converted to the more generic curve type.
+ * E.g. QgsLineStringV2 -> QgsCompoundCurveV2, QgsPolygonV2 -> QgsCurvePolygonV2,
+ * QgsMultiLineStringV2 -> QgsMultiCurveV2, QgsMultiPolygonV2 -> QgsMultiSurfaceV2
+ */
+ virtual QgsAbstractGeometryV2* toCurveType() const { return 0; }
+
/** Returns approximate angle at a vertex. This is usually the average angle between adjacent
* segments, and can be pictured as the orientation of a line following the curvature of the
* geometry at the specified vertex.
diff --git a/src/core/geometry/qgsgeometry.cpp b/src/core/geometry/qgsgeometry.cpp
index cb4dcc6..8cf207b 100644
--- a/src/core/geometry/qgsgeometry.cpp
+++ b/src/core/geometry/qgsgeometry.cpp
@@ -132,6 +132,11 @@ QgsAbstractGeometryV2* QgsGeometry::geometry() const
void QgsGeometry::setGeometry( QgsAbstractGeometryV2* geometry )
{
+ if ( d->geometry == geometry )
+ {
+ return;
+ }
+
detach( false );
if ( d->geometry )
{
diff --git a/src/core/geometry/qgslinestringv2.cpp b/src/core/geometry/qgslinestringv2.cpp
index a6d2cd1..13534a8 100644
--- a/src/core/geometry/qgslinestringv2.cpp
+++ b/src/core/geometry/qgslinestringv2.cpp
@@ -17,6 +17,7 @@
#include "qgslinestringv2.h"
#include "qgsapplication.h"
+#include "qgscompoundcurvev2.h"
#include "qgscoordinatetransform.h"
#include "qgsgeometryutils.h"
#include "qgsmaptopixel.h"
@@ -583,6 +584,13 @@ QPolygonF QgsLineStringV2::asQPolygonF() const
return points;
}
+QgsAbstractGeometryV2* QgsLineStringV2::toCurveType() const
+{
+ QgsCompoundCurveV2* compoundCurve = new QgsCompoundCurveV2();
+ compoundCurve->addCurve( clone() );
+ return compoundCurve;
+}
+
/***************************************************************************
* This class is considered CRITICAL and any change MUST be accompanied with
* full unit tests.
diff --git a/src/core/geometry/qgslinestringv2.h b/src/core/geometry/qgslinestringv2.h
index 3ebfff2..16677d5 100644
--- a/src/core/geometry/qgslinestringv2.h
+++ b/src/core/geometry/qgslinestringv2.h
@@ -132,6 +132,9 @@ class CORE_EXPORT QgsLineStringV2: public QgsCurveV2
*/
QPolygonF asQPolygonF() const;
+ /** Returns the geometry converted to QgsCompoundCurveV2*/
+ QgsAbstractGeometryV2* toCurveType() const override;
+
//reimplemented methods
virtual QString geometryType() const override { return "LineString"; }
diff --git a/src/core/geometry/qgsmultilinestringv2.cpp b/src/core/geometry/qgsmultilinestringv2.cpp
index fc1a9e6..a83bdc6 100644
--- a/src/core/geometry/qgsmultilinestringv2.cpp
+++ b/src/core/geometry/qgsmultilinestringv2.cpp
@@ -20,6 +20,7 @@ email : marco.hugentobler at sourcepole dot com
#include "qgscompoundcurvev2.h"
#include "qgsgeometryutils.h"
#include "qgslinestringv2.h"
+#include "qgsmulticurvev2.h"
QgsMultiLineStringV2* QgsMultiLineStringV2::clone() const
{
@@ -101,3 +102,13 @@ bool QgsMultiLineStringV2::addGeometry( QgsAbstractGeometryV2* g )
setZMTypeFromSubGeometry( g, QgsWKBTypes::MultiLineString );
return QgsGeometryCollectionV2::addGeometry( g );
}
+
+QgsAbstractGeometryV2* QgsMultiLineStringV2::toCurveType() const
+{
+ QgsMultiCurveV2* multiCurve = new QgsMultiCurveV2();
+ for ( int i = 0; i < mGeometries.size(); ++i )
+ {
+ multiCurve->addGeometry( mGeometries.at( i )->clone() );
+ }
+ return multiCurve;
+}
diff --git a/src/core/geometry/qgsmultilinestringv2.h b/src/core/geometry/qgsmultilinestringv2.h
index f3de420..6e28ad4 100644
--- a/src/core/geometry/qgsmultilinestringv2.h
+++ b/src/core/geometry/qgsmultilinestringv2.h
@@ -42,6 +42,9 @@ class CORE_EXPORT QgsMultiLineStringV2: public QgsMultiCurveV2
/** Adds a geometry and takes ownership. Returns true in case of success*/
virtual bool addGeometry( QgsAbstractGeometryV2* g ) override;
+ /** Returns the geometry converted to QgsMultiCurveV2*/
+ QgsAbstractGeometryV2* toCurveType() const override;
+
protected:
virtual bool wktOmitChildType() const override { return true; }
diff --git a/src/core/geometry/qgsmultipolygonv2.cpp b/src/core/geometry/qgsmultipolygonv2.cpp
index 80e9ca0..8277989 100644
--- a/src/core/geometry/qgsmultipolygonv2.cpp
+++ b/src/core/geometry/qgsmultipolygonv2.cpp
@@ -117,3 +117,13 @@ bool QgsMultiPolygonV2::addGeometry( QgsAbstractGeometryV2* g )
setZMTypeFromSubGeometry( g, QgsWKBTypes::MultiPolygon );
return QgsGeometryCollectionV2::addGeometry( g );
}
+
+QgsAbstractGeometryV2* QgsMultiPolygonV2::toCurveType() const
+{
+ QgsMultiSurfaceV2* multiSurface = new QgsMultiSurfaceV2();
+ for ( int i = 0; i < mGeometries.size(); ++i )
+ {
+ multiSurface->addGeometry( mGeometries.at( i )->clone() );
+ }
+ return multiSurface;
+}
diff --git a/src/core/geometry/qgsmultipolygonv2.h b/src/core/geometry/qgsmultipolygonv2.h
index d59a71e..176dfd1 100644
--- a/src/core/geometry/qgsmultipolygonv2.h
+++ b/src/core/geometry/qgsmultipolygonv2.h
@@ -43,6 +43,9 @@ class CORE_EXPORT QgsMultiPolygonV2: public QgsMultiSurfaceV2
/** Adds a geometry and takes ownership. Returns true in case of success*/
virtual bool addGeometry( QgsAbstractGeometryV2* g ) override;
+ /** Returns the geometry converted to QgsMultiSurfaceV2*/
+ QgsAbstractGeometryV2* toCurveType() const override;
+
protected:
virtual bool wktOmitChildType() const override { return true; }
diff --git a/src/core/geometry/qgspolygonv2.cpp b/src/core/geometry/qgspolygonv2.cpp
index 3521df0..9fecf25 100644
--- a/src/core/geometry/qgspolygonv2.cpp
+++ b/src/core/geometry/qgspolygonv2.cpp
@@ -240,3 +240,15 @@ QgsPolygonV2* QgsPolygonV2::surfaceToPolygon() const
{
return clone();
}
+
+QgsAbstractGeometryV2* QgsPolygonV2::toCurveType() const
+{
+ QgsCurvePolygonV2* curvePolygon = new QgsCurvePolygonV2();
+ curvePolygon->setExteriorRing( mExteriorRing->clone() );
+ int nInteriorRings = mInteriorRings.size();
+ for ( int i = 0; i < nInteriorRings; ++i )
+ {
+ curvePolygon->addInteriorRing( mInteriorRings.at( i )->clone() );
+ }
+ return curvePolygon;
+}
diff --git a/src/core/geometry/qgspolygonv2.h b/src/core/geometry/qgspolygonv2.h
index c645a8d..1f0c125 100644
--- a/src/core/geometry/qgspolygonv2.h
+++ b/src/core/geometry/qgspolygonv2.h
@@ -50,6 +50,9 @@ class CORE_EXPORT QgsPolygonV2: public QgsCurvePolygonV2
QgsPolygonV2* surfaceToPolygon() const override;
+ /** Returns the geometry converted to QgsCurvePolygonV2*/
+ QgsAbstractGeometryV2* toCurveType() const override;
+
void addInteriorRing( QgsCurveV2* ring ) override;
//overridden to handle LineString25D rings
virtual void setExteriorRing( QgsCurveV2* ring ) override;
diff --git a/src/core/qgsexpression.cpp b/src/core/qgsexpression.cpp
index 26853f1..6635efc 100644
--- a/src/core/qgsexpression.cpp
+++ b/src/core/qgsexpression.cpp
@@ -49,6 +49,8 @@
#include "qgscurvepolygonv2.h"
#include "qgsexpressionprivate.h"
#include "qgsexpressionsorter.h"
+#include "qgsmessagelog.h"
+#include "qgscsexception.h"
#if QT_VERSION < 0x050000
#include <qtextdocument.h>
@@ -2634,8 +2636,16 @@ static QVariant fcnTransformGeometry( const QVariantList& values, const QgsExpre
return QVariant::fromValue( fGeom );
QgsCoordinateTransform t( s, d );
- if ( fGeom.transform( t ) == 0 )
- return QVariant::fromValue( fGeom );
+ try
+ {
+ if ( fGeom.transform( t ) == 0 )
+ return QVariant::fromValue( fGeom );
+ }
+ catch ( QgsCsException &cse )
+ {
+ QgsMessageLog::logMessage( QString( "Transform error caught in transform() function: %1" ).arg( cse.what() ) );
+ return QVariant();
+ }
return QVariant();
}
diff --git a/src/core/qgslegendrenderer.cpp b/src/core/qgslegendrenderer.cpp
index 74cbd35..8d49139 100644
--- a/src/core/qgslegendrenderer.cpp
+++ b/src/core/qgslegendrenderer.cpp
@@ -266,17 +266,12 @@ void QgsLegendRenderer::setColumns( QList<Atom>& atomList )
// Divide atoms to columns
double totalHeight = 0;
- // bool first = true;
qreal maxAtomHeight = 0;
Q_FOREACH ( const Atom& atom, atomList )
{
- //if ( !first )
- //{
totalHeight += spaceAboveAtom( atom );
- //}
totalHeight += atom.size.height();
maxAtomHeight = qMax( atom.size.height(), maxAtomHeight );
- // first = false;
}
// We know height of each atom and we have to split them into columns
@@ -284,31 +279,36 @@ void QgsLegendRenderer::setColumns( QList<Atom>& atomList )
// We are using simple heuristic, brute fore appeared to be to slow,
// the number of combinations is N = n!/(k!*(n-k)!) where n = atomsCount-1
// and k = columnsCount-1
-
- double avgColumnHeight = totalHeight / mSettings.columnCount();
+ double maxColumnHeight = 0;
int currentColumn = 0;
int currentColumnAtomCount = 0; // number of atoms in current column
double currentColumnHeight = 0;
- double maxColumnHeight = 0;
double closedColumnsHeight = 0;
- // first = true; // first in column
+
for ( int i = 0; i < atomList.size(); i++ )
{
- Atom atom = atomList[i];
+ // Recalc average height for remaining columns including current
+ double avgColumnHeight = ( totalHeight - closedColumnsHeight ) / ( mSettings.columnCount() - currentColumn );
+
+ Atom atom = atomList.at( i );
double currentHeight = currentColumnHeight;
- //if ( !first )
- //{
- currentHeight += spaceAboveAtom( atom );
- //}
+ if ( currentColumnAtomCount > 0 )
+ currentHeight += spaceAboveAtom( atom );
currentHeight += atom.size.height();
- // Recalc average height for remaining columns including current
- avgColumnHeight = ( totalHeight - closedColumnsHeight ) / ( mSettings.columnCount() - currentColumn );
- if (( currentHeight - avgColumnHeight ) > atom.size.height() / 2 // center of current atom is over average height
- && currentColumnAtomCount > 0 // do not leave empty column
- && currentHeight > maxAtomHeight // no sense to make smaller columns than max atom height
- && currentHeight > maxColumnHeight // no sense to make smaller columns than max column already created
- && currentColumn < mSettings.columnCount() - 1 ) // must not exceed max number of columns
+ bool canCreateNewColumn = ( currentColumnAtomCount > 0 ) // do not leave empty column
+ && ( currentColumn < mSettings.columnCount() - 1 ); // must not exceed max number of columns
+
+ bool shouldCreateNewColumn = ( currentHeight - avgColumnHeight ) > atom.size.height() / 2 // center of current atom is over average height
+ && currentColumnAtomCount > 0 // do not leave empty column
+ && currentHeight > maxAtomHeight // no sense to make smaller columns than max atom height
+ && currentHeight > maxColumnHeight; // no sense to make smaller columns than max column already created
+
+ // also should create a new column if the number of items left < number of columns left
+ // in this case we should spread the remaining items out over the remaining columns
+ shouldCreateNewColumn |= ( atomList.size() - i < mSettings.columnCount() - currentColumn );
+
+ if ( canCreateNewColumn && shouldCreateNewColumn )
{
// New column
currentColumn++;
@@ -323,11 +323,9 @@ void QgsLegendRenderer::setColumns( QList<Atom>& atomList )
atomList[i].column = currentColumn;
currentColumnAtomCount++;
maxColumnHeight = qMax( currentColumnHeight, maxColumnHeight );
-
- // first = false;
}
- // Alling labels of symbols for each layr/column to the same labelXOffset
+ // Align labels of symbols for each layr/column to the same labelXOffset
QMap<QString, qreal> maxSymbolWidth;
for ( int i = 0; i < atomList.size(); i++ )
{
diff --git a/src/core/qgspallabeling.cpp b/src/core/qgspallabeling.cpp
index 92df90c..2439b47 100644
--- a/src/core/qgspallabeling.cpp
+++ b/src/core/qgspallabeling.cpp
@@ -18,6 +18,7 @@
#include "qgspallabeling.h"
#include "qgstextlabelfeature.h"
#include "qgsunittypes.h"
+#include "qgsstringutils.h"
#include <list>
@@ -2283,6 +2284,7 @@ void QgsPalLayerSettings::registerFeature( QgsFeature& f, QgsRenderContext &cont
// calculate rest of font attributes and store any data defined values
// this is done here for later use in making label backgrounds part of collision management (when implemented)
+ labelFont.setCapitalization( QFont::MixedCase ); // reset this - we don't use QFont's handling as it breaks with curved labels
parseTextStyle( labelFont, fontunits, context );
parseTextFormatting( context );
parseTextBuffer( context );
@@ -2316,6 +2318,41 @@ void QgsPalLayerSettings::registerFeature( QgsFeature& f, QgsRenderContext &cont
labelText = v.isNull() ? "" : v.toString();
}
+ // apply capitalization
+ QgsStringUtils::Capitalization capitalization = QgsStringUtils::MixedCase;
+ // maintain API - capitalization may have been set in textFont
+ if ( textFont.capitalization() != QFont::MixedCase )
+ {
+ capitalization = static_cast< QgsStringUtils::Capitalization >( textFont.capitalization() );
+ }
+ // data defined font capitalization?
+ if ( dataDefinedEvaluate( QgsPalLayerSettings::FontCase, exprVal, &context.expressionContext() ) )
+ {
+ QString fcase = exprVal.toString().trimmed();
+ QgsDebugMsgLevel( QString( "exprVal FontCase:%1" ).arg( fcase ), 4 );
+
+ if ( !fcase.isEmpty() )
+ {
+ if ( fcase.compare( "NoChange", Qt::CaseInsensitive ) == 0 )
+ {
+ capitalization = QgsStringUtils::MixedCase;
+ }
+ else if ( fcase.compare( "Upper", Qt::CaseInsensitive ) == 0 )
+ {
+ capitalization = QgsStringUtils::AllUppercase;
+ }
+ else if ( fcase.compare( "Lower", Qt::CaseInsensitive ) == 0 )
+ {
+ capitalization = QgsStringUtils::AllLowercase;
+ }
+ else if ( fcase.compare( "Capitalize", Qt::CaseInsensitive ) == 0 )
+ {
+ capitalization = QgsStringUtils::ForceFirstLetterToCapital;
+ }
+ }
+ }
+ labelText = QgsStringUtils::capitalize( labelText, capitalization );
+
// data defined format numbers?
bool formatnum = formatNumbers;
if ( dataDefinedEvaluate( QgsPalLayerSettings::NumFormat, exprVal, &context.expressionContext(), formatNumbers ) )
@@ -3315,7 +3352,6 @@ void QgsPalLayerSettings::parseTextStyle( QFont& labelFont,
// copy over existing font settings
//newFont = newFont.resolve( labelFont ); // should work, but let's be sure what's being copied
newFont.setPixelSize( labelFont.pixelSize() );
- newFont.setCapitalization( labelFont.capitalization() );
newFont.setUnderline( labelFont.underline() );
newFont.setStrikeOut( labelFont.strikeOut() );
newFont.setWordSpacing( labelFont.wordSpacing() );
@@ -3352,39 +3388,6 @@ void QgsPalLayerSettings::parseTextStyle( QFont& labelFont,
}
labelFont.setLetterSpacing( QFont::AbsoluteSpacing, scaleToPixelContext( letterspace, context, fontunits, false, fontSizeMapUnitScale ) );
- // data defined font capitalization?
- QFont::Capitalization fontcaps = labelFont.capitalization();
- if ( dataDefinedEvaluate( QgsPalLayerSettings::FontCase, exprVal, &context.expressionContext() ) )
- {
- QString fcase = exprVal.toString().trimmed();
- QgsDebugMsgLevel( QString( "exprVal FontCase:%1" ).arg( fcase ), 4 );
-
- if ( !fcase.isEmpty() )
- {
- if ( fcase.compare( "NoChange", Qt::CaseInsensitive ) == 0 )
- {
- fontcaps = QFont::MixedCase;
- }
- else if ( fcase.compare( "Upper", Qt::CaseInsensitive ) == 0 )
- {
- fontcaps = QFont::AllUppercase;
- }
- else if ( fcase.compare( "Lower", Qt::CaseInsensitive ) == 0 )
- {
- fontcaps = QFont::AllLowercase;
- }
- else if ( fcase.compare( "Capitalize", Qt::CaseInsensitive ) == 0 )
- {
- fontcaps = QFont::Capitalize;
- }
-
- if ( fontcaps != labelFont.capitalization() )
- {
- labelFont.setCapitalization( fontcaps );
- }
- }
- }
-
// data defined strikeout font style?
if ( dataDefinedEvaluate( QgsPalLayerSettings::Strikeout, exprVal, &context.expressionContext(), labelFont.strikeOut() ) )
{
diff --git a/src/core/qgspointlocator.cpp b/src/core/qgspointlocator.cpp
index f6c242f..66b2647 100644
--- a/src/core/qgspointlocator.cpp
+++ b/src/core/qgspointlocator.cpp
@@ -609,6 +609,7 @@ QgsPointLocator::QgsPointLocator( QgsVectorLayer* layer, const QgsCoordinateRefe
connect( mLayer, SIGNAL( featureAdded( QgsFeatureId ) ), this, SLOT( onFeatureAdded( QgsFeatureId ) ) );
connect( mLayer, SIGNAL( featureDeleted( QgsFeatureId ) ), this, SLOT( onFeatureDeleted( QgsFeatureId ) ) );
connect( mLayer, SIGNAL( geometryChanged( QgsFeatureId, QgsGeometry& ) ), this, SLOT( onGeometryChanged( QgsFeatureId, QgsGeometry& ) ) );
+ connect( mLayer, SIGNAL( dataChanged() ), this, SLOT( destroyIndex() ) );
}
diff --git a/src/core/qgspointlocator.h b/src/core/qgspointlocator.h
index 09aad1b..f2f7292 100644
--- a/src/core/qgspointlocator.h
+++ b/src/core/qgspointlocator.h
@@ -186,8 +186,8 @@ class CORE_EXPORT QgsPointLocator : public QObject
protected:
bool rebuildIndex( int maxFeaturesToIndex = -1 );
+ protected slots:
void destroyIndex();
-
private slots:
void onFeatureAdded( QgsFeatureId fid );
void onFeatureDeleted( QgsFeatureId fid );
diff --git a/src/core/qgsstringutils.cpp b/src/core/qgsstringutils.cpp
index 1d84445..0ed5e7c 100644
--- a/src/core/qgsstringutils.cpp
+++ b/src/core/qgsstringutils.cpp
@@ -15,6 +15,56 @@
#include "qgsstringutils.h"
#include <QVector>
+#include <QRegExp>
+#include <QStringList>
+#include <QTextBoundaryFinder>
+
+QString QgsStringUtils::capitalize( const QString& string, QgsStringUtils::Capitalization capitalization )
+{
+ if ( string.isEmpty() )
+ return QString();
+
+ switch ( capitalization )
+ {
+ case MixedCase:
+ return string;
+
+ case AllUppercase:
+ return string.toUpper();
+
+ case AllLowercase:
+ return string.toLower();
+
+ case ForceFirstLetterToCapital:
+ {
+ QString temp = string;
+
+ QTextBoundaryFinder wordSplitter( QTextBoundaryFinder::Word, string.constData(), string.length(), 0, 0 );
+ QTextBoundaryFinder letterSplitter( QTextBoundaryFinder::Grapheme, string.constData(), string.length(), 0, 0 );
+
+ wordSplitter.setPosition( 0 );
+ bool first = true;
+#if QT_VERSION >= 0x050000
+ while (( first && wordSplitter.boundaryReasons() & QTextBoundaryFinder::StartOfItem )
+ || wordSplitter.toNextBoundary() >= 0 )
+#else
+ while (( first && wordSplitter.boundaryReasons() & QTextBoundaryFinder::StartWord )
+ || wordSplitter.toNextBoundary() >= 0 )
+#endif
+ {
+ first = false;
+ letterSplitter.setPosition( wordSplitter.position() );
+ letterSplitter.toNextBoundary();
+ QString substr = string.mid( wordSplitter.position(), letterSplitter.position() - wordSplitter.position() );
+ temp.replace( wordSplitter.position(), substr.length(), substr.toUpper() );
+ }
+ return temp;
+ }
+
+ }
+ // no warnings
+ return string;
+}
int QgsStringUtils::levenshteinDistance( const QString& string1, const QString& string2, bool caseSensitive )
{
diff --git a/src/core/qgsstringutils.h b/src/core/qgsstringutils.h
index 4335870..5120aba 100644
--- a/src/core/qgsstringutils.h
+++ b/src/core/qgsstringutils.h
@@ -14,6 +14,7 @@
***************************************************************************/
#include <QString>
+#include <QFont> // for enum values
#ifndef QGSSTRINGUTILS_H
#define QGSSTRINGUTILS_H
@@ -28,6 +29,23 @@ class CORE_EXPORT QgsStringUtils
{
public:
+ //! Capitalization options
+ enum Capitalization
+ {
+ MixedCase = QFont::MixedCase, //!< Mixed case, ie no change
+ AllUppercase = QFont::AllUppercase, //!< Convert all characters to uppercase
+ AllLowercase = QFont::AllLowercase, //!< Convert all characters to lowercase
+ ForceFirstLetterToCapital = QFont::Capitalize, //!< Convert just the first letter of each word to uppercase, leave the rest untouched
+ };
+
+ /** Converts a string by applying capitalization rules to the string.
+ * @param string input string
+ * @param capitalization capitalization type to apply
+ * @return capitalized string
+ * @note added in QGIS 3.0
+ */
+ static QString capitalize( const QString& string, Capitalization capitalization );
+
/** Returns the Levenshtein edit distance between two strings. This equates to the minimum
* number of character edits (insertions, deletions or substitutions) required to change
* one string to another.
diff --git a/src/core/qgsvectordataprovider.cpp b/src/core/qgsvectordataprovider.cpp
index 7a4cebd..b5f740d 100644
--- a/src/core/qgsvectordataprovider.cpp
+++ b/src/core/qgsvectordataprovider.cpp
@@ -21,10 +21,15 @@
#include <limits>
#include "qgsvectordataprovider.h"
+#include "qgscircularstringv2.h"
+#include "qgscompoundcurvev2.h"
#include "qgsfeature.h"
#include "qgsfeatureiterator.h"
#include "qgsfeaturerequest.h"
#include "qgsfield.h"
+#include "qgsgeometry.h"
+#include "qgsgeometrycollectionv2.h"
+#include "qgsgeometryfactory.h"
#include "qgslogger.h"
#include "qgsmessagelog.h"
@@ -367,7 +372,7 @@ void QgsVectorDataProvider::uniqueValues( int index, QList<QVariant> &values, in
QgsFeature f;
QgsAttributeList keys;
keys.append( index );
- QgsFeatureIterator fi = getFeatures( QgsFeatureRequest().setSubsetOfAttributes( keys ) );
+ QgsFeatureIterator fi = getFeatures( QgsFeatureRequest().setSubsetOfAttributes( keys ).setFlags( QgsFeatureRequest::NoGeometry ) );
QSet<QString> set;
values.clear();
@@ -422,7 +427,8 @@ void QgsVectorDataProvider::fillMinMaxCache()
QgsFeature f;
QgsAttributeList keys = mCacheMinValues.keys();
- QgsFeatureIterator fi = getFeatures( QgsFeatureRequest().setSubsetOfAttributes( keys ) );
+ QgsFeatureIterator fi = getFeatures( QgsFeatureRequest().setSubsetOfAttributes( keys )
+ .setFlags( QgsFeatureRequest::NoGeometry ) );
while ( fi.nextFeature( f ) )
{
@@ -581,4 +587,103 @@ QSet<QString> QgsVectorDataProvider::layerDependencies() const
return QSet<QString>();
}
+QgsGeometry* QgsVectorDataProvider::convertToProviderType( const QgsGeometry& geom ) const
+{
+ if ( geom.isEmpty() )
+ {
+ return nullptr;
+ }
+
+ QgsAbstractGeometryV2* geometry = geom.geometry();
+ if ( !geometry )
+ {
+ return nullptr;
+ }
+
+ QgsWKBTypes::Type providerGeomType = QgsWKBTypes::Type( geometryType() );
+
+ //geom is already in the provider geometry type
+ if ( geometry->wkbType() == providerGeomType )
+ {
+ return nullptr;
+ }
+
+ QgsAbstractGeometryV2* outputGeom = nullptr;
+
+ //convert compoundcurve to circularstring (possible if compoundcurve consists of one circular string)
+ if ( QgsWKBTypes::flatType( providerGeomType ) == QgsWKBTypes::CircularString && QgsWKBTypes::flatType( geometry->wkbType() ) == QgsWKBTypes::CompoundCurve )
+ {
+ QgsCompoundCurveV2* compoundCurve = static_cast<QgsCompoundCurveV2*>( geometry );
+ if ( compoundCurve )
+ {
+ if ( compoundCurve->nCurves() == 1 )
+ {
+ const QgsCircularStringV2* circularString = dynamic_cast<const QgsCircularStringV2*>( compoundCurve->curveAt( 0 ) );
+ if ( circularString )
+ {
+ outputGeom = circularString->clone();
+ }
+ }
+ }
+ }
+
+ //convert to multitype if necessary
+ if ( QgsWKBTypes::isMultiType( providerGeomType ) && !QgsWKBTypes::isMultiType( geometry->wkbType() ) )
+ {
+ outputGeom = QgsGeometryFactory::geomFromWkbType( providerGeomType );
+ QgsGeometryCollectionV2* geomCollection = dynamic_cast<QgsGeometryCollectionV2*>( outputGeom );
+ if ( geomCollection )
+ {
+ geomCollection->addGeometry( geometry->clone() );
+ }
+ }
+
+ //convert to curved type if necessary
+ if ( !QgsWKBTypes::isCurvedType( geometry->wkbType() ) && QgsWKBTypes::isCurvedType( providerGeomType ) )
+ {
+ QgsAbstractGeometryV2* curveGeom = outputGeom ? outputGeom->toCurveType() : geometry->toCurveType();
+ if ( curveGeom )
+ {
+ delete outputGeom;
+ outputGeom = curveGeom;
+ }
+ }
+
+ //convert to linear type from curved type
+ if ( QgsWKBTypes::isCurvedType( geometry->wkbType() ) && !QgsWKBTypes::isCurvedType( providerGeomType ) )
+ {
+ QgsAbstractGeometryV2* segmentizedGeom = nullptr;
+ segmentizedGeom = outputGeom ? outputGeom->segmentize() : geometry->segmentize();
+ if ( segmentizedGeom )
+ {
+ delete outputGeom;
+ outputGeom = segmentizedGeom;
+ }
+ }
+
+ //set z/m types
+ if ( QgsWKBTypes::hasZ( providerGeomType ) )
+ {
+ if ( !outputGeom )
+ {
+ outputGeom = geometry->clone();
+ }
+ outputGeom->addZValue();
+ }
+ if ( QgsWKBTypes::hasM( providerGeomType ) )
+ {
+ if ( !outputGeom )
+ {
+ outputGeom = geometry->clone();
+ }
+ outputGeom->addMValue();
+ }
+
+ if ( outputGeom )
+ {
+ return new QgsGeometry( outputGeom );
+ }
+ return nullptr;
+}
+
QStringList QgsVectorDataProvider::smEncodings;
diff --git a/src/core/qgsvectordataprovider.h b/src/core/qgsvectordataprovider.h
index a601287..0aea4ba 100644
--- a/src/core/qgsvectordataprovider.h
+++ b/src/core/qgsvectordataprovider.h
@@ -429,6 +429,10 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider
/** Old-style mapping of index to name for QgsPalLabeling fix */
QgsAttrPalIndexNameHash mAttrPalIndexName;
+ /** Converts the geometry to the provider type if possible / necessary
+ @return the converted geometry or nullptr if no conversion was necessary or possible*/
+ QgsGeometry* convertToProviderType( const QgsGeometry& geom ) const;
+
private:
/** Old notation **/
QMap<QString, QVariant::Type> mOldTypeList;
diff --git a/src/core/qgsvectorlayer.cpp b/src/core/qgsvectorlayer.cpp
index ec50d7c..5535cb9 100644
--- a/src/core/qgsvectorlayer.cpp
+++ b/src/core/qgsvectorlayer.cpp
@@ -1923,8 +1923,11 @@ bool QgsVectorLayer::writeSymbology( QDomNode& node, QDomDocument& doc, QString&
if ( hasGeometryType() )
{
- QDomElement rendererElement = mRendererV2->save( doc );
- node.appendChild( rendererElement );
+ if ( mRendererV2 )
+ {
+ QDomElement rendererElement = mRendererV2->save( doc );
+ node.appendChild( rendererElement );
+ }
if ( mLabeling )
{
diff --git a/src/core/qgsvectorlayerfeatureiterator.cpp b/src/core/qgsvectorlayerfeatureiterator.cpp
index 7448ba9..1cce059 100644
--- a/src/core/qgsvectorlayerfeatureiterator.cpp
+++ b/src/core/qgsvectorlayerfeatureiterator.cpp
@@ -95,11 +95,7 @@ QgsVectorLayerFeatureIterator::QgsVectorLayerFeatureIterator( QgsVectorLayerFeat
, mFetchedFid( false )
, mEditGeometrySimplifier( nullptr )
{
- prepareExpressions();
-
- // prepare joins: may add more attributes to fetch (in order to allow join)
- if ( mSource->mJoinBuffer->containsJoins() )
- prepareJoins();
+ prepareFields();
mHasVirtualAttributes = !mFetchJoinInfo.isEmpty() || !mExpressionFieldInfo.isEmpty();
@@ -472,147 +468,214 @@ void QgsVectorLayerFeatureIterator::rewindEditBuffer()
mFetchChangedGeomIt = mSource->mChangedGeometries.constBegin();
}
+void QgsVectorLayerFeatureIterator::prepareJoin( int fieldIdx )
+{
+ if ( !mSource->mFields.exists( fieldIdx ) )
+ return;
+ if ( mSource->mFields.fieldOrigin( fieldIdx ) != QgsFields::OriginJoin )
+ return;
-void QgsVectorLayerFeatureIterator::prepareJoins()
-{
- QgsAttributeList fetchAttributes = ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) ? mRequest.subsetOfAttributes() : mSource->mFields.allAttributesList();
- QgsAttributeList sourceJoinFields; // attributes that also need to be fetched from this layer in order to have joins working
+ int sourceLayerIndex;
+ const QgsVectorJoinInfo* joinInfo = mSource->mJoinBuffer->joinForFieldIndex( fieldIdx, mSource->mFields, sourceLayerIndex );
+ Q_ASSERT( joinInfo );
- mFetchJoinInfo.clear();
+ QgsVectorLayer* joinLayer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( joinInfo->joinLayerId ) );
+ Q_ASSERT( joinLayer );
- for ( QgsAttributeList::const_iterator attIt = fetchAttributes.constBegin(); attIt != fetchAttributes.constEnd(); ++attIt )
+ if ( !mFetchJoinInfo.contains( joinInfo ) )
{
- if ( !mSource->mFields.exists( *attIt ) )
- continue;
+ FetchJoinInfo info;
+ info.joinInfo = joinInfo;
+ info.joinLayer = joinLayer;
+ info.indexOffset = mSource->mJoinBuffer->joinedFieldsOffset( joinInfo, mSource->mFields );
- if ( mSource->mFields.fieldOrigin( *attIt ) != QgsFields::OriginJoin )
- continue;
+ if ( joinInfo->targetFieldName.isEmpty() )
+ info.targetField = joinInfo->targetFieldIndex; //for compatibility with 1.x
+ else
+ info.targetField = mSource->mFields.indexFromName( joinInfo->targetFieldName );
+
+ if ( joinInfo->joinFieldName.isEmpty() )
+ info.joinField = joinInfo->joinFieldIndex; //for compatibility with 1.x
+ else
+ info.joinField = joinLayer->fields().indexFromName( joinInfo->joinFieldName );
+
+ // for joined fields, we always need to request the targetField from the provider too
+ if ( !mPreparedFields.contains( info.targetField ) && !mFieldsToPrepare.contains( info.targetField ) )
+ mFieldsToPrepare << info.targetField;
+
+ if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes && !mRequest.subsetOfAttributes().contains( info.targetField ) )
+ mRequest.setSubsetOfAttributes( mRequest.subsetOfAttributes() << info.targetField );
+
+ mFetchJoinInfo.insert( joinInfo, info );
+ }
+
+ // store field source index - we'll need it when fetching from provider
+ mFetchJoinInfo[ joinInfo ].attributes.push_back( sourceLayerIndex );
+}
+
+void QgsVectorLayerFeatureIterator::prepareExpression( int fieldIdx )
+{
+ const QList<QgsExpressionFieldBuffer::ExpressionField>& exps = mSource->mExpressionFieldBuffer->expressions();
+
+ int oi = mSource->mFields.fieldOriginIndex( fieldIdx );
+ QgsExpression* exp = new QgsExpression( exps[oi].cachedExpression );
- int sourceLayerIndex;
- const QgsVectorJoinInfo* joinInfo = mSource->mJoinBuffer->joinForFieldIndex( *attIt, mSource->mFields, sourceLayerIndex );
- Q_ASSERT( joinInfo );
+ QgsDistanceArea da;
+ da.setSourceCrs( mSource->mCrsId );
+ da.setEllipsoidalMode( true );
+ da.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
+ exp->setGeomCalculator( da );
+ exp->setDistanceUnits( QgsProject::instance()->distanceUnits() );
+ exp->setAreaUnits( QgsProject::instance()->areaUnits() );
- QgsVectorLayer* joinLayer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( joinInfo->joinLayerId ) );
- Q_ASSERT( joinLayer );
+ exp->prepare( mExpressionContext.data() );
+ mExpressionFieldInfo.insert( fieldIdx, exp );
- if ( !mFetchJoinInfo.contains( joinInfo ) )
+ Q_FOREACH ( const QString& col, exp->referencedColumns() )
+ {
+ int dependantFieldIdx = mSource->mFields.fieldNameIndex( col );
+ if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes )
{
- FetchJoinInfo info;
- info.joinInfo = joinInfo;
- info.joinLayer = joinLayer;
- info.indexOffset = mSource->mJoinBuffer->joinedFieldsOffset( joinInfo, mSource->mFields );
-
- if ( joinInfo->targetFieldName.isEmpty() )
- info.targetField = joinInfo->targetFieldIndex; //for compatibility with 1.x
- else
- info.targetField = mSource->mFields.indexFromName( joinInfo->targetFieldName );
-
- if ( joinInfo->joinFieldName.isEmpty() )
- info.joinField = joinInfo->joinFieldIndex; //for compatibility with 1.x
- else
- info.joinField = joinLayer->fields().indexFromName( joinInfo->joinFieldName );
-
- // for joined fields, we always need to request the targetField from the provider too
- if ( !fetchAttributes.contains( info.targetField ) )
- sourceJoinFields << info.targetField;
-
- mFetchJoinInfo.insert( joinInfo, info );
+ mRequest.setSubsetOfAttributes( mRequest.subsetOfAttributes() << dependantFieldIdx );
}
-
- // store field source index - we'll need it when fetching from provider
- mFetchJoinInfo[ joinInfo ].attributes.push_back( sourceLayerIndex );
+ // also need to fetch this dependant field
+ if ( !mPreparedFields.contains( dependantFieldIdx ) && !mFieldsToPrepare.contains( dependantFieldIdx ) )
+ mFieldsToPrepare << dependantFieldIdx;
}
- // add sourceJoinFields if we're using a subset
- if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes )
- mRequest.setSubsetOfAttributes( mRequest.subsetOfAttributes() + sourceJoinFields );
+ if ( exp->needsGeometry() )
+ {
+ mRequest.setFlags( mRequest.flags() & ~QgsFeatureRequest::NoGeometry );
+ }
}
-void QgsVectorLayerFeatureIterator::prepareExpressions()
+void QgsVectorLayerFeatureIterator::prepareFields()
{
- const QList<QgsExpressionFieldBuffer::ExpressionField> exps = mSource->mExpressionFieldBuffer->expressions();
+ mPreparedFields.clear();
+ mFieldsToPrepare.clear();
+ mFetchJoinInfo.clear();
+ mOrderedJoinInfoList.clear();
mExpressionContext.reset( new QgsExpressionContext() );
mExpressionContext->appendScope( QgsExpressionContextUtils::globalScope() );
mExpressionContext->appendScope( QgsExpressionContextUtils::projectScope() );
mExpressionContext->setFields( mSource->mFields );
- QList< int > virtualFieldsToFetch;
- for ( int i = 0; i < mSource->mFields.count(); i++ )
+ mFieldsToPrepare = ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) ? mRequest.subsetOfAttributes() : mSource->mFields.allAttributesList();
+
+ while ( !mFieldsToPrepare.isEmpty() )
{
- if ( mSource->mFields.fieldOrigin( i ) == QgsFields::OriginExpression )
- {
- // Only prepare if there is no subset defined or the subset contains this field
- if ( !( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes )
- || mRequest.subsetOfAttributes().contains( i ) )
- {
- virtualFieldsToFetch << i;
- }
- }
+ int fieldIdx = mFieldsToPrepare.takeFirst();
+ if ( mPreparedFields.contains( fieldIdx ) )
+ continue;
+
+ mPreparedFields << fieldIdx;
+ prepareField( fieldIdx );
}
- QList< int > virtualFieldsProcessed;
- while ( !virtualFieldsToFetch.isEmpty() )
+ //sort joins by dependency
+ if ( mFetchJoinInfo.size() > 0 )
{
- int fieldIdx = virtualFieldsToFetch.takeFirst();
- if ( virtualFieldsProcessed.contains( fieldIdx ) )
- continue;
+ createOrderedJoinList();
+ }
+}
- virtualFieldsProcessed << fieldIdx;
+void QgsVectorLayerFeatureIterator::createOrderedJoinList()
+{
+ mOrderedJoinInfoList = mFetchJoinInfo.values();
+ if ( mOrderedJoinInfoList.size() < 2 )
+ {
+ return;
+ }
+ QSet<int> resolvedFields; //todo: get provider / virtual fields without joins
- int oi = mSource->mFields.fieldOriginIndex( fieldIdx );
- QgsExpression* exp = new QgsExpression( exps[oi].cachedExpression );
+ //add all provider fields without joins as resolved fields
+ QList< int >::const_iterator prepFieldIt = mPreparedFields.constBegin();
+ for ( ; prepFieldIt != mPreparedFields.constEnd(); ++prepFieldIt )
+ {
+ if ( mSource->mFields.fieldOrigin( *prepFieldIt ) != QgsFields::OriginJoin )
+ {
+ resolvedFields.insert( *prepFieldIt );
+ }
+ }
- QgsDistanceArea da;
- da.setSourceCrs( mSource->mCrsId );
- da.setEllipsoidalMode( true );
- da.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
- exp->setGeomCalculator( da );
- exp->setDistanceUnits( QgsProject::instance()->distanceUnits() );
- exp->setAreaUnits( QgsProject::instance()->areaUnits() );
+ //iterate through the joins. If target field is not yet covered, move the entry to the end of the list
- exp->prepare( mExpressionContext.data() );
- mExpressionFieldInfo.insert( fieldIdx, exp );
+ //some join combinations might not have a resolution at all
+ int maxIterations = ( mOrderedJoinInfoList.size() + 1 ) * mOrderedJoinInfoList.size() / 2.0;
+ int currentIteration = 0;
- Q_FOREACH ( const QString& col, exp->referencedColumns() )
+ for ( int i = 0; i < mOrderedJoinInfoList.size() - 1; ++i )
+ {
+ if ( !resolvedFields.contains( mOrderedJoinInfoList.at( i ).targetField ) )
+ {
+ mOrderedJoinInfoList.append( mOrderedJoinInfoList.at( i ) );
+ mOrderedJoinInfoList.removeAt( i );
+ --i;
+ }
+ else
{
- int dependantFieldIdx = mSource->mFields.fieldNameIndex( col );
- if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes )
+ int offset = mOrderedJoinInfoList.at( i ).indexOffset;
+ int joinField = mOrderedJoinInfoList.at( i ).joinField;
+
+ QgsAttributeList attributes = mOrderedJoinInfoList.at( i ).attributes;
+ QgsAttributeList::const_iterator attIt = attributes.constBegin();
+ for ( ; attIt != attributes.constEnd(); ++attIt )
{
- mRequest.setSubsetOfAttributes( mRequest.subsetOfAttributes() << dependantFieldIdx );
+ if ( *attIt != joinField )
+ {
+ resolvedFields.insert( joinField < *attIt ? *attIt + offset - 1 : *attIt + offset );
+ }
}
- // also need to fetch this dependant field
- if ( mSource->mFields.fieldOrigin( dependantFieldIdx ) == QgsFields::OriginExpression )
- virtualFieldsToFetch << dependantFieldIdx;
}
- if ( exp->needsGeometry() )
+ ++currentIteration;
+ if ( currentIteration >= maxIterations )
{
- mRequest.setFlags( mRequest.flags() & ~QgsFeatureRequest::NoGeometry );
+ break;
}
}
+}
+
+void QgsVectorLayerFeatureIterator::prepareField( int fieldIdx )
+{
+ switch ( mSource->mFields.fieldOrigin( fieldIdx ) )
+ {
+ case QgsFields::OriginExpression:
+ prepareExpression( fieldIdx );
+ break;
+
+ case QgsFields::OriginJoin:
+ if ( mSource->mJoinBuffer->containsJoins() )
+ {
+ prepareJoin( fieldIdx );
+ }
+ break;
+ case QgsFields::OriginUnknown:
+ case QgsFields::OriginProvider:
+ case QgsFields::OriginEdit:
+ break;
+ }
}
void QgsVectorLayerFeatureIterator::addJoinedAttributes( QgsFeature &f )
{
- QMap<const QgsVectorJoinInfo*, FetchJoinInfo>::const_iterator joinIt = mFetchJoinInfo.constBegin();
- for ( ; joinIt != mFetchJoinInfo.constEnd(); ++joinIt )
+ QList< FetchJoinInfo >::const_iterator joinIt = mOrderedJoinInfoList.constBegin();
+ for ( ; joinIt != mOrderedJoinInfoList.constEnd(); ++joinIt )
{
- const FetchJoinInfo& info = joinIt.value();
- Q_ASSERT( joinIt.key() );
+ QVariant targetFieldValue = f.attribute( joinIt->targetField );
- QVariant targetFieldValue = f.attribute( info.targetField );
if ( !targetFieldValue.isValid() )
continue;
- const QHash< QString, QgsAttributes>& memoryCache = info.joinInfo->cachedAttributes;
+ const QHash< QString, QgsAttributes>& memoryCache = joinIt->joinInfo->cachedAttributes;
if ( memoryCache.isEmpty() )
- info.addJoinedAttributesDirect( f, targetFieldValue );
+ joinIt->addJoinedAttributesDirect( f, targetFieldValue );
else
- info.addJoinedAttributesCached( f, targetFieldValue );
+ joinIt->addJoinedAttributesCached( f, targetFieldValue );
}
}
@@ -623,24 +686,48 @@ void QgsVectorLayerFeatureIterator::addVirtualAttributes( QgsFeature& f )
attr.resize( mSource->mFields.count() ); // Provider attrs count + joined attrs count + expression attrs count
f.setAttributes( attr );
+ // possible TODO - handle combinations of expression -> join -> expression -> join?
+ // but for now, write that off as too complex and an unlikely rare, unsupported use case
+
+ QList< int > fetchedVirtualAttributes;
+ //first, check through joins for any virtual fields we need
+ QMap<const QgsVectorJoinInfo*, FetchJoinInfo>::const_iterator joinIt = mFetchJoinInfo.constBegin();
+ for ( ; joinIt != mFetchJoinInfo.constEnd(); ++joinIt )
+ {
+ if ( mExpressionFieldInfo.contains( joinIt->targetField ) )
+ {
+ // have to calculate expression field before we can handle this join
+ addExpressionAttribute( f, joinIt->targetField );
+ fetchedVirtualAttributes << joinIt->targetField;
+ }
+ }
+
if ( !mFetchJoinInfo.isEmpty() )
addJoinedAttributes( f );
+ // add remaining expression fields
if ( !mExpressionFieldInfo.isEmpty() )
{
QMap<int, QgsExpression*>::ConstIterator it = mExpressionFieldInfo.constBegin();
-
for ( ; it != mExpressionFieldInfo.constEnd(); ++it )
{
- QgsExpression* exp = it.value();
- mExpressionContext->setFeature( f );
- QVariant val = exp->evaluate( mExpressionContext.data() );
- mSource->mFields.at( it.key() ).convertCompatible( val );
- f.setAttribute( it.key(), val );
+ if ( fetchedVirtualAttributes.contains( it.key() ) )
+ continue;
+
+ addExpressionAttribute( f, it.key() );
}
}
}
+void QgsVectorLayerFeatureIterator::addExpressionAttribute( QgsFeature& f, int attrIndex )
+{
+ QgsExpression* exp = mExpressionFieldInfo.value( attrIndex );
+ mExpressionContext->setFeature( f );
+ QVariant val = exp->evaluate( mExpressionContext.data() );
+ mSource->mFields.at( attrIndex ).convertCompatible( val );
+ f.setAttribute( attrIndex, val );
+}
+
bool QgsVectorLayerFeatureIterator::prepareSimplification( const QgsSimplifyMethod& simplifyMethod )
{
delete mEditGeometrySimplifier;
diff --git a/src/core/qgsvectorlayerfeatureiterator.h b/src/core/qgsvectorlayerfeatureiterator.h
index a047a90..3f837ad 100644
--- a/src/core/qgsvectorlayerfeatureiterator.h
+++ b/src/core/qgsvectorlayerfeatureiterator.h
@@ -97,10 +97,19 @@ class CORE_EXPORT QgsVectorLayerFeatureIterator : public QgsAbstractFeatureItera
//! @note not available in Python bindings
void rewindEditBuffer();
+
+ //! @note not available in Python bindings
+ void prepareJoin( int fieldIdx );
+
//! @note not available in Python bindings
- void prepareJoins();
+ void prepareExpression( int fieldIdx );
+
//! @note not available in Python bindings
- void prepareExpressions();
+ void prepareFields();
+
+ //! @note not available in Python bindings
+ void prepareField( int fieldIdx );
+
//! @note not available in Python bindings
bool fetchNextAddedFeature( QgsFeature& f );
//! @note not available in Python bindings
@@ -127,6 +136,14 @@ class CORE_EXPORT QgsVectorLayerFeatureIterator : public QgsAbstractFeatureItera
*/
void addVirtualAttributes( QgsFeature &f );
+ /** Adds an expression based attribute to a feature
+ * @param f feature
+ * @param attrIndex attribute index
+ * @note added in QGIS 2.14
+ * @note not available in Python bindings
+ */
+ void addExpressionAttribute( QgsFeature& f, int attrIndex );
+
/** Update feature with uncommited attribute updates.
* @note not available in Python bindings
*/
@@ -179,6 +196,12 @@ class CORE_EXPORT QgsVectorLayerFeatureIterator : public QgsAbstractFeatureItera
QScopedPointer<QgsExpressionContext> mExpressionContext;
+ QList< int > mPreparedFields;
+ QList< int > mFieldsToPrepare;
+
+ /** Join list sorted by dependency*/
+ QList< FetchJoinInfo > mOrderedJoinInfoList;
+
/**
* Will always return true. We assume that ordering has been done on provider level already.
*
@@ -187,6 +210,8 @@ class CORE_EXPORT QgsVectorLayerFeatureIterator : public QgsAbstractFeatureItera
//! returns whether the iterator supports simplify geometries on provider side
virtual bool providerCanSimplify( QgsSimplifyMethod::MethodType methodType ) const override;
+
+ void createOrderedJoinList();
};
#endif // QGSVECTORLAYERFEATUREITERATOR_H
diff --git a/src/core/qgsvectorlayerlabelprovider.h b/src/core/qgsvectorlayerlabelprovider.h
index fb3efaf..a3d7823 100644
--- a/src/core/qgsvectorlayerlabelprovider.h
+++ b/src/core/qgsvectorlayerlabelprovider.h
@@ -114,6 +114,8 @@ class CORE_EXPORT QgsVectorLayerLabelProvider : public QgsAbstractLabelProvider
//! List of generated
QList<QgsLabelFeature*> mLabels;
+
+ friend class TestQgsLabelingEngineV2;
};
#endif // QGSVECTORLAYERLABELPROVIDER_H
diff --git a/src/core/symbology-ng/qgsvectorcolorrampv2.cpp b/src/core/symbology-ng/qgsvectorcolorrampv2.cpp
index d03ce35..c7f6b44 100644
--- a/src/core/symbology-ng/qgsvectorcolorrampv2.cpp
+++ b/src/core/symbology-ng/qgsvectorcolorrampv2.cpp
@@ -296,8 +296,11 @@ double QgsVectorRandomColorRampV2::value( int index ) const
QColor QgsVectorRandomColorRampV2::color( double value ) const
{
+ if ( value < 0 || value > 1 )
+ return QColor();
+
int colorCnt = mColors.count();
- int colorIdx = static_cast< int >( value * ( colorCnt - 1 ) );
+ int colorIdx = qMin( static_cast< int >( value * colorCnt ), colorCnt - 1 );
if ( colorIdx >= 0 && colorIdx < colorCnt )
return mColors.at( colorIdx );
diff --git a/src/gui/editorwidgets/qgswebviewwidgetwrapper.cpp b/src/gui/editorwidgets/qgswebviewwidgetwrapper.cpp
index 039cd85..a5bc1c1 100644
--- a/src/gui/editorwidgets/qgswebviewwidgetwrapper.cpp
+++ b/src/gui/editorwidgets/qgswebviewwidgetwrapper.cpp
@@ -114,6 +114,7 @@ void QgsWebViewWidgetWrapper::initWidget( QWidget* editor )
mWebView->page()->setNetworkAccessManager( QgsNetworkAccessManager::instance() );
mWebView->settings()->setAttribute( QWebSettings::LocalContentCanAccessRemoteUrls, true );
mWebView->settings()->setAttribute( QWebSettings::JavascriptCanOpenWindows, true );
+ mWebView->settings()->setAttribute( QWebSettings::PluginsEnabled, true );
#ifdef QGISDEBUG
mWebView->settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled, true );
#endif
diff --git a/src/providers/delimitedtext/qgsdelimitedtextfeatureiterator.cpp b/src/providers/delimitedtext/qgsdelimitedtextfeatureiterator.cpp
index 0638034..e963350 100644
--- a/src/providers/delimitedtext/qgsdelimitedtextfeatureiterator.cpp
+++ b/src/providers/delimitedtext/qgsdelimitedtextfeatureiterator.cpp
@@ -501,8 +501,16 @@ QgsDelimitedTextFeatureSource::QgsDelimitedTextFeatureSource( const QgsDelimited
, mXyDms( p->mXyDms )
, attributeColumns( p->attributeColumns )
{
+ QUrl url = p->mFile->url();
+
+ // make sure watcher not created when using iterator (e.g. for rendering, see issue #15558)
+ if ( url.hasQueryItem( "watchFile" ) )
+ {
+ url.removeQueryItem( "watchFile" );
+ }
+
mFile = new QgsDelimitedTextFile();
- mFile->setFromUrl( p->mFile->url() );
+ mFile->setFromUrl( url );
mExpressionContext << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope();
diff --git a/src/providers/delimitedtext/qgsdelimitedtextfile.cpp b/src/providers/delimitedtext/qgsdelimitedtextfile.cpp
index 4af29bf..b788c19 100644
--- a/src/providers/delimitedtext/qgsdelimitedtextfile.cpp
+++ b/src/providers/delimitedtext/qgsdelimitedtextfile.cpp
@@ -35,7 +35,7 @@ QgsDelimitedTextFile::QgsDelimitedTextFile( const QString& url ) :
mEncoding( "UTF-8" ),
mFile( nullptr ),
mStream( nullptr ),
- mUseWatcher( true ),
+ mUseWatcher( false ),
mWatcher( nullptr ),
mDefinitionValid( false ),
mUseHeader( true ),
@@ -158,9 +158,9 @@ bool QgsDelimitedTextFile::setFromUrl( const QUrl &url )
}
//
- if ( url.hasQueryItem( "useWatcher" ) )
+ if ( url.hasQueryItem( "watchFile" ) )
{
- mUseWatcher = ! url.queryItemValue( "useWatcher" ).toUpper().startsWith( 'N' );
+ mUseWatcher = url.queryItemValue( "watchFile" ).toUpper().startsWith( 'Y' );
}
// The default type is csv, to be consistent with the
@@ -269,9 +269,9 @@ QUrl QgsDelimitedTextFile::url()
url.addQueryItem( "encoding", mEncoding );
}
- if ( !mUseWatcher )
+ if ( mUseWatcher )
{
- url.addQueryItem( "useWatcher", "no" );
+ url.addQueryItem( "watchFile", "yes" );
}
url.addQueryItem( "type", type() );
diff --git a/src/providers/ogr/qgsogrconnpool.h b/src/providers/ogr/qgsogrconnpool.h
index 5d28f78..7f7c1f5 100644
--- a/src/providers/ogr/qgsogrconnpool.h
+++ b/src/providers/ogr/qgsogrconnpool.h
@@ -17,6 +17,7 @@
#define QGSOGRCONNPOOL_H
#include "qgsconnectionpool.h"
+#include "qgsogrprovider.h"
#include <ogr_api.h>
@@ -43,7 +44,7 @@ inline void qgsConnectionPool_ConnectionCreate( QString connInfo, QgsOgrConn*& c
inline void qgsConnectionPool_ConnectionDestroy( QgsOgrConn* c )
{
- OGR_DS_Destroy( c->ds );
+ QgsOgrUtils::OGRDestroyWrapper( c->ds );
delete c;
}
diff --git a/src/providers/ogr/qgsogrfeatureiterator.cpp b/src/providers/ogr/qgsogrfeatureiterator.cpp
index 6b37691..70ea6f3 100644
--- a/src/providers/ogr/qgsogrfeatureiterator.cpp
+++ b/src/providers/ogr/qgsogrfeatureiterator.cpp
@@ -301,6 +301,12 @@ bool QgsOgrFeatureIterator::close()
iteratorClosed();
+ // Will for example release SQLite3 statements
+ if ( ogrLayer )
+ {
+ OGR_L_ResetReading( ogrLayer );
+ }
+
if ( mSubsetStringSet )
{
OGR_DS_ReleaseResultSet( mConn->ds, ogrLayer );
@@ -310,6 +316,7 @@ bool QgsOgrFeatureIterator::close()
QgsOgrConnPool::instance()->releaseConnection( mConn );
mConn = nullptr;
+ ogrLayer = nullptr;
mClosed = true;
return true;
diff --git a/src/providers/ogr/qgsogrprovider.cpp b/src/providers/ogr/qgsogrprovider.cpp
index 3249e4a..2ecc723 100644
--- a/src/providers/ogr/qgsogrprovider.cpp
+++ b/src/providers/ogr/qgsogrprovider.cpp
@@ -48,6 +48,13 @@ email : sherman at mrcc.com
#include "qgsvectorlayerimport.h"
#include "qgslocalec.h"
+#ifdef Q_OS_WIN
+#include <windows.h>
+#endif
+#ifdef Q_OS_LINUX
+#include <sys/vfs.h>
+#endif
+
static const QString TEXT_PROVIDER_KEY = "ogr";
static const QString TEXT_PROVIDER_DESCRIPTION =
QString( "OGR data provider" )
@@ -383,11 +390,14 @@ QgsOgrProvider::QgsOgrProvider( QString const & uri )
QgsOgrProvider::~QgsOgrProvider()
{
- close();
QgsOgrConnPool::instance()->unref( dataSourceUri() );
// We must also make sure to flush unusef cached connections so that
// the file can be removed (#15137)
QgsOgrConnPool::instance()->invalidateConnections( dataSourceUri() );
+
+ // Do that as last step for final cleanup that might be prevented by
+ // still opened datasets.
+ close();
}
QgsAbstractFeatureSource* QgsOgrProvider::featureSource() const
@@ -2627,6 +2637,152 @@ void QgsOgrProvider::forceReload()
QgsOgrConnPool::instance()->invalidateConnections( dataSourceUri() );
}
+OGRDataSourceH QgsOgrUtils::OGROpenWrapper( const char* pszPath, bool bUpdate, OGRSFDriverH *phDriver )
+{
+ CPLErrorReset();
+ OGRSFDriverH hDriver = nullptr;
+ OGRDataSourceH hDS = OGROpen( pszPath, bUpdate, &hDriver );
+ if ( phDriver )
+ *phDriver = hDriver;
+ if ( !hDS )
+ return nullptr;
+ // GDAL < 1.11.5 has a crashing bug with GeoPackage databases with curve geometry
+ // types (https://trac.osgeo.org/gdal/ticket/6558)
+#if GDAL_VERSION_MAJOR == 1 && GDAL_VERSION_MINOR == 11 && GDAL_VERSION_MACRO < 5
+ const char* pszLastErrorMsg = CPLGetLastErrorMsg();
+ if ( hDriver == OGRGetDriverByName( "GPKG" ) &&
+ strstr( pszLastErrorMsg, "geometry column" ) &&
+ strstr( pszLastErrorMsg, "of type" ) &&
+ strstr( pszLastErrorMsg, "ignored" ) )
+ {
+ QgsDebugMsg( QString( "Ignoring %1 that is a GeoPackage DB with curve geometries" ).arg( pszPath ) );
+ OGR_DS_Destroy( hDS );
+ hDS = nullptr;
+ }
+#endif
+ return hDS;
+}
+
+static bool IsLocalFile( const QString& path )
+{
+ QString dirName( QFileInfo( path ).absolutePath() );
+ // Start with the OS specific methods since the QT >= 5.4 method just
+ // return a string and not an enumerated type.
+#if defined(Q_OS_WIN)
+ if ( dirName.startsWith( "\\\\" ) )
+ return false;
+ if ( dirName.length() >= 3 && dirName[1] == ':' &&
+ ( dirName[2] == '\\' || dirName[2] == '/' ) )
+ {
+ dirName.resize( 3 );
+ return GetDriveType( dirName.toAscii().constData() ) != DRIVE_REMOTE;
+ }
+ return true;
+#elif defined(Q_OS_LINUX)
+ struct statfs sStatFS;
+ if ( statfs( dirName.toAscii().constData(), &sStatFS ) == 0 )
+ {
+ // Codes from http://man7.org/linux/man-pages/man2/statfs.2.html
+ if ( sStatFS.f_type == 0x6969 /* NFS */ ||
+ sStatFS.f_type == 0x517b /* SMB */ ||
+ sStatFS.f_type == 0xff534d42 /* CIFS */ )
+ {
+ return false;
+ }
+ }
+ return true;
+#elif QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
+ QStorageInfo info( dirName );
+ QString fileSystem( info.fileSystemType() );
+ QgsDebugMsg( QString( "Filesystem for %1 is %2" ).arg( path ).arg( fileSystem ) );
+ return path != "nfs" && path != "smbfs";
+#else
+ return true;
+#endif
+}
+
+void QgsOgrUtils::OGRDestroyWrapper( OGRDataSourceH ogrDataSource )
+{
+ if ( !ogrDataSource )
+ return;
+ OGRSFDriverH ogrDriver = OGR_DS_GetDriver( ogrDataSource );
+ QString ogrDriverName = OGR_Dr_GetName( ogrDriver );
+ QString datasetName( FROM8( OGR_DS_GetName( ogrDataSource ) ) );
+ if ( ogrDriverName == "GPKG" &&
+ IsLocalFile( datasetName ) &&
+ !CPLGetConfigOption( "OGR_SQLITE_JOURNAL", NULL ) )
+ {
+ // We need to reset all iterators on layers, otherwise we will not
+ // be able to change journal_mode.
+ int layerCount = OGR_DS_GetLayerCount( ogrDataSource );
+ for ( int i = 0; i < layerCount; i ++ )
+ {
+ OGR_L_ResetReading( OGR_DS_GetLayer( ogrDataSource, i ) );
+ }
+
+ CPLPushErrorHandler( CPLQuietErrorHandler );
+ QgsDebugMsg( "GPKG: Trying to return to delete mode" );
+ bool bSuccess = false;
+ OGRLayerH hSqlLyr = OGR_DS_ExecuteSQL( ogrDataSource,
+ "PRAGMA journal_mode = delete",
+ NULL, NULL );
+ if ( hSqlLyr != NULL )
+ {
+ OGRFeatureH hFeat = OGR_L_GetNextFeature( hSqlLyr );
+ if ( hFeat != NULL )
+ {
+ const char* pszRet = OGR_F_GetFieldAsString( hFeat, 0 );
+ bSuccess = EQUAL( pszRet, "delete" );
+ QgsDebugMsg( QString( "Return: %1" ).arg( pszRet ) );
+ OGR_F_Destroy( hFeat );
+ }
+ }
+ else if ( CPLGetLastErrorType() != CE_None )
+ {
+ QgsDebugMsg( QString( "Return: %1" ).arg( CPLGetLastErrorMsg() ) );
+ }
+ OGR_DS_ReleaseResultSet( ogrDataSource, hSqlLyr );
+ CPLPopErrorHandler();
+ OGR_DS_Destroy( ogrDataSource );
+
+ // This may have not worked if the file was opened in read-only mode,
+ // so retry in update mode
+ if ( !bSuccess )
+ {
+ QgsDebugMsg( "GPKG: Trying again" );
+ CPLSetThreadLocalConfigOption( "OGR_SQLITE_JOURNAL", "DELETE" );
+ ogrDataSource = OGROpen( TO8F( datasetName ), TRUE, NULL );
+ CPLSetThreadLocalConfigOption( "OGR_SQLITE_JOURNAL", NULL );
+ if ( ogrDataSource )
+ {
+#ifdef QGISDEBUG
+ CPLPushErrorHandler( CPLQuietErrorHandler );
+ OGRLayerH hSqlLyr = OGR_DS_ExecuteSQL( ogrDataSource,
+ "PRAGMA journal_mode",
+ NULL, NULL );
+ CPLPopErrorHandler();
+ if ( hSqlLyr != NULL )
+ {
+ OGRFeatureH hFeat = OGR_L_GetNextFeature( hSqlLyr );
+ if ( hFeat != NULL )
+ {
+ const char* pszRet = OGR_F_GetFieldAsString( hFeat, 0 );
+ QgsDebugMsg( QString( "Return: %1" ).arg( pszRet ) );
+ OGR_F_Destroy( hFeat );
+ }
+ OGR_DS_ReleaseResultSet( ogrDataSource, hSqlLyr );
+ }
+#endif
+ OGR_DS_Destroy( ogrDataSource );
+ }
+ }
+ }
+ else
+ {
+ OGR_DS_Destroy( ogrDataSource );
+ }
+}
+
QByteArray QgsOgrUtils::quotedIdentifier( QByteArray field, const QString& ogrDriverName )
{
if ( ogrDriverName == "MySQL" )
@@ -2855,7 +3011,22 @@ void QgsOgrProvider::open( OpenMode mode )
// first try to open in update mode (unless specified otherwise)
if ( !openReadOnly )
- ogrDataSource = OGROpen( TO8F( mFilePath ), true, &ogrDriver );
+ {
+ if ( QFileInfo( mFilePath ).suffix().compare( "gpkg", Qt::CaseInsensitive ) == 0 &&
+ IsLocalFile( mFilePath ) &&
+ !CPLGetConfigOption( "OGR_SQLITE_JOURNAL", NULL ) &&
+ QSettings().value( "/qgis/walForSqlite3", true ).toBool() )
+ {
+ // For GeoPackage, we force opening of the file in WAL (Write Ahead Log)
+ // mode so as to avoid readers blocking writer(s), and vice-versa.
+ // https://www.sqlite.org/wal.html
+ // But only do that on a local file since WAL is advertized not to work
+ // on network shares
+ CPLSetThreadLocalConfigOption( "OGR_SQLITE_JOURNAL", "WAL" );
+ }
+ ogrDataSource = QgsOgrUtils::OGROpenWrapper( TO8F( mFilePath ), true, &ogrDriver );
+ CPLSetThreadLocalConfigOption( "OGR_SQLITE_JOURNAL", NULL );
+ }
mValid = false;
if ( ogrDataSource )
@@ -2985,7 +3156,7 @@ void QgsOgrProvider::close()
if ( ogrDataSource )
{
- OGR_DS_Destroy( ogrDataSource );
+ QgsOgrUtils::OGRDestroyWrapper( ogrDataSource );
}
ogrDataSource = nullptr;
ogrLayer = nullptr;
diff --git a/src/providers/ogr/qgsogrprovider.h b/src/providers/ogr/qgsogrprovider.h
index c1cf3aa..690ba7a 100644
--- a/src/providers/ogr/qgsogrprovider.h
+++ b/src/providers/ogr/qgsogrprovider.h
@@ -15,6 +15,9 @@ email : sherman at mrcc.com
* *
***************************************************************************/
+#ifndef QGSOGRPROVIDER_H
+#define QGSOGRPROVIDER_H
+
#include "QTextCodec"
#include "qgsrectangle.h"
@@ -400,4 +403,9 @@ class QgsOgrUtils
/** Quote a value for placement in a SQL string.
*/
static QString quotedValue( const QVariant& value );
+
+ static OGRDataSourceH OGROpenWrapper( const char* pszPath, bool bUpdate, OGRSFDriverH *phDriver );
+ static void OGRDestroyWrapper( OGRDataSourceH ogrDataSource );
};
+
+#endif // QGSOGRPROVIDER_H
diff --git a/src/providers/postgres/qgspostgresdataitems.cpp b/src/providers/postgres/qgspostgresdataitems.cpp
index 5d52ded..4c254a5 100644
--- a/src/providers/postgres/qgspostgresdataitems.cpp
+++ b/src/providers/postgres/qgspostgresdataitems.cpp
@@ -693,9 +693,13 @@ bool QgsPGSchemaItem::handleDrop( const QMimeData * data, Qt::DropAction )
{
QgsPGConnectionItem *conn = qobject_cast<QgsPGConnectionItem *>( parent() );
if ( !conn )
- return 0;
+ return false;
+
+ bool result = conn->handleDrop( data, mName );
+ if ( result )
+ refresh();
- return conn->handleDrop( data, mName );
+ return result;
}
// ---------------------------------------------------------------------------
diff --git a/src/providers/postgres/qgspostgresprovider.cpp b/src/providers/postgres/qgspostgresprovider.cpp
index 0ce3044..948275f 100644
--- a/src/providers/postgres/qgspostgresprovider.cpp
+++ b/src/providers/postgres/qgspostgresprovider.cpp
@@ -2306,8 +2306,11 @@ void QgsPostgresProvider::appendGeomParam( const QgsGeometry *geom, QStringList
}
QString param;
- const unsigned char *buf = geom->asWkb();
- for ( int i = 0; i < geom->wkbSize(); ++i )
+ QScopedPointer<QgsGeometry> convertedGeom( convertToProviderType( *geom ) );
+ const unsigned char *buf = convertedGeom ? convertedGeom->asWkb() : geom->asWkb();
+ size_t wkbSize = convertedGeom ? convertedGeom->wkbSize() : geom->wkbSize();
+
+ for ( size_t i = 0; i < wkbSize; ++i )
{
if ( connectionRO()->useWkbHex() )
param += QString( "%1" ).arg(( int ) buf[i], 2, 16, QChar( '0' ) );
diff --git a/src/providers/spatialite/qgsspatialitesourceselect.cpp b/src/providers/spatialite/qgsspatialitesourceselect.cpp
index a583fc9..da7a2ef 100644
--- a/src/providers/spatialite/qgsspatialitesourceselect.cpp
+++ b/src/providers/spatialite/qgsspatialitesourceselect.cpp
@@ -460,6 +460,10 @@ void QgsSpatiaLiteSourceSelect::on_btnConnect_clicked()
QMessageBox::critical( this, tr( "SpatiaLite getTableInfo Error" ),
tr( "Failure exploring tables from: %1\n\n%2" ).arg( mSqlitePath, errCause ) );
break;
+ case QgsSpatiaLiteConnection::FailedToCheckMetadata:
+ QMessageBox::critical( this, tr( "SpatiaLite metadata check failed" ),
+ tr( "Failure getting table metadata ... is this really a SpatialLite database? %1\n\n%2" ).arg( mSqlitePath, errCause ) );
+ break;
default:
QMessageBox::critical( this, tr( "SpatiaLite Error" ),
tr( "Unexpected error when working with: %1\n\n%2" ).arg( mSqlitePath, errCause ) );
diff --git a/src/providers/virtual/qgsvirtuallayerqueryparser.cpp b/src/providers/virtual/qgsvirtuallayerqueryparser.cpp
index 9d1047d..1a1c10c 100644
--- a/src/providers/virtual/qgsvirtuallayerqueryparser.cpp
+++ b/src/providers/virtual/qgsvirtuallayerqueryparser.cpp
@@ -39,8 +39,8 @@ namespace QgsVirtualLayerQueryParser
while ( true )
{
char *errMsg = nullptr;
- int r = sqlite3_exec( db.get(), query.toLocal8Bit().constData(), nullptr, nullptr, &errMsg );
- QString err = errMsg;
+ int r = sqlite3_exec( db.get(), query.toUtf8().constData(), nullptr, nullptr, &errMsg );
+ QString err = QString::fromUtf8( errMsg );
if ( r && err.startsWith( noSuchError ) )
{
QString tableName = err.mid( noSuchError.size() );
@@ -48,7 +48,7 @@ namespace QgsVirtualLayerQueryParser
// create a dummy table to skip this error
QString createStr = QString( "CREATE TABLE \"%1\" (id int)" ).arg( tableName.replace( "\"", "\"\"" ) );
- ( void )sqlite3_exec( db.get(), createStr.toLocal8Bit().constData(), nullptr, NULL, NULL );
+ ( void )sqlite3_exec( db.get(), createStr.toUtf8().constData(), nullptr, NULL, NULL );
}
else
{
diff --git a/src/providers/virtual/qgsvirtuallayersqlitemodule.cpp b/src/providers/virtual/qgsvirtuallayersqlitemodule.cpp
index 5397ba9..e9b76b6 100644
--- a/src/providers/virtual/qgsvirtuallayersqlitemodule.cpp
+++ b/src/providers/virtual/qgsvirtuallayersqlitemodule.cpp
@@ -324,11 +324,11 @@ int vtableCreateConnect( sqlite3* sql, void* aux, int argc, const char* const* a
Q_UNUSED( isCreated );
#define RETURN_CSTR_ERROR(err) if (outErr) {size_t s = strlen(err); *outErr=reinterpret_cast<char*>(sqlite3_malloc( static_cast<int>( s ) +1)); strncpy(*outErr, err, s);}
-#define RETURN_CPPSTR_ERROR(err) if (outErr) {*outErr=reinterpret_cast<char*>(sqlite3_malloc( static_cast<int>( err.size() )+1)); strncpy(*outErr, err.c_str(), err.size());}
+#define RETURN_CPPSTR_ERROR(err) if (outErr) {*outErr=reinterpret_cast<char*>(sqlite3_malloc( static_cast<int>( err.toUtf8().size() )+1)); strncpy(*outErr, err.toUtf8().constData(), err.toUtf8().size());}
if ( argc < 4 )
{
- std::string err( "Missing arguments: layer_id | provider, source" );
+ QString err( "Missing arguments: layer_id | provider, source" );
RETURN_CPPSTR_ERROR( err );
return SQLITE_ERROR;
}
@@ -341,7 +341,7 @@ int vtableCreateConnect( sqlite3* sql, void* aux, int argc, const char* const* a
// CREATE VIRTUAL TABLE vtab USING QgsVLayer(layer_id)
// vtab = argv[2]
// layer_id = argv[3]
- QString layerid( argv[3] );
+ QString layerid = QString::fromUtf8( argv[3] );
if ( layerid.size() >= 1 && layerid[0] == '\'' )
{
layerid = layerid.mid( 1, layerid.size() - 2 );
@@ -351,8 +351,8 @@ int vtableCreateConnect( sqlite3* sql, void* aux, int argc, const char* const* a
{
if ( outErr )
{
- std::string err( "Cannot find layer " );
- err += argv[3];
+ QString err( "Cannot find layer " );
+ err += QString::fromUtf8( argv[3] );
RETURN_CPPSTR_ERROR( err );
}
return SQLITE_ERROR;
@@ -368,7 +368,7 @@ int vtableCreateConnect( sqlite3* sql, void* aux, int argc, const char* const* a
// source = argv[4]
// encoding = argv[5]
QString provider = argv[3];
- QString source = argv[4];
+ QString source = QString::fromUtf8( argv[4] );
QString encoding = "UTF-8";
if ( argc == 6 )
{
@@ -386,17 +386,16 @@ int vtableCreateConnect( sqlite3* sql, void* aux, int argc, const char* const* a
}
try
{
- newVtab.reset( new VTable( sql, provider, source, argv[2], encoding ) );
+ newVtab.reset( new VTable( sql, provider, source, QString::fromUtf8( argv[2] ), encoding ) );
}
catch ( std::runtime_error& e )
{
- std::string err( e.what() );
- RETURN_CPPSTR_ERROR( err );
+ RETURN_CSTR_ERROR( e.what() );
return SQLITE_ERROR;
}
}
- r = sqlite3_declare_vtab( sql, newVtab->creationString().toLocal8Bit().constData() );
+ r = sqlite3_declare_vtab( sql, newVtab->creationString().toUtf8().constData() );
if ( r )
{
RETURN_CSTR_ERROR( sqlite3_errmsg( sql ) );
diff --git a/tests/src/core/testqgsexpression.cpp b/tests/src/core/testqgsexpression.cpp
index b76db34..7f54fa7 100644
--- a/tests/src/core/testqgsexpression.cpp
+++ b/tests/src/core/testqgsexpression.cpp
@@ -614,6 +614,7 @@ class TestQgsExpression: public QObject
QTest::newRow( "shortest_line geom" ) << "geom_to_wkt(shortest_line( geom_from_wkt('LineString( 1 1, 5 1, 5 5 )'),geom_from_wkt('Point( 6 3 )')))" << false << QVariant( "LineString (5 3, 6 3)" );
QTest::newRow( "shortest_line not geom" ) << "shortest_line('g','a')" << true << QVariant();
QTest::newRow( "shortest_line null" ) << "shortest_line(NULL,NULL)" << false << QVariant();
+ QTest::newRow( "transform invalid" ) << "transform(make_point(0,0),'EPSG:4326','EPSG:28356')" << false << QVariant();
// string functions
QTest::newRow( "lower" ) << "lower('HeLLo')" << false << QVariant( "hello" );
diff --git a/tests/src/core/testqgslabelingenginev2.cpp b/tests/src/core/testqgslabelingenginev2.cpp
index 9f70edf..c7dfed6 100644
--- a/tests/src/core/testqgslabelingenginev2.cpp
+++ b/tests/src/core/testqgslabelingenginev2.cpp
@@ -43,6 +43,7 @@ class TestQgsLabelingEngineV2 : public QObject
void testRuleBased();
void zOrder(); //test that labels are stacked correctly
void testEncodeDecodePositionOrder();
+ void testCapitalization();
private:
QgsVectorLayer* vl;
@@ -413,6 +414,65 @@ void TestQgsLabelingEngineV2::testEncodeDecodePositionOrder()
QCOMPARE( decoded, expected );
}
+void TestQgsLabelingEngineV2::testCapitalization()
+{
+ QgsFeature f( vl->fields(), 1 );
+ f.setGeometry( QgsGeometry::fromPoint( QgsPoint( 1, 2 ) ) );
+
+ // make a fake render context
+ QSize size( 640, 480 );
+ QgsMapSettings mapSettings;
+ mapSettings.setOutputSize( size );
+ mapSettings.setExtent( vl->extent() );
+ mapSettings.setLayers( QStringList() << vl->id() );
+ mapSettings.setOutputDpi( 96 );
+ QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings );
+ QStringList attributes;
+ QgsLabelingEngineV2 engine;
+ engine.setMapSettings( mapSettings );
+
+ // no change
+ QgsPalLayerSettings settings;
+ QFont font = settings.textFont;
+ font.setCapitalization( QFont::MixedCase );
+ settings.textFont = font;
+ settings.fieldName = QString( "'a teSt LABEL'" );
+ settings.isExpression = true;
+
+ QgsVectorLayerLabelProvider* provider = new QgsVectorLayerLabelProvider( vl, true, &settings );
+ engine.addProvider( provider );
+ provider->prepare( context, attributes );
+ provider->registerFeature( f, context );
+ QCOMPARE( provider->mLabels.at( 0 )->labelText(), QString( "a teSt LABEL" ) );
+
+ //uppercase
+ font.setCapitalization( QFont::AllUppercase );
+ settings.textFont = font;
+ QgsVectorLayerLabelProvider* provider2 = new QgsVectorLayerLabelProvider( vl, true, &settings );
+ engine.addProvider( provider2 );
+ provider2->prepare( context, attributes );
+ provider2->registerFeature( f, context );
+ QCOMPARE( provider2->mLabels.at( 0 )->labelText(), QString( "A TEST LABEL" ) );
+
+ //lowercase
+ font.setCapitalization( QFont::AllLowercase );
+ settings.textFont = font;
+ QgsVectorLayerLabelProvider* provider3 = new QgsVectorLayerLabelProvider( vl, true, &settings );
+ engine.addProvider( provider3 );
+ provider3->prepare( context, attributes );
+ provider3->registerFeature( f, context );
+ QCOMPARE( provider3->mLabels.at( 0 )->labelText(), QString( "a test label" ) );
+
+ //first letter uppercase
+ font.setCapitalization( QFont::Capitalize );
+ settings.textFont = font;
+ QgsVectorLayerLabelProvider* provider4 = new QgsVectorLayerLabelProvider( vl, true, &settings );
+ engine.addProvider( provider4 );
+ provider4->prepare( context, attributes );
+ provider4->registerFeature( f, context );
+ QCOMPARE( provider4->mLabels.at( 0 )->labelText(), QString( "A TeSt LABEL" ) );
+}
+
bool TestQgsLabelingEngineV2::imageCheck( const QString& testName, QImage &image, int mismatchCount )
{
//draw background
diff --git a/tests/src/core/testqgslegendrenderer.cpp b/tests/src/core/testqgslegendrenderer.cpp
index 7d9e251..f6820e8 100644
--- a/tests/src/core/testqgslegendrenderer.cpp
+++ b/tests/src/core/testqgslegendrenderer.cpp
@@ -115,6 +115,8 @@ class TestQgsLegendRenderer : public QObject
void testThreeColumns();
void testFilterByMap();
void testFilterByMapSameSymbol();
+ void testColumns_data();
+ void testColumns();
void testRasterBorder();
void testFilterByPolygon();
void testFilterByExpression();
@@ -126,6 +128,7 @@ class TestQgsLegendRenderer : public QObject
QgsVectorLayer* mVL3; // point
QgsRasterLayer* mRL;
QString mReport;
+ bool _testLegendColumns( int itemCount, int columnCount, const QString& testName );
};
@@ -448,6 +451,65 @@ void TestQgsLegendRenderer::testFilterByMapSameSymbol()
QgsMapLayerRegistry::instance()->removeMapLayer( vl4 );
}
+bool TestQgsLegendRenderer::_testLegendColumns( int itemCount, int columnCount, const QString& testName )
+{
+ QgsFillSymbolV2* sym = new QgsFillSymbolV2();
+ sym->setColor( Qt::cyan );
+
+ QgsLayerTreeGroup* root = new QgsLayerTreeGroup();
+
+ QList< QgsVectorLayer* > layers;
+ for ( int i = 1; i <= itemCount; ++i )
+ {
+ QgsVectorLayer* vl = new QgsVectorLayer( "Polygon", QString( "Layer %1" ).arg( i ), "memory" );
+ QgsMapLayerRegistry::instance()->addMapLayer( vl );
+ vl->setRendererV2( new QgsSingleSymbolRendererV2( sym->clone() ) );
+ root->addLayer( vl );
+ layers << vl;
+ }
+ delete sym;
+
+ QgsLayerTreeModel legendModel( root );
+ QgsLegendSettings settings;
+ settings.setColumnCount( columnCount );
+ _setStandardTestFont( settings, "Bold" );
+ _renderLegend( testName, &legendModel, settings );
+ bool result = _verifyImage( testName, mReport );
+
+ Q_FOREACH ( QgsVectorLayer* l, layers )
+ {
+ QgsMapLayerRegistry::instance()->removeMapLayer( l );
+ }
+ return result;
+}
+
+void TestQgsLegendRenderer::testColumns_data()
+{
+ QTest::addColumn<QString>( "testName" );
+ QTest::addColumn<int>( "items" );
+ QTest::addColumn<int>( "columns" );
+
+ QTest::newRow( "2 items, 2 columns" ) << "legend_2_by_2" << 2 << 2;
+ QTest::newRow( "3 items, 2 columns" ) << "legend_3_by_2" << 3 << 2;
+ QTest::newRow( "4 items, 2 columns" ) << "legend_4_by_2" << 4 << 2;
+ QTest::newRow( "5 items, 2 columns" ) << "legend_5_by_2" << 5 << 2;
+ QTest::newRow( "3 items, 3 columns" ) << "legend_3_by_3" << 3 << 3;
+ QTest::newRow( "4 items, 3 columns" ) << "legend_4_by_3" << 4 << 3;
+ QTest::newRow( "5 items, 3 columns" ) << "legend_5_by_3" << 5 << 3;
+ QTest::newRow( "6 items, 3 columns" ) << "legend_6_by_3" << 6 << 3;
+ QTest::newRow( "7 items, 3 columns" ) << "legend_7_by_3" << 7 << 3;
+}
+
+void TestQgsLegendRenderer::testColumns()
+{
+ //test rendering legend with different combinations of columns and items
+
+ QFETCH( QString, testName );
+ QFETCH( int, items );
+ QFETCH( int, columns );
+ QVERIFY( _testLegendColumns( items, columns, testName ) );
+}
+
void TestQgsLegendRenderer::testRasterBorder()
{
QString testName = "legend_raster_border";
diff --git a/tests/src/python/test_provider_ogr_gpkg.py b/tests/src/python/test_provider_ogr_gpkg.py
new file mode 100644
index 0000000..b746135
--- /dev/null
+++ b/tests/src/python/test_provider_ogr_gpkg.py
@@ -0,0 +1,164 @@
+# -*- coding: utf-8 -*-
+"""QGIS Unit tests for the OGR/GPKG provider.
+
+.. note:: 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.
+"""
+__author__ = 'Even Rouault'
+__date__ = '2016-04-21'
+__copyright__ = 'Copyright 2016, Even Rouault'
+# This will get replaced with a git SHA1 when you do a git archive
+__revision__ = '$Format:%H$'
+
+import qgis # NOQA
+
+import os
+import tempfile
+import shutil
+import glob
+from osgeo import gdal, ogr
+
+from qgis.core import QgsVectorLayer, QgsFeature, QgsGeometry, QgsFeatureRequest
+from qgis.testing import start_app, unittest
+from utilities import unitTestDataPath
+
+start_app()
+
+
+def GDAL_COMPUTE_VERSION(maj, min, rev):
+ return ((maj) * 1000000 + (min) * 10000 + (rev) * 100)
+
+
+class ErrorReceiver():
+
+ def __init__(self):
+ self.msg = None
+
+ def receiveError(self, msg):
+ self.msg = msg
+
+
+class TestPyQgsOGRProviderGpkg(unittest.TestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ """Run before all tests"""
+ # Create test layer
+ cls.basetestpath = tempfile.mkdtemp()
+
+ @classmethod
+ def tearDownClass(cls):
+ """Run after all tests"""
+ shutil.rmtree(cls.basetestpath, True)
+
+ def XXXXtestSingleToMultiPolygonPromotion(self):
+
+ tmpfile = os.path.join(self.basetestpath, 'testSingleToMultiPolygonPromotion.gpkg')
+ ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile)
+ lyr = ds.CreateLayer('test', geom_type=ogr.wkbMultiPolygon)
+ ds = None
+
+ vl = QgsVectorLayer(u'{}|layerid=0'.format(tmpfile), u'test', u'ogr')
+ f = QgsFeature()
+ f.setGeometry(QgsGeometry.fromWkt('POLYGON ((0 0,0 1,1 1,0 0))'))
+ vl.dataProvider().addFeatures([f])
+ got = [f for f in vl.getFeatures()][0]
+ got_geom = got.geometry()
+ reference = QgsGeometry.fromWkt('MultiPolygon (((0 0, 0 1, 1 1, 0 0)))')
+ # The geometries must be binarily identical
+ self.assertEqual(got_geom.asWkb(), reference.asWkb(), 'Expected {}, got {}'.format(reference.exportToWkt(), got_geom.exportToWkt()))
+
+ def XXXXtestCurveGeometryType(self):
+ if int(gdal.VersionInfo('VERSION_NUM')) < GDAL_COMPUTE_VERSION(2, 0, 0):
+ return
+
+ tmpfile = os.path.join(self.basetestpath, 'testCurveGeometryType.gpkg')
+ ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile)
+ lyr = ds.CreateLayer('test', geom_type=ogr.wkbCurvePolygon)
+ ds = None
+
+ vl = QgsVectorLayer(u'{}'.format(tmpfile), u'test', u'ogr')
+ self.assertEqual(vl.dataProvider().subLayers(), [u'0:test:0:CurvePolygon'])
+ f = QgsFeature()
+ f.setGeometry(QgsGeometry.fromWkt('POLYGON ((0 0,0 1,1 1,0 0))'))
+ vl.dataProvider().addFeatures([f])
+ got = [f for f in vl.getFeatures()][0]
+ got_geom = got.geometry()
+ reference = QgsGeometry.fromWkt('CurvePolygon (((0 0, 0 1, 1 1, 0 0)))')
+ # The geometries must be binarily identical
+ self.assertEqual(got_geom.asWkb(), reference.asWkb(), 'Expected {}, got {}'.format(reference.exportToWkt(), got_geom.exportToWkt()))
+
+ def internalTestBug15351(self, orderClosing):
+
+ tmpfile = os.path.join(self.basetestpath, 'testBug15351.gpkg')
+ ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile)
+ lyr = ds.CreateLayer('test', geom_type=ogr.wkbPoint)
+ f = ogr.Feature(lyr.GetLayerDefn())
+ f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(0 0)'))
+ lyr.CreateFeature(f)
+ f = None
+ ds = None
+
+ vl = QgsVectorLayer(u'{}'.format(tmpfile), u'test', u'ogr')
+ self.assertTrue(vl.startEditing())
+ self.assertTrue(vl.changeGeometry(1, QgsGeometry.fromWkt('Point (3 50)')))
+
+ # Iterate over features (will open a new OGR connection), but do not
+ # close the iterator for now
+ it = vl.getFeatures()
+ f = QgsFeature()
+ it.nextFeature(f)
+
+ if orderClosing == 'closeIter_commit_closeProvider':
+ it = None
+
+ # Commit changes
+ cbk = ErrorReceiver()
+ vl.dataProvider().raiseError.connect(cbk.receiveError)
+ self.assertTrue(vl.commitChanges())
+ self.assertIsNone(cbk.msg)
+
+ # Close layer and iterator in different orders
+ if orderClosing == 'closeIter_commit_closeProvider':
+ vl = None
+ elif orderClosing == 'commit_closeProvider_closeIter':
+ vl = None
+ it = None
+ else:
+ assert orderClosing == 'commit_closeIter_closeProvider'
+ it = None
+ vl = None
+
+ # Test that we succeeded restoring default journal mode, and we
+ # are not let in WAL mode.
+ ds = ogr.Open(tmpfile)
+ lyr = ds.ExecuteSQL('PRAGMA journal_mode')
+ f = lyr.GetNextFeature()
+ res = f.GetField(0)
+ ds.ReleaseResultSet(lyr)
+ ds = None
+ self.assertEqual(res, 'delete')
+
+ # We need GDAL 2.0 to issue PRAGMA journal_mode
+ # Note: for that case, we don't strictly need turning on WAL
+ def testBug15351_closeIter_commit_closeProvider(self):
+ if int(gdal.VersionInfo('VERSION_NUM')) < GDAL_COMPUTE_VERSION(2, 0, 0):
+ return
+ self.internalTestBug15351('closeIter_commit_closeProvider')
+
+ # We need GDAL 2.0 to issue PRAGMA journal_mode
+ def testBug15351_closeIter_commit_closeProvider(self):
+ if int(gdal.VersionInfo('VERSION_NUM')) < GDAL_COMPUTE_VERSION(2, 0, 0):
+ return
+ self.internalTestBug15351('closeIter_commit_closeProvider')
+
+ # We need GDAL 2.0 to issue PRAGMA journal_mode
+ def testBug15351_commit_closeIter_closeProvider(self):
+ if int(gdal.VersionInfo('VERSION_NUM')) < GDAL_COMPUTE_VERSION(2, 0, 0):
+ return
+ self.internalTestBug15351('commit_closeIter_closeProvider')
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/src/python/test_provider_virtual.py b/tests/src/python/test_provider_virtual.py
index 6ed2a72..7a4fe0c 100644
--- a/tests/src/python/test_provider_virtual.py
+++ b/tests/src/python/test_provider_virtual.py
@@ -738,6 +738,20 @@ class TestQgsVirtualLayerProvider(unittest.TestCase, ProviderTestCase):
ids = [f.id() for f in vl2.getFeatures()]
self.assertEqual(ids, [])
+ def test_layer_with_accents(self):
+ l1 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), u"françéà", "ogr", False)
+ self.assertEqual(l1.isValid(), True)
+ QgsMapLayerRegistry.instance().addMapLayer(l1)
+
+ df = QgsVirtualLayerDefinition()
+ df.setQuery(u'select * from "françéà"')
+
+ vl = QgsVectorLayer(df.toString(), "testq", "virtual")
+ self.assertEqual(vl.isValid(), True)
+ ids = [f.id() for f in vl.getFeatures()]
+ self.assertEqual(len(ids), 4)
+
+ QgsMapLayerRegistry.instance().removeMapLayer(l1.id())
if __name__ == '__main__':
unittest.main()
diff --git a/tests/src/python/test_qgsfeatureiterator.py b/tests/src/python/test_qgsfeatureiterator.py
index 19f25c1..034d0a8 100644
--- a/tests/src/python/test_qgsfeatureiterator.py
+++ b/tests/src/python/test_qgsfeatureiterator.py
@@ -15,7 +15,7 @@ __revision__ = '$Format:%H$'
import qgis
import os
-from qgis.core import QgsVectorLayer, QgsFeatureRequest, QgsFeature, QgsField, NULL
+from qgis.core import QgsVectorLayer, QgsFeatureRequest, QgsFeature, QgsField, QgsMapLayerRegistry, QgsVectorJoinInfo, NULL
from qgis.testing import (start_app,
unittest
)
@@ -23,6 +23,7 @@ from PyQt4.QtCore import QVariant
from utilities import (unitTestDataPath,
compareWkt
)
+
start_app()
TEST_DATA_DIR = unitTestDataPath()
@@ -155,6 +156,91 @@ class TestQgsFeatureIterator(unittest.TestCase):
fet = next(layer.getFeatures(QgsFeatureRequest().setSubsetOfAttributes(['exp2'], layer.fields())))
self.assertEqual(fet['Class'], NULL)
+ def test_JoinUsingExpression(self):
+ """ test joining a layer using a virtual field """
+ joinLayer = QgsVectorLayer(
+ "Point?field=x:string&field=y:integer&field=z:integer",
+ "joinlayer", "memory")
+ pr = joinLayer.dataProvider()
+ f1 = QgsFeature()
+ f1.setAttributes(["foo", 246, 321])
+ f2 = QgsFeature()
+ f2.setAttributes(["bar", 456, 654])
+ self.assertTrue(pr.addFeatures([f1, f2]))
+
+ layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer",
+ "addfeat", "memory")
+ pr = layer.dataProvider()
+ f = QgsFeature()
+ f.setAttributes(["test", 123])
+ self.assertTrue(pr.addFeatures([f]))
+ layer.addExpressionField('"fldint"*2', QgsField('exp1', QVariant.LongLong))
+
+ QgsMapLayerRegistry.instance().addMapLayers([layer, joinLayer])
+
+ join = QgsVectorJoinInfo()
+ join.targetFieldName = "exp1"
+ join.joinLayerId = joinLayer.id()
+ join.joinFieldName = "y"
+ join.memoryCache = True
+ layer.addJoin(join)
+
+ f = QgsFeature()
+ fi = layer.getFeatures()
+ self.assertTrue(fi.nextFeature(f))
+ attrs = f.attributes()
+ self.assertEqual(attrs[0], "test")
+ self.assertEqual(attrs[1], 123)
+ self.assertEqual(attrs[2], "foo")
+ self.assertEqual(attrs[3], 321)
+ self.assertEqual(attrs[4], 246)
+ self.assertFalse(fi.nextFeature(f))
+
+ QgsMapLayerRegistry.instance().removeMapLayers([layer, joinLayer])
+
+ def test_JoinUsingExpression2(self):
+ """ test joining a layer using a virtual field (the other way!) """
+ joinLayer = QgsVectorLayer(
+ "Point?field=x:string&field=y:integer&field=z:integer",
+ "joinlayer", "memory")
+ pr = joinLayer.dataProvider()
+ f1 = QgsFeature()
+ f1.setAttributes(["foo", 246, 321])
+ f2 = QgsFeature()
+ f2.setAttributes(["bar", 456, 654])
+ self.assertTrue(pr.addFeatures([f1, f2]))
+ joinLayer.addExpressionField('"y"/2', QgsField('exp1', QVariant.LongLong))
+
+ layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer",
+ "addfeat", "memory")
+ pr = layer.dataProvider()
+ f = QgsFeature()
+ f.setAttributes(["test", 123])
+ self.assertTrue(pr.addFeatures([f]))
+
+ QgsMapLayerRegistry.instance().addMapLayers([layer, joinLayer])
+
+ join = QgsVectorJoinInfo()
+ join.targetFieldName = "fldint"
+ join.joinLayerId = joinLayer.id()
+ join.joinFieldName = "exp1"
+ join.memoryCache = True
+ layer.addJoin(join)
+
+ f = QgsFeature()
+ fi = layer.getFeatures()
+ self.assertTrue(fi.nextFeature(f))
+ attrs = f.attributes()
+ self.assertEqual(attrs[0], "test")
+ self.assertEqual(attrs[1], 123)
+ self.assertEqual(attrs[2], "foo")
+ self.assertEqual(attrs[3], 246)
+ self.assertEqual(attrs[4], 321)
+ self.assertFalse(fi.nextFeature(f))
+
+ QgsMapLayerRegistry.instance().removeMapLayers([layer, joinLayer])
+ # try the other way too
+
if __name__ == '__main__':
unittest.main()
diff --git a/tests/testdata/control_images/legend/expected_legend_2_by_2/expected_legend_2_by_2.png b/tests/testdata/control_images/legend/expected_legend_2_by_2/expected_legend_2_by_2.png
new file mode 100644
index 0000000..33fce22
Binary files /dev/null and b/tests/testdata/control_images/legend/expected_legend_2_by_2/expected_legend_2_by_2.png differ
diff --git a/tests/testdata/control_images/legend/expected_legend_2_by_2/expected_legend_2_by_2_mask.png b/tests/testdata/control_images/legend/expected_legend_2_by_2/expected_legend_2_by_2_mask.png
new file mode 100644
index 0000000..b2f5f23
Binary files /dev/null and b/tests/testdata/control_images/legend/expected_legend_2_by_2/expected_legend_2_by_2_mask.png differ
diff --git a/tests/testdata/control_images/legend/expected_legend_3_by_2/expected_legend_3_by_2.png b/tests/testdata/control_images/legend/expected_legend_3_by_2/expected_legend_3_by_2.png
new file mode 100644
index 0000000..925aa73
Binary files /dev/null and b/tests/testdata/control_images/legend/expected_legend_3_by_2/expected_legend_3_by_2.png differ
diff --git a/tests/testdata/control_images/legend/expected_legend_3_by_2/expected_legend_3_by_2_mask.png b/tests/testdata/control_images/legend/expected_legend_3_by_2/expected_legend_3_by_2_mask.png
new file mode 100644
index 0000000..26a6e24
Binary files /dev/null and b/tests/testdata/control_images/legend/expected_legend_3_by_2/expected_legend_3_by_2_mask.png differ
diff --git a/tests/testdata/control_images/legend/expected_legend_3_by_3/expected_legend_3_by_3.png b/tests/testdata/control_images/legend/expected_legend_3_by_3/expected_legend_3_by_3.png
new file mode 100644
index 0000000..0273549
Binary files /dev/null and b/tests/testdata/control_images/legend/expected_legend_3_by_3/expected_legend_3_by_3.png differ
diff --git a/tests/testdata/control_images/legend/expected_legend_3_by_3/expected_legend_3_by_3_mask.png b/tests/testdata/control_images/legend/expected_legend_3_by_3/expected_legend_3_by_3_mask.png
new file mode 100644
index 0000000..619c13d
Binary files /dev/null and b/tests/testdata/control_images/legend/expected_legend_3_by_3/expected_legend_3_by_3_mask.png differ
diff --git a/tests/testdata/control_images/legend/expected_legend_4_by_2/expected_legend_4_by_2.png b/tests/testdata/control_images/legend/expected_legend_4_by_2/expected_legend_4_by_2.png
new file mode 100644
index 0000000..a3e7fb3
Binary files /dev/null and b/tests/testdata/control_images/legend/expected_legend_4_by_2/expected_legend_4_by_2.png differ
diff --git a/tests/testdata/control_images/legend/expected_legend_4_by_2/expected_legend_4_by_2_mask.png b/tests/testdata/control_images/legend/expected_legend_4_by_2/expected_legend_4_by_2_mask.png
new file mode 100644
index 0000000..5f83169
Binary files /dev/null and b/tests/testdata/control_images/legend/expected_legend_4_by_2/expected_legend_4_by_2_mask.png differ
diff --git a/tests/testdata/control_images/legend/expected_legend_4_by_3/expected_legend_4_by_3.png b/tests/testdata/control_images/legend/expected_legend_4_by_3/expected_legend_4_by_3.png
new file mode 100644
index 0000000..c1e72c6
Binary files /dev/null and b/tests/testdata/control_images/legend/expected_legend_4_by_3/expected_legend_4_by_3.png differ
diff --git a/tests/testdata/control_images/legend/expected_legend_4_by_3/expected_legend_4_by_3_mask.png b/tests/testdata/control_images/legend/expected_legend_4_by_3/expected_legend_4_by_3_mask.png
new file mode 100644
index 0000000..eb17139
Binary files /dev/null and b/tests/testdata/control_images/legend/expected_legend_4_by_3/expected_legend_4_by_3_mask.png differ
diff --git a/tests/testdata/control_images/legend/expected_legend_5_by_2/expected_legend_5_by_2.png b/tests/testdata/control_images/legend/expected_legend_5_by_2/expected_legend_5_by_2.png
new file mode 100644
index 0000000..e61cb2f
Binary files /dev/null and b/tests/testdata/control_images/legend/expected_legend_5_by_2/expected_legend_5_by_2.png differ
diff --git a/tests/testdata/control_images/legend/expected_legend_5_by_2/expected_legend_5_by_2_mask.png b/tests/testdata/control_images/legend/expected_legend_5_by_2/expected_legend_5_by_2_mask.png
new file mode 100644
index 0000000..b7c9aa4
Binary files /dev/null and b/tests/testdata/control_images/legend/expected_legend_5_by_2/expected_legend_5_by_2_mask.png differ
diff --git a/tests/testdata/control_images/legend/expected_legend_5_by_3/expected_legend_5_by_3.png b/tests/testdata/control_images/legend/expected_legend_5_by_3/expected_legend_5_by_3.png
new file mode 100644
index 0000000..56f1db3
Binary files /dev/null and b/tests/testdata/control_images/legend/expected_legend_5_by_3/expected_legend_5_by_3.png differ
diff --git a/tests/testdata/control_images/legend/expected_legend_5_by_3/expected_legend_5_by_3_mask.png b/tests/testdata/control_images/legend/expected_legend_5_by_3/expected_legend_5_by_3_mask.png
new file mode 100644
index 0000000..8fabd8d
Binary files /dev/null and b/tests/testdata/control_images/legend/expected_legend_5_by_3/expected_legend_5_by_3_mask.png differ
diff --git a/tests/testdata/control_images/legend/expected_legend_6_by_3/expected_legend_6_by_3.png b/tests/testdata/control_images/legend/expected_legend_6_by_3/expected_legend_6_by_3.png
new file mode 100644
index 0000000..26155b3
Binary files /dev/null and b/tests/testdata/control_images/legend/expected_legend_6_by_3/expected_legend_6_by_3.png differ
diff --git a/tests/testdata/control_images/legend/expected_legend_6_by_3/expected_legend_6_by_3_mask.png b/tests/testdata/control_images/legend/expected_legend_6_by_3/expected_legend_6_by_3_mask.png
new file mode 100644
index 0000000..0228bfc
Binary files /dev/null and b/tests/testdata/control_images/legend/expected_legend_6_by_3/expected_legend_6_by_3_mask.png differ
diff --git a/tests/testdata/control_images/legend/expected_legend_7_by_3/expected_legend_7_by_3.png b/tests/testdata/control_images/legend/expected_legend_7_by_3/expected_legend_7_by_3.png
new file mode 100644
index 0000000..bae0e2f
Binary files /dev/null and b/tests/testdata/control_images/legend/expected_legend_7_by_3/expected_legend_7_by_3.png differ
diff --git a/tests/testdata/control_images/legend/expected_legend_7_by_3/expected_legend_7_by_3_mask.png b/tests/testdata/control_images/legend/expected_legend_7_by_3/expected_legend_7_by_3_mask.png
new file mode 100644
index 0000000..63ef7e9
Binary files /dev/null and b/tests/testdata/control_images/legend/expected_legend_7_by_3/expected_legend_7_by_3_mask.png differ
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/qgis.git
More information about the Pkg-grass-devel
mailing list