Last active
November 2, 2016 00:19
-
-
Save dakcarto/8a6a45737523efce13c7f1521ff85c8b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From d527c8571c4a7e9ed2a671126faa0284ff436019 Mon Sep 17 00:00:00 2001 | |
From: Matteo Ghetta <[email protected]> | |
Date: Mon, 10 Oct 2016 10:48:27 +0200 | |
Subject: [PATCH] Missing import fixed for R algorithm | |
--- | |
python/plugins/processing/algs/r/RUtils.py | 2 +- | |
1 file changed, 1 insertion(+), 1 deletion(-) | |
diff --git a/python/plugins/processing/algs/r/RUtils.py b/python/plugins/processing/algs/r/RUtils.py | |
index ddfe701..8c5612c 100644 | |
--- a/python/plugins/processing/algs/r/RUtils.py | |
+++ b/python/plugins/processing/algs/r/RUtils.py | |
@@ -33,7 +33,7 @@ import subprocess | |
from PyQt4.QtCore import QSettings, QCoreApplication | |
from processing.core.ProcessingConfig import ProcessingConfig | |
from processing.core.ProcessingLog import ProcessingLog | |
-from processing.tools.system import userFolder, isWindows, mkdir | |
+from processing.tools.system import userFolder, isWindows, mkdir, getTempFilenameInTempFolder | |
class RUtils: | |
-- | |
2.8.1 | |
From 6bf74b437646c480595ead6765102a3f70825b4f Mon Sep 17 00:00:00 2001 | |
From: "Juergen E. Fischer" <[email protected]> | |
Date: Sat, 22 Oct 2016 21:54:28 +0200 | |
Subject: [PATCH] fix #15744 (followup dbf6169) | |
--- | |
python/plugins/processing/algs/qgis/Eliminate.py | 3 --- | |
1 file changed, 3 deletions(-) | |
diff --git a/python/plugins/processing/algs/qgis/Eliminate.py b/python/plugins/processing/algs/qgis/Eliminate.py | |
index 6bc6352..a975ee6 100644 | |
--- a/python/plugins/processing/algs/qgis/Eliminate.py | |
+++ b/python/plugins/processing/algs/qgis/Eliminate.py | |
@@ -54,9 +54,6 @@ class Eliminate(GeoAlgorithm): | |
MODE_SMALLEST_AREA = 1 | |
MODE_BOUNDARY = 2 | |
- def getIcon(self): | |
- return QIcon(os.path.join(pluginPath, 'images', 'ftools', 'eliminate.png')) | |
- | |
def defineCharacteristics(self): | |
self.name, self.i18n_name = self.trAlgorithm('Eliminate sliver polygons') | |
self.group, self.i18n_group = self.trAlgorithm('Vector geometry tools') | |
-- | |
2.8.1 | |
From 36db42ebb4e2e338ae56a3ade68083e06d70cb7a Mon Sep 17 00:00:00 2001 | |
From: rldhont <[email protected]> | |
Date: Tue, 25 Oct 2016 13:40:10 +0200 | |
Subject: [PATCH] [BUGFIX][QGIS Server] Do not cache invalid layer | |
After readLayerXml, the server stored layers in cache and in registry without verifying validity. | |
--- | |
src/server/qgshostedrdsbuilder.cpp | 2 +- | |
src/server/qgsserverprojectparser.cpp | 4 ++++ | |
2 files changed, 5 insertions(+), 1 deletion(-) | |
diff --git a/src/server/qgshostedrdsbuilder.cpp b/src/server/qgshostedrdsbuilder.cpp | |
index acba4e6..72b236d 100644 | |
--- a/src/server/qgshostedrdsbuilder.cpp | |
+++ b/src/server/qgshostedrdsbuilder.cpp | |
@@ -61,7 +61,7 @@ QgsMapLayer* QgsHostedRDSBuilder::createMapLayer( const QDomElement& elem, | |
{ | |
rl = qobject_cast<QgsRasterLayer*>( QgsMSLayerCache::instance()->searchLayer( uri, layerName ) ); | |
} | |
- if ( !rl ) | |
+ if ( !rl || !rl->isValid() ) | |
{ | |
QgsDebugMsg( "hostedrds layer not in cache, so create and insert it" ); | |
rl = new QgsRasterLayer( uri, layerNameFromUri( uri ) ); | |
diff --git a/src/server/qgsserverprojectparser.cpp b/src/server/qgsserverprojectparser.cpp | |
index f3807a0..89361db 100644 | |
--- a/src/server/qgsserverprojectparser.cpp | |
+++ b/src/server/qgsserverprojectparser.cpp | |
@@ -278,6 +278,10 @@ QgsMapLayer* QgsServerProjectParser::createLayerFromElement( const QDomElement& | |
layer->readLayerXML( const_cast<QDomElement&>( elem ) ); //should be changed to const in QgsMapLayer | |
//layer->setLayerName( layerName( elem ) ); | |
+ if ( !layer->isValid() ) | |
+ { | |
+ return nullptr; | |
+ } | |
// Insert layer in registry and cache before addValueRelationLayersForLayer | |
if ( !QgsMapLayerRegistry::instance()->mapLayer( id ) ) | |
QgsMapLayerRegistry::instance()->addMapLayer( layer, false, false ); | |
-- | |
2.8.1 | |
From 2a13dbff39ca63f9a8c9c5c653ac08ab245dcd5d Mon Sep 17 00:00:00 2001 | |
From: =?UTF-8?q?Germ=C3=A1n?= <[email protected]> | |
Date: Tue, 25 Oct 2016 20:57:22 -0500 | |
Subject: [PATCH] Import vector because it is used in line 95. | |
It seems that line 95 was added by a cherry pick commit. | |
--- | |
python/plugins/processing/algs/qgis/Eliminate.py | 2 +- | |
1 file changed, 1 insertion(+), 1 deletion(-) | |
diff --git a/python/plugins/processing/algs/qgis/Eliminate.py b/python/plugins/processing/algs/qgis/Eliminate.py | |
index a975ee6..63dd595 100644 | |
--- a/python/plugins/processing/algs/qgis/Eliminate.py | |
+++ b/python/plugins/processing/algs/qgis/Eliminate.py | |
@@ -37,7 +37,7 @@ from processing.core.parameters import ParameterTableField | |
from processing.core.parameters import ParameterString | |
from processing.core.parameters import ParameterSelection | |
from processing.core.outputs import OutputVector | |
-from processing.tools import dataobjects | |
+from processing.tools import dataobjects, vector | |
class Eliminate(GeoAlgorithm): | |
-- | |
2.8.1 | |
From fa7491f28168d12887a93bb116026e591d4729c2 Mon Sep 17 00:00:00 2001 | |
From: Marco Hugentobler <[email protected]> | |
Date: Thu, 27 Oct 2016 09:18:11 +0200 | |
Subject: [PATCH] Fix python bindings of QgsGeometryRubberBand | |
--- | |
python/gui/qgsgeometryrubberband.sip | 2 +- | |
1 file changed, 1 insertion(+), 1 deletion(-) | |
diff --git a/python/gui/qgsgeometryrubberband.sip b/python/gui/qgsgeometryrubberband.sip | |
index 4d8cc7a..3cb22a7 100644 | |
--- a/python/gui/qgsgeometryrubberband.sip | |
+++ b/python/gui/qgsgeometryrubberband.sip | |
@@ -54,7 +54,7 @@ class QgsGeometryRubberBand: QgsMapCanvasItem | |
~QgsGeometryRubberBand(); | |
/** Sets geometry (takes ownership). Geometry is expected to be in map coordinates */ | |
- void setGeometry( QgsAbstractGeometryV2* geom ); | |
+ void setGeometry( QgsAbstractGeometryV2* geom /Transfer/ ); | |
/** Returns a pointer to the geometry*/ | |
const QgsAbstractGeometryV2* geometry(); | |
/** Moves vertex to new position (in map coordinates)*/ | |
-- | |
2.8.1 | |
From 68cbf0701206a156b71500b75e10aff8cee93f86 Mon Sep 17 00:00:00 2001 | |
From: Nyall Dawson <[email protected]> | |
Date: Fri, 28 Oct 2016 07:58:58 +1000 | |
Subject: [PATCH] Speed up point layer rendering - don't calculate unused label | |
obstacles | |
Cuts render time by ~60%. Fix #15752. | |
(cherry-picked from 5798a82c8011ea7f44a1ed1d55ef0719786e8056) | |
--- | |
src/core/qgsvectorlayerrenderer.cpp | 2 +- | |
1 file changed, 1 insertion(+), 1 deletion(-) | |
diff --git a/src/core/qgsvectorlayerrenderer.cpp b/src/core/qgsvectorlayerrenderer.cpp | |
index 6c7e477..126869b 100644 | |
--- a/src/core/qgsvectorlayerrenderer.cpp | |
+++ b/src/core/qgsvectorlayerrenderer.cpp | |
@@ -333,7 +333,7 @@ void QgsVectorLayerRenderer::drawRendererV2( QgsFeatureIterator& fit ) | |
} | |
} | |
// new labeling engine | |
- if ( mContext.labelingEngineV2() ) | |
+ if ( mContext.labelingEngineV2() && ( mLabelProvider || mDiagramProvider ) ) | |
{ | |
QScopedPointer<QgsGeometry> obstacleGeometry; | |
QgsSymbolV2List symbols = mRendererV2->originalSymbolsForFeature( fet, mContext ); | |
-- | |
2.8.1 | |
From 5f01a87278eaca8bda625f6e1d52bf3cdf582669 Mon Sep 17 00:00:00 2001 | |
From: Nyall Dawson <[email protected]> | |
Date: Fri, 28 Oct 2016 08:25:40 +1000 | |
Subject: [PATCH] Optimise QgsAbstractGeometry | |
Make nCoordinates virtual, and provide shortcuts for some | |
geometry types. The base method which calls coordinateSequence() | |
is quite slow in certain circumstances. | |
Speeds up rendering point layers by ~25%, also likely to | |
speed up lots of geometry heavy operations throughout QGIS | |
Refs #15752 | |
(cherry-picked from 49432a84683e99bdc2592e7ae808e81fa3bc40cd) | |
--- | |
python/core/geometry/qgsabstractgeometryv2.sip | 2 +- | |
python/core/geometry/qgscurvepolygonv2.sip | 1 + | |
python/core/geometry/qgsgeometrycollectionv2.sip | 1 + | |
python/core/geometry/qgslinestringv2.sip | 1 + | |
python/core/geometry/qgsmultipointv2.sip | 1 + | |
python/core/geometry/qgspointv2.sip | 1 + | |
src/core/geometry/qgsabstractgeometryv2.h | 2 +- | |
src/core/geometry/qgscurvepolygonv2.cpp | 21 +++++++++++++++++++++ | |
src/core/geometry/qgscurvepolygonv2.h | 1 + | |
src/core/geometry/qgsgeometrycollectionv2.cpp | 16 ++++++++++++++++ | |
src/core/geometry/qgsgeometrycollectionv2.h | 2 ++ | |
src/core/geometry/qgslinestringv2.h | 1 + | |
src/core/geometry/qgsmultipointv2.h | 1 + | |
src/core/geometry/qgspointv2.h | 1 + | |
14 files changed, 50 insertions(+), 2 deletions(-) | |
diff --git a/python/core/geometry/qgsabstractgeometryv2.sip b/python/core/geometry/qgsabstractgeometryv2.sip | |
index 2264423..1840fd9 100644 | |
--- a/python/core/geometry/qgsabstractgeometryv2.sip | |
+++ b/python/core/geometry/qgsabstractgeometryv2.sip | |
@@ -227,7 +227,7 @@ class QgsAbstractGeometryV2 | |
/** Returns the number of nodes contained in the geometry | |
*/ | |
- int nCoordinates() const; | |
+ virtual int nCoordinates() const; | |
/** Returns the point corresponding to a specified vertex id | |
*/ | |
diff --git a/python/core/geometry/qgscurvepolygonv2.sip b/python/core/geometry/qgscurvepolygonv2.sip | |
index 4843e16..268b114 100644 | |
--- a/python/core/geometry/qgscurvepolygonv2.sip | |
+++ b/python/core/geometry/qgscurvepolygonv2.sip | |
@@ -65,6 +65,7 @@ class QgsCurvePolygonV2: public QgsSurfaceV2 | |
virtual bool deleteVertex( QgsVertexId position ); | |
virtual QList< QList< QList< QgsPointV2 > > > coordinateSequence() const; | |
+ virtual int nCoordinates() const; | |
double closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const; | |
bool nextVertex( QgsVertexId& id, QgsPointV2& vertex ) const; | |
diff --git a/python/core/geometry/qgsgeometrycollectionv2.sip b/python/core/geometry/qgsgeometrycollectionv2.sip | |
index 87c2f0e..6930477 100644 | |
--- a/python/core/geometry/qgsgeometrycollectionv2.sip | |
+++ b/python/core/geometry/qgsgeometrycollectionv2.sip | |
@@ -69,6 +69,7 @@ class QgsGeometryCollectionV2: public QgsAbstractGeometryV2 | |
virtual QgsRectangle boundingBox() const; | |
virtual QList< QList< QList< QgsPointV2 > > > coordinateSequence() const; | |
+ virtual int nCoordinates() const; | |
virtual double closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const; | |
bool nextVertex( QgsVertexId& id, QgsPointV2& vertex ) const; | |
diff --git a/python/core/geometry/qgslinestringv2.sip b/python/core/geometry/qgslinestringv2.sip | |
index 319a811..5257225 100644 | |
--- a/python/core/geometry/qgslinestringv2.sip | |
+++ b/python/core/geometry/qgslinestringv2.sip | |
@@ -134,6 +134,7 @@ class QgsLineStringV2: public QgsCurveV2 | |
virtual QgsLineStringV2* curveToLine() const /Factory/; | |
int numPoints() const; | |
+ virtual int nCoordinates() const; | |
void points( QList<QgsPointV2>& pt ) const; | |
void draw( QPainter& p ) const; | |
diff --git a/python/core/geometry/qgsmultipointv2.sip b/python/core/geometry/qgsmultipointv2.sip | |
index 2838451..beec306 100644 | |
--- a/python/core/geometry/qgsmultipointv2.sip | |
+++ b/python/core/geometry/qgsmultipointv2.sip | |
@@ -16,6 +16,7 @@ class QgsMultiPointV2: public QgsGeometryCollectionV2 | |
QDomElement asGML3( QDomDocument& doc, int precision = 17, const QString& ns = "gml" ) const; | |
QString asJSON( int precision = 17 ) const; | |
+ virtual int nCoordinates() const; | |
/** Adds a geometry and takes ownership. Returns true in case of success*/ | |
virtual bool addGeometry( QgsAbstractGeometryV2* g ); | |
diff --git a/python/core/geometry/qgspointv2.sip b/python/core/geometry/qgspointv2.sip | |
index 13d3f48..a92278f 100644 | |
--- a/python/core/geometry/qgspointv2.sip | |
+++ b/python/core/geometry/qgspointv2.sip | |
@@ -156,6 +156,7 @@ class QgsPointV2: public QgsAbstractGeometryV2 | |
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform ); | |
void transform( const QTransform& t ); | |
virtual QList< QList< QList< QgsPointV2 > > > coordinateSequence() const; | |
+ virtual int nCoordinates() const; | |
//low-level editing | |
virtual bool insertVertex( QgsVertexId position, const QgsPointV2& vertex ); | |
diff --git a/src/core/geometry/qgsabstractgeometryv2.h b/src/core/geometry/qgsabstractgeometryv2.h | |
index f5493f9..e6d4984 100644 | |
--- a/src/core/geometry/qgsabstractgeometryv2.h | |
+++ b/src/core/geometry/qgsabstractgeometryv2.h | |
@@ -213,7 +213,7 @@ class CORE_EXPORT QgsAbstractGeometryV2 | |
/** Returns the number of nodes contained in the geometry | |
*/ | |
- int nCoordinates() const; | |
+ virtual int nCoordinates() const; | |
/** Returns the point corresponding to a specified vertex id | |
*/ | |
diff --git a/src/core/geometry/qgscurvepolygonv2.cpp b/src/core/geometry/qgscurvepolygonv2.cpp | |
index 0393dbc..b4abde2 100644 | |
--- a/src/core/geometry/qgscurvepolygonv2.cpp | |
+++ b/src/core/geometry/qgscurvepolygonv2.cpp | |
@@ -607,6 +607,27 @@ QgsCoordinateSequenceV2 QgsCurvePolygonV2::coordinateSequence() const | |
return mCoordinateSequence; | |
} | |
+int QgsCurvePolygonV2::nCoordinates() const | |
+{ | |
+ if ( !mCoordinateSequence.isEmpty() ) | |
+ return QgsAbstractGeometryV2::nCoordinates(); | |
+ | |
+ int count = 0; | |
+ | |
+ if ( mExteriorRing ) | |
+ { | |
+ count += mExteriorRing->nCoordinates(); | |
+ } | |
+ | |
+ QList<QgsCurveV2*>::const_iterator it = mInteriorRings.constBegin(); | |
+ for ( ; it != mInteriorRings.constEnd(); ++it ) | |
+ { | |
+ count += ( *it )->nCoordinates(); | |
+ } | |
+ | |
+ return count; | |
+} | |
+ | |
double QgsCurvePolygonV2::closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const | |
{ | |
if ( !mExteriorRing ) | |
diff --git a/src/core/geometry/qgscurvepolygonv2.h b/src/core/geometry/qgscurvepolygonv2.h | |
index c644d37..e8c4e94 100644 | |
--- a/src/core/geometry/qgscurvepolygonv2.h | |
+++ b/src/core/geometry/qgscurvepolygonv2.h | |
@@ -91,6 +91,7 @@ class CORE_EXPORT QgsCurvePolygonV2: public QgsSurfaceV2 | |
virtual bool deleteVertex( QgsVertexId position ) override; | |
virtual QgsCoordinateSequenceV2 coordinateSequence() const override; | |
+ virtual int nCoordinates() const override; | |
double closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const override; | |
bool nextVertex( QgsVertexId& id, QgsPointV2& vertex ) const override; | |
diff --git a/src/core/geometry/qgsgeometrycollectionv2.cpp b/src/core/geometry/qgsgeometrycollectionv2.cpp | |
index 2cec10c..f545d18 100644 | |
--- a/src/core/geometry/qgsgeometrycollectionv2.cpp | |
+++ b/src/core/geometry/qgsgeometrycollectionv2.cpp | |
@@ -361,6 +361,22 @@ QgsCoordinateSequenceV2 QgsGeometryCollectionV2::coordinateSequence() const | |
return mCoordinateSequence; | |
} | |
+int QgsGeometryCollectionV2::nCoordinates() const | |
+{ | |
+ if ( !mCoordinateSequence.isEmpty() ) | |
+ return QgsAbstractGeometryV2::nCoordinates(); | |
+ | |
+ int count = 0; | |
+ | |
+ QVector< QgsAbstractGeometryV2* >::const_iterator geomIt = mGeometries.constBegin(); | |
+ for ( ; geomIt != mGeometries.constEnd(); ++geomIt ) | |
+ { | |
+ count += ( *geomIt )->nCoordinates(); | |
+ } | |
+ | |
+ return count; | |
+} | |
+ | |
double QgsGeometryCollectionV2::closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const | |
{ | |
return QgsGeometryUtils::closestSegmentFromComponents( mGeometries, QgsGeometryUtils::PART, pt, segmentPt, vertexAfter, leftOf, epsilon ); | |
diff --git a/src/core/geometry/qgsgeometrycollectionv2.h b/src/core/geometry/qgsgeometrycollectionv2.h | |
index 12c0c48..77e7e86 100644 | |
--- a/src/core/geometry/qgsgeometrycollectionv2.h | |
+++ b/src/core/geometry/qgsgeometrycollectionv2.h | |
@@ -93,6 +93,8 @@ class CORE_EXPORT QgsGeometryCollectionV2: public QgsAbstractGeometryV2 | |
virtual QgsRectangle boundingBox() const override; | |
virtual QgsCoordinateSequenceV2 coordinateSequence() const override; | |
+ virtual int nCoordinates() const override; | |
+ | |
virtual double closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const override; | |
bool nextVertex( QgsVertexId& id, QgsPointV2& vertex ) const override; | |
diff --git a/src/core/geometry/qgslinestringv2.h b/src/core/geometry/qgslinestringv2.h | |
index 16677d5..f43a915 100644 | |
--- a/src/core/geometry/qgslinestringv2.h | |
+++ b/src/core/geometry/qgslinestringv2.h | |
@@ -159,6 +159,7 @@ class CORE_EXPORT QgsLineStringV2: public QgsCurveV2 | |
virtual QgsLineStringV2* curveToLine() const override; | |
int numPoints() const override; | |
+ virtual int nCoordinates() const override { return mX.size(); } | |
void points( QgsPointSequenceV2 &pt ) const override; | |
void draw( QPainter& p ) const override; | |
diff --git a/src/core/geometry/qgsmultipointv2.h b/src/core/geometry/qgsmultipointv2.h | |
index 977a2e7..67e5566 100644 | |
--- a/src/core/geometry/qgsmultipointv2.h | |
+++ b/src/core/geometry/qgsmultipointv2.h | |
@@ -39,6 +39,7 @@ class CORE_EXPORT QgsMultiPointV2: public QgsGeometryCollectionV2 | |
QDomElement asGML3( QDomDocument& doc, int precision = 17, const QString& ns = "gml" ) const override; | |
QString asJSON( int precision = 17 ) const override; | |
+ virtual int nCoordinates() const override { return mGeometries.size(); } | |
/** Adds a geometry and takes ownership. Returns true in case of success*/ | |
virtual bool addGeometry( QgsAbstractGeometryV2* g ) override; | |
diff --git a/src/core/geometry/qgspointv2.h b/src/core/geometry/qgspointv2.h | |
index 2ed1e64..ac2900c 100644 | |
--- a/src/core/geometry/qgspointv2.h | |
+++ b/src/core/geometry/qgspointv2.h | |
@@ -168,6 +168,7 @@ class CORE_EXPORT QgsPointV2: public QgsAbstractGeometryV2 | |
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform ) override; | |
void transform( const QTransform& t ) override; | |
virtual QgsCoordinateSequenceV2 coordinateSequence() const override; | |
+ virtual int nCoordinates() const override { return 1; } | |
//low-level editing | |
virtual bool insertVertex( QgsVertexId position, const QgsPointV2& vertex ) override { Q_UNUSED( position ); Q_UNUSED( vertex ); return false; } | |
-- | |
2.8.1 | |
From c93d56a94c5c5696e5b5f4285cb03f591020bebd Mon Sep 17 00:00:00 2001 | |
From: Nyall Dawson <[email protected]> | |
Date: Fri, 28 Oct 2016 08:36:54 +1000 | |
Subject: [PATCH] Use QgsExpressionContextScope::addVariable instead of | |
setVariable | |
...where appropriate (ie, read-only, non user set variables). | |
It's much faster as it doesn't need to check whether the | |
variable already exists. | |
Results in ~10% improvement in rendering speed. Refs #15752. | |
(cherry-picked from 85897885445c7383938ac89318d12a7d37024bb4) | |
--- | |
src/app/composer/qgsattributeselectiondialog.cpp | 2 +- | |
src/app/qgsattributetabledialog.cpp | 4 ++-- | |
src/app/qgsfieldcalculator.cpp | 4 ++-- | |
src/core/composer/qgscomposerattributetablev2.cpp | 2 +- | |
src/core/composer/qgscomposermapgrid.cpp | 8 ++++---- | |
src/core/qgsconditionalstyle.cpp | 2 +- | |
src/core/qgsexpression.cpp | 4 ++-- | |
src/core/qgsexpressioncontext.cpp | 4 ++-- | |
src/core/symbology-ng/qgssymbolv2.cpp | 10 +++++----- | |
src/gui/attributetable/qgsfieldconditionalformatwidget.cpp | 2 +- | |
src/gui/symbology-ng/qgssymbollayerv2widget.cpp | 2 +- | |
11 files changed, 22 insertions(+), 22 deletions(-) | |
diff --git a/src/app/composer/qgsattributeselectiondialog.cpp b/src/app/composer/qgsattributeselectiondialog.cpp | |
index 0e4fdc5..7c360de 100644 | |
--- a/src/app/composer/qgsattributeselectiondialog.cpp | |
+++ b/src/app/composer/qgsattributeselectiondialog.cpp | |
@@ -107,7 +107,7 @@ static QgsExpressionContext _getExpressionContext( const void* context ) | |
} | |
QScopedPointer< QgsExpressionContext > expContext( object->createExpressionContext() ); | |
- expContext->lastScope()->setVariable( "row_number", 1 ); | |
+ expContext->lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QString( "row_number" ), 1, true ) ); | |
expContext->setHighlightedVariables( QStringList() << "row_number" ); | |
return QgsExpressionContext( *expContext ); | |
} | |
diff --git a/src/app/qgsattributetabledialog.cpp b/src/app/qgsattributetabledialog.cpp | |
index 8a1684b..1670cd3 100644 | |
--- a/src/app/qgsattributetabledialog.cpp | |
+++ b/src/app/qgsattributetabledialog.cpp | |
@@ -55,7 +55,7 @@ static QgsExpressionContext _getExpressionContext( const void* context ) | |
if ( layer ) | |
expContext << QgsExpressionContextUtils::layerScope( layer ); | |
- expContext.lastScope()->setVariable( "row_number", 1 ); | |
+ expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QString( "row_number" ), 1, true ) ); | |
expContext.setHighlightedVariables( QStringList() << "row_number" ); | |
@@ -393,7 +393,7 @@ void QgsAttributeTableDialog::runFieldCalculation( QgsVectorLayer* layer, const | |
} | |
context.setFeature( feature ); | |
- context.lastScope()->setVariable( QString( "row_number" ), rownum ); | |
+ context.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QString( "row_number" ), rownum, true ) ); | |
QVariant value = exp.evaluate( &context ); | |
fld.convertCompatible( value ); | |
diff --git a/src/app/qgsfieldcalculator.cpp b/src/app/qgsfieldcalculator.cpp | |
index f8dc400..b26ab2a 100644 | |
--- a/src/app/qgsfieldcalculator.cpp | |
+++ b/src/app/qgsfieldcalculator.cpp | |
@@ -43,7 +43,7 @@ QgsFieldCalculator::QgsFieldCalculator( QgsVectorLayer* vl, QWidget* parent ) | |
<< QgsExpressionContextUtils::projectScope() | |
<< QgsExpressionContextUtils::layerScope( mVectorLayer ); | |
- expContext.lastScope()->setVariable( "row_number", 1 ); | |
+ expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QString( "row_number" ), 1, true ) ); | |
expContext.setHighlightedVariables( QStringList() << "row_number" ); | |
builder->setLayer( vl ); | |
@@ -281,7 +281,7 @@ void QgsFieldCalculator::accept() | |
while ( fit.nextFeature( feature ) ) | |
{ | |
expContext.setFeature( feature ); | |
- expContext.lastScope()->setVariable( QString( "row_number" ), rownum ); | |
+ expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QString( "row_number" ), rownum, true ) ); | |
QVariant value = exp.evaluate( &expContext ); | |
if ( exp.hasEvalError() ) | |
diff --git a/src/core/composer/qgscomposerattributetablev2.cpp b/src/core/composer/qgscomposerattributetablev2.cpp | |
index 2b58610..e88677b 100644 | |
--- a/src/core/composer/qgscomposerattributetablev2.cpp | |
+++ b/src/core/composer/qgscomposerattributetablev2.cpp | |
@@ -503,7 +503,7 @@ bool QgsComposerAttributeTableV2::getTableContents( QgsComposerTableContents &co | |
{ | |
// Lets assume it's an expression | |
QgsExpression* expression = new QgsExpression(( *columnIt )->attribute() ); | |
- context->lastScope()->setVariable( QString( "row_number" ), counter + 1 ); | |
+ context->lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QString( "row_number" ), counter + 1, true ) ); | |
expression->prepare( context.data() ); | |
QVariant value = expression->evaluate( context.data() ); | |
currentRow << value; | |
diff --git a/src/core/composer/qgscomposermapgrid.cpp b/src/core/composer/qgscomposermapgrid.cpp | |
index 9f89f73..c1911a8 100644 | |
--- a/src/core/composer/qgscomposermapgrid.cpp | |
+++ b/src/core/composer/qgscomposermapgrid.cpp | |
@@ -1502,8 +1502,8 @@ QString QgsComposerMapGrid::gridAnnotationString( double value, QgsComposerMapGr | |
} | |
else if ( mGridAnnotationFormat == CustomFormat ) | |
{ | |
- expressionContext.lastScope()->setVariable( "grid_number", value ); | |
- expressionContext.lastScope()->setVariable( "grid_axis", coord == QgsComposerMapGrid::Longitude ? "x" : "y" ); | |
+ expressionContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QString( "grid_number" ), value, true ) ); | |
+ expressionContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QString( "grid_axis" ), coord == QgsComposerMapGrid::Longitude ? "x" : "y", true ) ); | |
if ( !mGridAnnotationExpression.data() ) | |
{ | |
mGridAnnotationExpression.reset( new QgsExpression( mGridAnnotationExpressionString ) ); | |
@@ -2238,8 +2238,8 @@ QgsExpressionContext* QgsComposerMapGrid::createExpressionContext() const | |
{ | |
QgsExpressionContext* context = QgsComposerObject::createExpressionContext(); | |
context->appendScope( new QgsExpressionContextScope( tr( "Grid" ) ) ); | |
- context->lastScope()->setVariable( "grid_number", 0 ); | |
- context->lastScope()->setVariable( "grid_axis", "x" ); | |
+ context->lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QString( "grid_number" ), 0, true ) ); | |
+ context->lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QString( "grid_axis" ), "x", true ) ); | |
context->setHighlightedVariables( QStringList() << "grid_number" << "grid_axis" ); | |
return context; | |
} | |
diff --git a/src/core/qgsconditionalstyle.cpp b/src/core/qgsconditionalstyle.cpp | |
index 3cfa6b5..169af65 100644 | |
--- a/src/core/qgsconditionalstyle.cpp | |
+++ b/src/core/qgsconditionalstyle.cpp | |
@@ -195,7 +195,7 @@ void QgsConditionalStyle::setSymbol( QgsSymbolV2* value ) | |
bool QgsConditionalStyle::matches( const QVariant& value, QgsExpressionContext& context ) const | |
{ | |
QgsExpression exp( mRule ); | |
- context.lastScope()->setVariable( "value", value ); | |
+ context.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QString( "value" ), value, true ) ); | |
return exp.evaluate( &context ).toBool(); | |
} | |
diff --git a/src/core/qgsexpression.cpp b/src/core/qgsexpression.cpp | |
index 2b2c98a..95f9ddf 100644 | |
--- a/src/core/qgsexpression.cpp | |
+++ b/src/core/qgsexpression.cpp | |
@@ -1027,7 +1027,7 @@ static QVariant fcnFeature( const QVariantList&, const QgsExpressionContext* con | |
if ( !context ) | |
return QVariant(); | |
- return context->variable( QgsExpressionContext::EXPR_FEATURE ); | |
+ return context->feature(); | |
} | |
static QVariant fcnAttribute( const QVariantList& values, const QgsExpressionContext*, QgsExpression* parent ) | |
{ | |
@@ -4313,7 +4313,7 @@ QVariant QgsExpression::NodeColumnRef::eval( QgsExpression *parent, const QgsExp | |
if ( context && context->hasVariable( QgsExpressionContext::EXPR_FEATURE ) ) | |
{ | |
- QgsFeature feature = qvariant_cast<QgsFeature>( context->variable( QgsExpressionContext::EXPR_FEATURE ) ); | |
+ QgsFeature feature = context->feature(); | |
if ( index >= 0 ) | |
return feature.attribute( index ); | |
else | |
diff --git a/src/core/qgsexpressioncontext.cpp b/src/core/qgsexpressioncontext.cpp | |
index c5512cc..501fc12 100644 | |
--- a/src/core/qgsexpressioncontext.cpp | |
+++ b/src/core/qgsexpressioncontext.cpp | |
@@ -191,12 +191,12 @@ void QgsExpressionContextScope::addFunction( const QString& name, QgsScopedExpre | |
void QgsExpressionContextScope::setFeature( const QgsFeature &feature ) | |
{ | |
- setVariable( QgsExpressionContext::EXPR_FEATURE, QVariant::fromValue( feature ) ); | |
+ addVariable( StaticVariable( QgsExpressionContext::EXPR_FEATURE, QVariant::fromValue( feature ), true ) ); | |
} | |
void QgsExpressionContextScope::setFields( const QgsFields &fields ) | |
{ | |
- setVariable( QgsExpressionContext::EXPR_FIELDS, QVariant::fromValue( fields ) ); | |
+ addVariable( StaticVariable( QgsExpressionContext::EXPR_FIELDS, QVariant::fromValue( fields ), true ) ); | |
} | |
diff --git a/src/core/symbology-ng/qgssymbolv2.cpp b/src/core/symbology-ng/qgssymbolv2.cpp | |
index aa3a84b..70cd0a1 100644 | |
--- a/src/core/symbology-ng/qgssymbolv2.cpp | |
+++ b/src/core/symbology-ng/qgssymbolv2.cpp | |
@@ -738,8 +738,8 @@ void QgsSymbolV2::renderFeature( const QgsFeature& feature, QgsRenderContext& co | |
{ | |
context.expressionContext().appendScope( mSymbolRenderContext->expressionContextScope() ); | |
QgsExpressionContextUtils::updateSymbolScope( this, mSymbolRenderContext->expressionContextScope() ); | |
- mSymbolRenderContext->expressionContextScope()->setVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_COUNT, segmentizedGeometry->geometry()->partCount() ); | |
- mSymbolRenderContext->expressionContextScope()->setVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, 1 ); | |
+ mSymbolRenderContext->expressionContextScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_COUNT, segmentizedGeometry->geometryPartCount(), true ) ); | |
+ mSymbolRenderContext->expressionContextScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, 1, true ) ); | |
} | |
switch ( QgsWKBTypes::flatType( segmentizedGeometry->geometry()->wkbType() ) ) | |
@@ -806,7 +806,7 @@ void QgsSymbolV2::renderFeature( const QgsFeature& feature, QgsRenderContext& co | |
for ( int i = 0; i < mp->numGeometries(); ++i ) | |
{ | |
- mSymbolRenderContext->expressionContextScope()->setVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, i + 1 ); | |
+ mSymbolRenderContext->expressionContextScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, i + 1, true ) ); | |
const QgsPointV2* point = static_cast< const QgsPointV2* >( mp->geometryN( i ) ); | |
_getPoint( pt, context, point ); | |
@@ -836,7 +836,7 @@ void QgsSymbolV2::renderFeature( const QgsFeature& feature, QgsRenderContext& co | |
for ( unsigned int i = 0; i < num && wkbPtr; ++i ) | |
{ | |
- mSymbolRenderContext->expressionContextScope()->setVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, i + 1 ); | |
+ mSymbolRenderContext->expressionContextScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, i + 1, true ) ); | |
if ( geomCollection ) | |
{ | |
@@ -870,7 +870,7 @@ void QgsSymbolV2::renderFeature( const QgsFeature& feature, QgsRenderContext& co | |
for ( unsigned int i = 0; i < num && wkbPtr; ++i ) | |
{ | |
- mSymbolRenderContext->expressionContextScope()->setVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, i + 1 ); | |
+ mSymbolRenderContext->expressionContextScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, i + 1, true ) ); | |
if ( geomCollection ) | |
{ | |
diff --git a/src/gui/attributetable/qgsfieldconditionalformatwidget.cpp b/src/gui/attributetable/qgsfieldconditionalformatwidget.cpp | |
index ffc158e..ded4665 100644 | |
--- a/src/gui/attributetable/qgsfieldconditionalformatwidget.cpp | |
+++ b/src/gui/attributetable/qgsfieldconditionalformatwidget.cpp | |
@@ -63,7 +63,7 @@ void QgsFieldConditionalFormatWidget::setExpression() | |
context << QgsExpressionContextUtils::globalScope() | |
<< QgsExpressionContextUtils::projectScope() | |
<< QgsExpressionContextUtils::layerScope( mLayer ); | |
- context.lastScope()->setVariable( "value", 0 ); | |
+ context.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QString( "value" ), 0, true ) ); | |
context.setHighlightedVariables( QStringList() << "value" ); | |
QgsExpressionBuilderDialog dlg( mLayer, mRuleEdit->text(), this, "generic", context ); | |
diff --git a/src/gui/symbology-ng/qgssymbollayerv2widget.cpp b/src/gui/symbology-ng/qgssymbollayerv2widget.cpp | |
index ed76136..dab2ceb 100644 | |
--- a/src/gui/symbology-ng/qgssymbollayerv2widget.cpp | |
+++ b/src/gui/symbology-ng/qgssymbollayerv2widget.cpp | |
@@ -80,7 +80,7 @@ static QgsExpressionContext _getExpressionContext( const void* context ) | |
{ | |
//cheat a bit - set the symbol color variable to match the symbol layer's color (when we should really be using the *symbols* | |
//color, but that's not accessible here). 99% of the time these will be the same anyway | |
- symbolScope->setVariable( QgsExpressionContext::EXPR_SYMBOL_COLOR, symbolLayer->color() ); | |
+ symbolScope->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_SYMBOL_COLOR, symbolLayer->color(), true ) ); | |
} | |
expContext << symbolScope; | |
expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_COUNT, 1, true ) ); | |
-- | |
2.8.1 | |
From 9a6cefcd4b50ec0112c82434031555519063b46f Mon Sep 17 00:00:00 2001 | |
From: Martin Dobias <[email protected]> | |
Date: Mon, 3 Oct 2016 12:04:03 +0800 | |
Subject: [PATCH] Fix listing of WMTS layers in browser (fixes #15350) | |
(cherry picked from commit 29d2bef7954d4e2b2cf21611c1398d0a7666e4c6) | |
--- | |
src/providers/wms/qgswmsdataitems.cpp | 33 ++++++++++++++++++++++++--------- | |
1 file changed, 24 insertions(+), 9 deletions(-) | |
diff --git a/src/providers/wms/qgswmsdataitems.cpp b/src/providers/wms/qgswmsdataitems.cpp | |
index d7508a0..16b3f9d 100644 | |
--- a/src/providers/wms/qgswmsdataitems.cpp | |
+++ b/src/providers/wms/qgswmsdataitems.cpp | |
@@ -115,46 +115,61 @@ QVector<QgsDataItem*> QgsWMSConnectionItem::createChildren() | |
QgsDataItem *layerItem = l.styles.size() == 1 ? this : new QgsDataCollectionItem( this, title, mPath + '/' + l.identifier ); | |
if ( layerItem != this ) | |
{ | |
+ layerItem->setCapabilities( layerItem->capabilities2() & ~QgsDataItem::Fertile ); | |
+ layerItem->setState( QgsDataItem::Populated ); | |
layerItem->setToolTip( title ); | |
- addChildItem( layerItem ); | |
+ children << layerItem; | |
} | |
Q_FOREACH ( const QgsWmtsStyle &style, l.styles ) | |
{ | |
QString styleName = style.title.isEmpty() ? style.identifier : style.title; | |
if ( layerItem == this ) | |
- styleName.prepend( title + " - " ); | |
+ styleName = title; // just one style so no need to display it | |
QgsDataItem *styleItem = l.setLinks.size() == 1 ? layerItem : new QgsDataCollectionItem( layerItem, styleName, layerItem->path() + '/' + style.identifier ); | |
if ( styleItem != layerItem ) | |
{ | |
+ styleItem->setCapabilities( styleItem->capabilities2() & ~QgsDataItem::Fertile ); | |
+ styleItem->setState( QgsDataItem::Populated ); | |
styleItem->setToolTip( styleName ); | |
- layerItem->addChildItem( styleItem ); | |
+ if ( layerItem == this ) | |
+ children << styleItem; | |
+ else | |
+ layerItem->addChildItem( styleItem ); | |
} | |
Q_FOREACH ( const QgsWmtsTileMatrixSetLink &setLink, l.setLinks ) | |
{ | |
QString linkName = setLink.tileMatrixSet; | |
if ( styleItem == layerItem ) | |
- linkName.prepend( styleName + " - " ); | |
+ linkName = styleName; // just one link so no need to display it | |
QgsDataItem *linkItem = l.formats.size() == 1 ? styleItem : new QgsDataCollectionItem( styleItem, linkName, styleItem->path() + '/' + setLink.tileMatrixSet ); | |
if ( linkItem != styleItem ) | |
{ | |
+ linkItem->setCapabilities( linkItem->capabilities2() & ~QgsDataItem::Fertile ); | |
+ linkItem->setState( QgsDataItem::Populated ); | |
linkItem->setToolTip( linkName ); | |
- styleItem->addChildItem( linkItem ); | |
+ if ( styleItem == this ) | |
+ children << linkItem; | |
+ else | |
+ styleItem->addChildItem( linkItem ); | |
} | |
Q_FOREACH ( const QString& format, l.formats ) | |
{ | |
QString name = format; | |
if ( linkItem == styleItem ) | |
- name.prepend( linkName + " - " ); | |
+ name = linkName; // just one format so no need to display it | |
- QgsDataItem *layerItem = new QgsWMTSLayerItem( linkItem, name, linkItem->path() + '/' + name, uri, | |
+ QgsDataItem *tileLayerItem = new QgsWMTSLayerItem( linkItem, name, linkItem->path() + '/' + name, uri, | |
l.identifier, format, style.identifier, setLink.tileMatrixSet, tileMatrixSets[ setLink.tileMatrixSet ].crs, title ); | |
- layerItem->setToolTip( name ); | |
- linkItem->addChildItem( layerItem ); | |
+ tileLayerItem->setToolTip( name ); | |
+ if ( linkItem == this ) | |
+ children << tileLayerItem; | |
+ else | |
+ linkItem->addChildItem( tileLayerItem ); | |
} | |
} | |
} | |
-- | |
2.8.1 | |
From 80e820f41f15a7020c7c0c843149443bf92660b2 Mon Sep 17 00:00:00 2001 | |
From: Nyall Dawson <[email protected]> | |
Date: Fri, 28 Oct 2016 16:56:46 +1000 | |
Subject: [PATCH] Fix build | |
--- | |
src/core/qgsexpression.cpp | 2 +- | |
src/core/symbology-ng/qgssymbolv2.cpp | 2 +- | |
2 files changed, 2 insertions(+), 2 deletions(-) | |
diff --git a/src/core/qgsexpression.cpp b/src/core/qgsexpression.cpp | |
index 95f9ddf..8a09c1a 100644 | |
--- a/src/core/qgsexpression.cpp | |
+++ b/src/core/qgsexpression.cpp | |
@@ -1027,7 +1027,7 @@ static QVariant fcnFeature( const QVariantList&, const QgsExpressionContext* con | |
if ( !context ) | |
return QVariant(); | |
- return context->feature(); | |
+ return context->variable( QgsExpressionContext::EXPR_FEATURE ); | |
} | |
static QVariant fcnAttribute( const QVariantList& values, const QgsExpressionContext*, QgsExpression* parent ) | |
{ | |
diff --git a/src/core/symbology-ng/qgssymbolv2.cpp b/src/core/symbology-ng/qgssymbolv2.cpp | |
index 70cd0a1..45a1f83 100644 | |
--- a/src/core/symbology-ng/qgssymbolv2.cpp | |
+++ b/src/core/symbology-ng/qgssymbolv2.cpp | |
@@ -738,7 +738,7 @@ void QgsSymbolV2::renderFeature( const QgsFeature& feature, QgsRenderContext& co | |
{ | |
context.expressionContext().appendScope( mSymbolRenderContext->expressionContextScope() ); | |
QgsExpressionContextUtils::updateSymbolScope( this, mSymbolRenderContext->expressionContextScope() ); | |
- mSymbolRenderContext->expressionContextScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_COUNT, segmentizedGeometry->geometryPartCount(), true ) ); | |
+ mSymbolRenderContext->expressionContextScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_COUNT, segmentizedGeometry->geometry()->partCount(), true ) ); | |
mSymbolRenderContext->expressionContextScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, 1, true ) ); | |
} | |
-- | |
2.8.1 | |
From f3652069cf3b57608299e24d0e2097c28e2391e6 Mon Sep 17 00:00:00 2001 | |
From: Martin Dobias <[email protected]> | |
Date: Mon, 3 Oct 2016 15:29:10 +0800 | |
Subject: [PATCH] Fix WMS identify when using "Feature" format and the layer | |
has named CRS | |
(cherry picked from commit 9ef91ea6294cdab762ffb2543d02473bcccbed80) | |
--- | |
src/providers/wms/qgswmsprovider.cpp | 3 ++- | |
1 file changed, 2 insertions(+), 1 deletion(-) | |
diff --git a/src/providers/wms/qgswmsprovider.cpp b/src/providers/wms/qgswmsprovider.cpp | |
index 9a72362..48718bc 100644 | |
--- a/src/providers/wms/qgswmsprovider.cpp | |
+++ b/src/providers/wms/qgswmsprovider.cpp | |
@@ -2677,7 +2677,7 @@ QgsRasterIdentifyResult QgsWmsProvider::identify( const QgsPoint & thePoint, Qgs | |
QString crsType = result.property( "crs" ).property( "type" ).toString(); | |
QString crsText; | |
if ( crsType == "name" ) | |
- crsText = result.property( "crs" ).property( "name" ).toString(); | |
+ crsText = result.property( "crs" ).property( "properties" ).property( "name" ).toString(); | |
else if ( crsType == "EPSG" ) | |
crsText = QString( "%1:%2" ).arg( crsType, result.property( "crs" ).property( "properties" ).property( "code" ).toString() ); | |
else | |
@@ -2773,6 +2773,7 @@ QgsRasterIdentifyResult QgsWmsProvider::identify( const QgsPoint & thePoint, Qgs | |
catch ( const QString &err ) | |
{ | |
QgsDebugMsg( QString( "JSON error: %1\nResult: %2" ).arg( err, QString::fromUtf8( mIdentifyResultBodies.value( jsonPart ) ) ) ); | |
+ results.insert( results.size(), err ); // string returned for format type "feature" means error | |
} | |
delete coordinateTransform; | |
-- | |
2.8.1 | |
From 66a213bc5aa9fa22affc512c31b80594ce6d3ffa Mon Sep 17 00:00:00 2001 | |
From: Martin Dobias <[email protected]> | |
Date: Wed, 5 Oct 2016 09:08:21 +0800 | |
Subject: [PATCH] Fix crash when loading WCS layers (fixes #15595) | |
The problem is that some providers would still issue network | |
requests in prepareJobs() - this should be ideally avoided, | |
because it is run in main thread - all the work should be deferred | |
to be done in worker thread. | |
(cherry picked from commit 08f4a0f40cce21d5730653a75bdd44f175f3b0b8) | |
--- | |
src/gui/qgsmapcanvas.cpp | 11 ++++++++--- | |
1 file changed, 8 insertions(+), 3 deletions(-) | |
diff --git a/src/gui/qgsmapcanvas.cpp b/src/gui/qgsmapcanvas.cpp | |
index 856d16b..7308b05 100644 | |
--- a/src/gui/qgsmapcanvas.cpp | |
+++ b/src/gui/qgsmapcanvas.cpp | |
@@ -663,9 +663,6 @@ void QgsMapCanvas::refreshMap() | |
stopRendering(); // if any... | |
- // from now on we can accept refresh requests again | |
- mRefreshScheduled = false; | |
- | |
//build the expression context | |
QgsExpressionContext expressionContext; | |
expressionContext << QgsExpressionContextUtils::globalScope() | |
@@ -698,6 +695,14 @@ void QgsMapCanvas::refreshMap() | |
mJob->start(); | |
+ // from now on we can accept refresh requests again | |
+ // this must be reset only after the job has been started, because | |
+ // some providers (yes, it's you WCS and AMS!) during preparation | |
+ // do network requests and start an internal event loop, which may | |
+ // end up calling refresh() and would schedule another refresh, | |
+ // deleting the one we have just started. | |
+ mRefreshScheduled = false; | |
+ | |
mMapUpdateTimer.start(); | |
emit renderStarting(); | |
-- | |
2.8.1 | |
From 9f228d4b7c260bf7fd9aec8f6489b51fc1b58b8a Mon Sep 17 00:00:00 2001 | |
From: Hugo Mercier <[email protected]> | |
Date: Fri, 28 Oct 2016 11:17:46 +0200 | |
Subject: [PATCH] Don't delete QgsAttributeDialog too early. Fixes #15737 | |
(cherry picked from commit 9ecdf6101433) | |
--- | |
src/app/qgsfeatureaction.cpp | 32 ++++++++++++++++++++------------ | |
src/gui/qgsattributedialog.cpp | 5 +---- | |
src/gui/qgsattributedialog.h | 5 ++--- | |
3 files changed, 23 insertions(+), 19 deletions(-) | |
diff --git a/src/app/qgsfeatureaction.cpp b/src/app/qgsfeatureaction.cpp | |
index 106cfcf..a78df31 100644 | |
--- a/src/app/qgsfeatureaction.cpp | |
+++ b/src/app/qgsfeatureaction.cpp | |
@@ -98,7 +98,9 @@ bool QgsFeatureAction::viewFeatureForm( QgsHighlight *h ) | |
QgsAttributeDialog *dialog = newDialog( true ); | |
dialog->setHighlight( h ); | |
- dialog->show(); // will also delete the dialog on close (show() is overridden) | |
+ // delete the dialog when it is closed | |
+ dialog->setAttribute( Qt::WA_DeleteOnClose ); | |
+ dialog->show(); | |
return true; | |
} | |
@@ -108,24 +110,29 @@ bool QgsFeatureAction::editFeature( bool showModal ) | |
if ( !mLayer ) | |
return false; | |
- QgsAttributeDialog *dialog = newDialog( false ); | |
- | |
- if ( !mFeature->isValid() ) | |
- dialog->setIsAddDialog( true ); | |
- | |
if ( showModal ) | |
{ | |
- dialog->setAttribute( Qt::WA_DeleteOnClose ); | |
- int rv = dialog->exec(); | |
+ QScopedPointer<QgsAttributeDialog> dialog( newDialog( false ) ); | |
+ | |
+ if ( !mFeature->isValid() ) | |
+ dialog->setIsAddDialog( true ); | |
+ int rv = dialog->exec(); | |
mFeature->setAttributes( dialog->feature()->attributes() ); | |
return rv; | |
} | |
else | |
{ | |
- dialog->show(); // will also delete the dialog on close (show() is overridden) | |
- } | |
+ QgsAttributeDialog* dialog = newDialog( false ); | |
+ | |
+ if ( !mFeature->isValid() ) | |
+ dialog->setIsAddDialog( true ); | |
+ // delete the dialog when it is closed | |
+ dialog->setAttribute( Qt::WA_DeleteOnClose ); | |
+ dialog->show(); | |
+ } | |
+ | |
return true; | |
} | |
@@ -193,6 +200,8 @@ bool QgsFeatureAction::addFeature( const QgsAttributeMap& defaultAttributes, boo | |
else | |
{ | |
QgsAttributeDialog *dialog = newDialog( false ); | |
+ // delete the dialog when it is closed | |
+ dialog->setAttribute( Qt::WA_DeleteOnClose ); | |
dialog->setIsAddDialog( true ); | |
dialog->setEditCommandMessage( text() ); | |
@@ -201,12 +210,11 @@ bool QgsFeatureAction::addFeature( const QgsAttributeMap& defaultAttributes, boo | |
if ( !showModal ) | |
{ | |
setParent( dialog ); // keep dialog until the dialog is closed and destructed | |
- dialog->show(); // will also delete the dialog on close (show() is overridden) | |
+ dialog->show(); | |
mFeature = nullptr; | |
return true; | |
} | |
- dialog->setAttribute( Qt::WA_DeleteOnClose ); | |
dialog->exec(); | |
} | |
diff --git a/src/gui/qgsattributedialog.cpp b/src/gui/qgsattributedialog.cpp | |
index ee1b9cf..ee71f2e 100644 | |
--- a/src/gui/qgsattributedialog.cpp | |
+++ b/src/gui/qgsattributedialog.cpp | |
@@ -87,11 +87,8 @@ void QgsAttributeDialog::accept() | |
QDialog::accept(); | |
} | |
-void QgsAttributeDialog::show( bool autoDelete ) | |
+void QgsAttributeDialog::show() | |
{ | |
- if ( autoDelete ) | |
- setAttribute( Qt::WA_DeleteOnClose ); | |
- | |
QDialog::show(); | |
raise(); | |
activateWindow(); | |
diff --git a/src/gui/qgsattributedialog.h b/src/gui/qgsattributedialog.h | |
index e7dd32b..4263f32 100644 | |
--- a/src/gui/qgsattributedialog.h | |
+++ b/src/gui/qgsattributedialog.h | |
@@ -130,9 +130,8 @@ class GUI_EXPORT QgsAttributeDialog : public QDialog | |
public slots: | |
void accept() override; | |
- //! Show the dialog non-blocking. Reparents this dialog to be a child of the dialog form and is deleted when | |
- //! closed. | |
- void show( bool autoDelete = true ); | |
+ //! Show the dialog non-blocking. Reparents this dialog to be a child of the dialog form | |
+ void show(); | |
private: | |
void init( QgsVectorLayer* layer, QgsFeature* feature, const QgsAttributeEditorContext& context ); | |
-- | |
2.8.1 | |
From afd04eb0b860cd1266368741f7eea97f92433f22 Mon Sep 17 00:00:00 2001 | |
From: Martin Dobias <[email protected]> | |
Date: Fri, 7 Oct 2016 17:34:54 +0800 | |
Subject: [PATCH] Fix crash in node tool after deleting the whole geometry | |
(fixes #15659) | |
Made sure that both closestVertex() and closestSegment() return negative | |
distance on error (e.g. with null or emtpy geometry). | |
Also fixes snapping when dealing with layers with null/invalid geometries | |
(cherry picked from commit c093d5188fad685c4a596ff23c27aad7d151dac2) | |
--- | |
src/app/nodetool/qgsmaptoolnodetool.cpp | 7 +++-- | |
src/core/geometry/qgscircularstringv2.cpp | 3 +++ | |
src/core/geometry/qgscurvepolygonv2.cpp | 2 +- | |
src/core/geometry/qgsgeometry.cpp | 9 +++++-- | |
src/core/geometry/qgsgeometryutils.cpp | 1 + | |
src/core/geometry/qgsgeometryutils.h | 8 ++++-- | |
src/core/geometry/qgslinestringv2.cpp | 10 ++----- | |
src/core/qgspointlocator.cpp | 2 ++ | |
tests/src/core/testqgsgeometry.cpp | 5 ++-- | |
tests/src/core/testqgspointlocator.cpp | 43 +++++++++++++++++++++++++++++++ | |
10 files changed, 70 insertions(+), 20 deletions(-) | |
diff --git a/src/app/nodetool/qgsmaptoolnodetool.cpp b/src/app/nodetool/qgsmaptoolnodetool.cpp | |
index ccb0786..0ca5092 100644 | |
--- a/src/app/nodetool/qgsmaptoolnodetool.cpp | |
+++ b/src/app/nodetool/qgsmaptoolnodetool.cpp | |
@@ -272,12 +272,11 @@ void QgsMapToolNodeTool::canvasPressEvent( QgsMapMouseEvent* e ) | |
// get geometry and find if snapping is near it | |
int atVertex, beforeVertex, afterVertex; | |
- double dist; | |
- QgsPoint closestLayerVertex = mSelectedFeature->geometry()->closestVertex( layerCoordPoint, atVertex, beforeVertex, afterVertex, dist ); | |
- dist = sqrt( dist ); | |
+ double sqrDist; // will be negative on error | |
+ QgsPoint closestLayerVertex = mSelectedFeature->geometry()->closestVertex( layerCoordPoint, atVertex, beforeVertex, afterVertex, sqrDist ); | |
mSnapper.snapToCurrentLayer( e->pos(), snapResults, QgsSnapper::SnapToVertex, tol ); | |
- if ( dist <= tol ) | |
+ if ( sqrDist >= 0 && sqrt( sqrDist ) <= tol ) | |
{ | |
// some vertex selected | |
mMoving = true; | |
diff --git a/src/core/geometry/qgscircularstringv2.cpp b/src/core/geometry/qgscircularstringv2.cpp | |
index 7245894..c88c4f7 100644 | |
--- a/src/core/geometry/qgscircularstringv2.cpp | |
+++ b/src/core/geometry/qgscircularstringv2.cpp | |
@@ -825,6 +825,9 @@ double QgsCircularStringV2::closestSegment( const QgsPointV2& pt, QgsPointV2& se | |
} | |
} | |
+ if ( minDist == std::numeric_limits<double>::max() ) | |
+ return -1; // error: no segments | |
+ | |
segmentPt = minDistSegmentPoint; | |
vertexAfter = minDistVertexAfter; | |
vertexAfter.part = 0; | |
diff --git a/src/core/geometry/qgscurvepolygonv2.cpp b/src/core/geometry/qgscurvepolygonv2.cpp | |
index b4abde2..33c037f 100644 | |
--- a/src/core/geometry/qgscurvepolygonv2.cpp | |
+++ b/src/core/geometry/qgscurvepolygonv2.cpp | |
@@ -632,7 +632,7 @@ double QgsCurvePolygonV2::closestSegment( const QgsPointV2& pt, QgsPointV2& segm | |
{ | |
if ( !mExteriorRing ) | |
{ | |
- return 0.0; | |
+ return -1; | |
} | |
QList<QgsCurveV2*> segmentList; | |
segmentList.append( mExteriorRing ); | |
diff --git a/src/core/geometry/qgsgeometry.cpp b/src/core/geometry/qgsgeometry.cpp | |
index 8cf207b..682b066 100644 | |
--- a/src/core/geometry/qgsgeometry.cpp | |
+++ b/src/core/geometry/qgsgeometry.cpp | |
@@ -347,6 +347,7 @@ QgsPoint QgsGeometry::closestVertex( const QgsPoint& point, int& atVertex, int& | |
{ | |
if ( !d->geometry ) | |
{ | |
+ sqrDist = -1; | |
return QgsPoint( 0, 0 ); | |
} | |
@@ -531,12 +532,14 @@ double QgsGeometry::closestVertexWithContext( const QgsPoint& point, int& atVert | |
{ | |
if ( !d->geometry ) | |
{ | |
- return 0.0; | |
+ return -1; | |
} | |
QgsVertexId vId; | |
QgsPointV2 pt( point.x(), point.y() ); | |
QgsPointV2 closestPoint = QgsGeometryUtils::closestVertex( *( d->geometry ), pt, vId ); | |
+ if ( !vId.isValid() ) | |
+ return -1; | |
atVertex = vertexNrFromVertexId( vId ); | |
return QgsGeometryUtils::sqrDistance2D( closestPoint, pt ); | |
} | |
@@ -550,7 +553,7 @@ double QgsGeometry::closestSegmentWithContext( | |
{ | |
if ( !d->geometry ) | |
{ | |
- return 0; | |
+ return -1; | |
} | |
QgsPointV2 segmentPt; | |
@@ -558,6 +561,8 @@ double QgsGeometry::closestSegmentWithContext( | |
bool leftOfBool; | |
double sqrDist = d->geometry->closestSegment( QgsPointV2( point.x(), point.y() ), segmentPt, vertexAfter, &leftOfBool, epsilon ); | |
+ if ( sqrDist < 0 ) | |
+ return -1; | |
minDistPoint.setX( segmentPt.x() ); | |
minDistPoint.setY( segmentPt.y() ); | |
diff --git a/src/core/geometry/qgsgeometryutils.cpp b/src/core/geometry/qgsgeometryutils.cpp | |
index 19e60d1..f913c0a 100644 | |
--- a/src/core/geometry/qgsgeometryutils.cpp | |
+++ b/src/core/geometry/qgsgeometryutils.cpp | |
@@ -65,6 +65,7 @@ QgsPointV2 QgsGeometryUtils::closestVertex( const QgsAbstractGeometryV2& geom, c | |
double minDist = std::numeric_limits<double>::max(); | |
double currentDist = 0; | |
QgsPointV2 minDistPoint; | |
+ id = QgsVertexId(); // set as invalid | |
QgsVertexId vertexId; | |
QgsPointV2 vertex; | |
diff --git a/src/core/geometry/qgsgeometryutils.h b/src/core/geometry/qgsgeometryutils.h | |
index 667fae1..7d7bd8d 100644 | |
--- a/src/core/geometry/qgsgeometryutils.h | |
+++ b/src/core/geometry/qgsgeometryutils.h | |
@@ -37,7 +37,8 @@ class CORE_EXPORT QgsGeometryUtils | |
*/ | |
static QList<QgsLineStringV2*> extractLineStrings( const QgsAbstractGeometryV2* geom ); | |
- /** Returns the closest vertex to a geometry for a specified point | |
+ /** Returns the closest vertex to a geometry for a specified point. | |
+ * On error null point will be returned and "id" argument will be invalid. | |
*/ | |
static QgsPointV2 closestVertex( const QgsAbstractGeometryV2& geom, const QgsPointV2& pt, QgsVertexId& id ); | |
@@ -227,7 +228,7 @@ class CORE_EXPORT QgsGeometryUtils | |
for ( int i = 0; i < container.size(); ++i ) | |
{ | |
sqrDist = container.at( i )->closestSegment( pt, segmentPt, vertexAfter, leftOf, epsilon ); | |
- if ( sqrDist < minDist ) | |
+ if ( sqrDist >= 0 && sqrDist < minDist ) | |
{ | |
minDist = sqrDist; | |
minDistSegmentX = segmentPt.x(); | |
@@ -257,6 +258,9 @@ class CORE_EXPORT QgsGeometryUtils | |
} | |
} | |
+ if ( minDist == std::numeric_limits<double>::max() ) | |
+ return -1; // error: no segments | |
+ | |
segmentPt.setX( minDistSegmentX ); | |
segmentPt.setY( minDistSegmentY ); | |
vertexAfter = minDistVertexAfter; | |
diff --git a/src/core/geometry/qgslinestringv2.cpp b/src/core/geometry/qgslinestringv2.cpp | |
index 13534a8..d39b61f 100644 | |
--- a/src/core/geometry/qgslinestringv2.cpp | |
+++ b/src/core/geometry/qgslinestringv2.cpp | |
@@ -744,16 +744,10 @@ double QgsLineStringV2::closestSegment( const QgsPointV2& pt, QgsPointV2& segmen | |
double segmentPtX, segmentPtY; | |
int size = mX.size(); | |
- if ( size == 0 ) | |
+ if ( size == 0 || size == 1 ) | |
{ | |
vertexAfter = QgsVertexId( 0, 0, 0 ); | |
- return sqrDist; | |
- } | |
- else if ( size == 1 ) | |
- { | |
- segmentPt = pointN( 0 ); | |
- vertexAfter = QgsVertexId( 0, 0, 1 ); | |
- return QgsGeometryUtils::sqrDistance2D( pt, segmentPt ); | |
+ return -1; | |
} | |
for ( int i = 1; i < size; ++i ) | |
{ | |
diff --git a/src/core/qgspointlocator.cpp b/src/core/qgspointlocator.cpp | |
index 66b2647..ecad55e 100644 | |
--- a/src/core/qgspointlocator.cpp | |
+++ b/src/core/qgspointlocator.cpp | |
@@ -100,6 +100,8 @@ class QgsPointLocator_VisitorNearestVertex : public IVisitor | |
int vertexIndex, beforeVertex, afterVertex; | |
double sqrDist; | |
QgsPoint pt = geom->closestVertex( mSrcPoint, vertexIndex, beforeVertex, afterVertex, sqrDist ); | |
+ if ( sqrDist < 0 ) | |
+ return; // probably empty geometry | |
QgsPointLocator::Match m( QgsPointLocator::Vertex, mLocator->mLayer, id, sqrt( sqrDist ), pt, vertexIndex ); | |
// in range queries the filter may reject some matches | |
diff --git a/tests/src/core/testqgsgeometry.cpp b/tests/src/core/testqgsgeometry.cpp | |
index 785c4ab..905c0a2 100644 | |
--- a/tests/src/core/testqgsgeometry.cpp | |
+++ b/tests/src/core/testqgsgeometry.cpp | |
@@ -2010,11 +2010,10 @@ void TestQgsGeometry::lineStringV2() | |
//closest segment | |
QgsLineStringV2 l35; | |
bool leftOf = false; | |
+ p = QgsPointV2(); // reset all coords to zero | |
( void )l35.closestSegment( QgsPointV2( 1, 2 ), p, v, 0, 0 ); //empty line, just want no crash | |
l35.setPoints( QgsPointSequenceV2() << QgsPointV2( 5, 10 ) ); | |
- QVERIFY( qgsDoubleNear( l35.closestSegment( QgsPointV2( 5, 10 ), p, v, 0, 0 ), 0 ) ); | |
- QCOMPARE( p, QgsPointV2( 5, 10 ) ); | |
- QCOMPARE( v, QgsVertexId( 0, 0, 1 ) ); | |
+ QVERIFY( l35.closestSegment( QgsPointV2( 5, 10 ), p, v, 0, 0 ) < 0 ); | |
l35.setPoints( QgsPointSequenceV2() << QgsPointV2( 5, 10 ) << QgsPointV2( 10, 10 ) ); | |
QVERIFY( qgsDoubleNear( l35.closestSegment( QgsPointV2( 4, 11 ), p, v, &leftOf, 0 ), 2.0 ) ); | |
QCOMPARE( p, QgsPointV2( 5, 10 ) ); | |
diff --git a/tests/src/core/testqgspointlocator.cpp b/tests/src/core/testqgspointlocator.cpp | |
index cb7e805..090c705 100644 | |
--- a/tests/src/core/testqgspointlocator.cpp | |
+++ b/tests/src/core/testqgspointlocator.cpp | |
@@ -23,6 +23,7 @@ | |
#include "qgsgeometry.h" | |
#include "qgsmaplayerregistry.h" | |
#include "qgspointlocator.h" | |
+#include "qgspolygonv2.h" | |
struct FilterExcludePoint : public QgsPointLocator::MatchFilter | |
@@ -256,6 +257,48 @@ class TestQgsPointLocator : public QObject | |
QVERIFY( m2.isValid() ); | |
QCOMPARE( m2.point(), QgsPoint( 1, 1 ) ); | |
} | |
+ | |
+ void testNullGeometries() | |
+ { | |
+ QgsVectorLayer* vlNullGeom = new QgsVectorLayer( "Polygon", "x", "memory" ); | |
+ QgsFeature ff( 0 ); | |
+ ff.setGeometry( QgsGeometry() ); | |
+ QgsFeatureList flist; | |
+ flist << ff; | |
+ vlNullGeom->dataProvider()->addFeatures( flist ); | |
+ | |
+ QgsPointLocator loc( vlNullGeom, 0, nullptr ); | |
+ | |
+ QgsPointLocator::Match m1 = loc.nearestVertex( QgsPoint( 2, 2 ), std::numeric_limits<double>::max() ); | |
+ QVERIFY( !m1.isValid() ); | |
+ | |
+ QgsPointLocator::Match m2 = loc.nearestEdge( QgsPoint( 2, 2 ), std::numeric_limits<double>::max() ); | |
+ QVERIFY( !m2.isValid() ); | |
+ | |
+ delete vlNullGeom; | |
+ } | |
+ | |
+ void testEmptyGeometries() | |
+ { | |
+ QgsVectorLayer* vlEmptyGeom = new QgsVectorLayer( "Polygon", "x", "memory" ); | |
+ QgsFeature ff( 0 ); | |
+ QgsGeometry g; | |
+ g.setGeometry( new QgsPolygonV2() ); | |
+ ff.setGeometry( g ); | |
+ QgsFeatureList flist; | |
+ flist << ff; | |
+ vlEmptyGeom->dataProvider()->addFeatures( flist ); | |
+ | |
+ QgsPointLocator loc( vlEmptyGeom, 0, nullptr ); | |
+ | |
+ QgsPointLocator::Match m1 = loc.nearestVertex( QgsPoint( 2, 2 ), std::numeric_limits<double>::max() ); | |
+ QVERIFY( !m1.isValid() ); | |
+ | |
+ QgsPointLocator::Match m2 = loc.nearestEdge( QgsPoint( 2, 2 ), std::numeric_limits<double>::max() ); | |
+ QVERIFY( !m2.isValid() ); | |
+ | |
+ delete vlEmptyGeom; | |
+ } | |
}; | |
QTEST_MAIN( TestQgsPointLocator ) | |
-- | |
2.8.1 | |
From d6860f30ad90bb0a8008a01db3de48b081df94cd Mon Sep 17 00:00:00 2001 | |
From: Martin Dobias <[email protected]> | |
Date: Fri, 14 Oct 2016 11:17:36 +0800 | |
Subject: [PATCH] Fix layer tree expanded state when used expand/collapse all | |
(fixes #15691) | |
(cherry picked from commit de85fdd6e8fa3d4f38196376aabccce317cbf341) | |
--- | |
python/gui/layertree/qgslayertreeview.sip | 8 ++++++ | |
src/app/qgisapp.cpp | 4 +-- | |
src/gui/layertree/qgslayertreeview.cpp | 46 +++++++++++++++++++++++++++++++ | |
src/gui/layertree/qgslayertreeview.h | 8 ++++++ | |
4 files changed, 64 insertions(+), 2 deletions(-) | |
diff --git a/python/gui/layertree/qgslayertreeview.sip b/python/gui/layertree/qgslayertreeview.sip | |
index af1f539..636a276 100644 | |
--- a/python/gui/layertree/qgslayertreeview.sip | |
+++ b/python/gui/layertree/qgslayertreeview.sip | |
@@ -72,6 +72,14 @@ class QgsLayerTreeView : QTreeView | |
//! Force refresh of layer symbology. Normally not needed as the changes of layer's renderer are monitored by the model | |
void refreshLayerSymbology( const QString& layerId ); | |
+ //! Enhancement of QTreeView::expandAll() that also records expanded state in layer tree nodes | |
+ //! @note added in QGIS 2.18 | |
+ void expandAllNodes(); | |
+ | |
+ //! Enhancement of QTreeView::collapseAll() that also records expanded state in layer tree nodes | |
+ //! @note added in QGIS 2.18 | |
+ void collapseAllNodes(); | |
+ | |
signals: | |
//! Emitted when a current layer is changed | |
void currentLayerChanged( QgsMapLayer* layer ); | |
diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp | |
index 581b4d1..e4e6496 100644 | |
--- a/src/app/qgisapp.cpp | |
+++ b/src/app/qgisapp.cpp | |
@@ -2757,11 +2757,11 @@ void QgisApp::initLayerTreeView() | |
QAction* actionExpandAll = new QAction( tr( "Expand All" ), this ); | |
actionExpandAll->setIcon( QgsApplication::getThemeIcon( "/mActionExpandTree.svg" ) ); | |
actionExpandAll->setToolTip( tr( "Expand All" ) ); | |
- connect( actionExpandAll, SIGNAL( triggered( bool ) ), mLayerTreeView, SLOT( expandAll() ) ); | |
+ connect( actionExpandAll, SIGNAL( triggered( bool ) ), mLayerTreeView, SLOT( expandAllNodes() ) ); | |
QAction* actionCollapseAll = new QAction( tr( "Collapse All" ), this ); | |
actionCollapseAll->setIcon( QgsApplication::getThemeIcon( "/mActionCollapseTree.svg" ) ); | |
actionCollapseAll->setToolTip( tr( "Collapse All" ) ); | |
- connect( actionCollapseAll, SIGNAL( triggered( bool ) ), mLayerTreeView, SLOT( collapseAll() ) ); | |
+ connect( actionCollapseAll, SIGNAL( triggered( bool ) ), mLayerTreeView, SLOT( collapseAllNodes() ) ); | |
QToolBar* toolbar = new QToolBar(); | |
toolbar->setIconSize( QSize( 16, 16 ) ); | |
diff --git a/src/gui/layertree/qgslayertreeview.cpp b/src/gui/layertree/qgslayertreeview.cpp | |
index 7530c26..74b298b 100644 | |
--- a/src/gui/layertree/qgslayertreeview.cpp | |
+++ b/src/gui/layertree/qgslayertreeview.cpp | |
@@ -313,3 +313,49 @@ void QgsLayerTreeView::refreshLayerSymbology( const QString& layerId ) | |
if ( nodeLayer ) | |
layerTreeModel()->refreshLayerLegend( nodeLayer ); | |
} | |
+ | |
+ | |
+static void _expandAllLegendNodes( QgsLayerTreeLayer* nodeLayer, bool expanded, QgsLayerTreeModel* model ) | |
+{ | |
+ // for layers we also need to find out with legend nodes contain some children and make them expanded/collapsed | |
+ // if we are collapsing, we just write out an empty list | |
+ QStringList lst; | |
+ if ( expanded ) | |
+ { | |
+ Q_FOREACH ( QgsLayerTreeModelLegendNode* legendNode, model->layerLegendNodes( nodeLayer ) ) | |
+ { | |
+ QString parentKey = legendNode->data( QgsLayerTreeModelLegendNode::ParentRuleKeyRole ).toString(); | |
+ if ( !parentKey.isEmpty() && !lst.contains( parentKey ) ) | |
+ lst << parentKey; | |
+ } | |
+ } | |
+ nodeLayer->setCustomProperty( "expandedLegendNodes", lst ); | |
+} | |
+ | |
+ | |
+static void _expandAllNodes( QgsLayerTreeGroup* parent, bool expanded, QgsLayerTreeModel* model ) | |
+{ | |
+ Q_FOREACH ( QgsLayerTreeNode* node, parent->children() ) | |
+ { | |
+ node->setExpanded( expanded ); | |
+ if ( QgsLayerTree::isGroup( node ) ) | |
+ _expandAllNodes( QgsLayerTree::toGroup( node ), expanded, model ); | |
+ else if ( QgsLayerTree::isLayer( node ) ) | |
+ _expandAllLegendNodes( QgsLayerTree::toLayer( node ), expanded, model ); | |
+ } | |
+} | |
+ | |
+ | |
+void QgsLayerTreeView::expandAllNodes() | |
+{ | |
+ // unfortunately expandAll() does not emit expanded() signals | |
+ _expandAllNodes( layerTreeModel()->rootGroup(), true, layerTreeModel() ); | |
+ expandAll(); | |
+} | |
+ | |
+void QgsLayerTreeView::collapseAllNodes() | |
+{ | |
+ // unfortunately collapseAll() does not emit collapsed() signals | |
+ _expandAllNodes( layerTreeModel()->rootGroup(), false, layerTreeModel() ); | |
+ collapseAll(); | |
+} | |
diff --git a/src/gui/layertree/qgslayertreeview.h b/src/gui/layertree/qgslayertreeview.h | |
index bf3fe5f..2a3878c 100644 | |
--- a/src/gui/layertree/qgslayertreeview.h | |
+++ b/src/gui/layertree/qgslayertreeview.h | |
@@ -91,6 +91,14 @@ class GUI_EXPORT QgsLayerTreeView : public QTreeView | |
//! Force refresh of layer symbology. Normally not needed as the changes of layer's renderer are monitored by the model | |
void refreshLayerSymbology( const QString& layerId ); | |
+ //! Enhancement of QTreeView::expandAll() that also records expanded state in layer tree nodes | |
+ //! @note added in QGIS 2.18 | |
+ void expandAllNodes(); | |
+ | |
+ //! Enhancement of QTreeView::collapseAll() that also records expanded state in layer tree nodes | |
+ //! @note added in QGIS 2.18 | |
+ void collapseAllNodes(); | |
+ | |
signals: | |
//! Emitted when a current layer is changed | |
void currentLayerChanged( QgsMapLayer* layer ); | |
-- | |
2.8.1 | |
From 8cf03ced0c94835fb96302b6ca49d5a98117bc44 Mon Sep 17 00:00:00 2001 | |
From: Even Rouault <[email protected]> | |
Date: Mon, 31 Oct 2016 17:10:58 +0100 | |
Subject: [PATCH] [OGR provider] Make addAttributes() return the requested | |
field type, precision and width so as to make | |
QgsVectorLayerEditBuffer::commitChanges() API | |
Fixes #15614 | |
--- | |
src/providers/ogr/qgsogrprovider.cpp | 34 +++++++++++++++++++++++++++++++++- | |
1 file changed, 33 insertions(+), 1 deletion(-) | |
diff --git a/src/providers/ogr/qgsogrprovider.cpp b/src/providers/ogr/qgsogrprovider.cpp | |
index 850a5ab..4335927 100644 | |
--- a/src/providers/ogr/qgsogrprovider.cpp | |
+++ b/src/providers/ogr/qgsogrprovider.cpp | |
@@ -1153,8 +1153,12 @@ bool QgsOgrProvider::addAttributes( const QList<QgsField> &attributes ) | |
bool returnvalue = true; | |
+ QMap< QString, QgsField > mapFieldNameToOriginalField; | |
+ | |
for ( QList<QgsField>::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter ) | |
{ | |
+ mapFieldNameToOriginalField[ iter->name()] = *iter; | |
+ | |
OGRFieldType type; | |
switch ( iter->type() ) | |
@@ -1164,8 +1168,16 @@ bool QgsOgrProvider::addAttributes( const QList<QgsField> &attributes ) | |
break; | |
#if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 2000000 | |
case QVariant::LongLong: | |
- type = OFTInteger64; | |
+ { | |
+ const char* pszDataTypes = GDALGetMetadataItem( ogrDriver, GDAL_DMD_CREATIONFIELDDATATYPES, NULL ); | |
+ if ( pszDataTypes && strstr( pszDataTypes, "Integer64" ) ) | |
+ type = OFTInteger64; | |
+ else | |
+ { | |
+ type = OFTReal; | |
+ } | |
break; | |
+ } | |
#endif | |
case QVariant::Double: | |
type = OFTReal; | |
@@ -1203,6 +1215,26 @@ bool QgsOgrProvider::addAttributes( const QList<QgsField> &attributes ) | |
OGR_Fld_Destroy( fielddefn ); | |
} | |
loadFields(); | |
+ | |
+ // The check in QgsVectorLayerEditBuffer::commitChanges() is questionable with | |
+ // real-world drivers that might only be able to satisfy request only partially. | |
+ // So to avoid erroring out, patch field type, width and precision to match | |
+ // what was requested. | |
+ // For example in case of Integer64->Real mapping so that QVariant::LongLong is | |
+ // still returned to the caller | |
+ // Or if a field width was specified but not strictly enforced by the driver (#15614) | |
+ for ( QMap< QString, QgsField >::const_iterator it = mapFieldNameToOriginalField.begin(); | |
+ it != mapFieldNameToOriginalField.end(); ++it ) | |
+ { | |
+ int idx = mAttributeFields.fieldNameIndex( it.key() ); | |
+ if ( idx >= 0 ) | |
+ { | |
+ mAttributeFields[ idx ].setType( it->type() ); | |
+ mAttributeFields[ idx ].setLength( it->length() ); | |
+ mAttributeFields[ idx ].setPrecision( it->precision() ); | |
+ } | |
+ } | |
+ | |
return returnvalue; | |
} | |
-- | |
2.8.1 | |
From 819f571b478f971236f6d04c349108cc6f0a2c3c Mon Sep 17 00:00:00 2001 | |
From: Even Rouault <[email protected]> | |
Date: Mon, 31 Oct 2016 18:16:29 +0100 | |
Subject: [PATCH] Fix test_provider_ogr_gpkg.py | |
--- | |
tests/src/python/test_provider_ogr_gpkg.py | 3 ++- | |
1 file changed, 2 insertions(+), 1 deletion(-) | |
diff --git a/tests/src/python/test_provider_ogr_gpkg.py b/tests/src/python/test_provider_ogr_gpkg.py | |
index d2e0f0c..7af9188 100644 | |
--- a/tests/src/python/test_provider_ogr_gpkg.py | |
+++ b/tests/src/python/test_provider_ogr_gpkg.py | |
@@ -160,9 +160,10 @@ class TestPyQgsOGRProviderGpkg(unittest.TestCase): | |
return | |
self.internalTestBug15351('commit_closeIter_closeProvider') | |
- @unittest.expectedFailure(int(gdal.VersionInfo('VERSION_NUM')) < GDAL_COMPUTE_VERSION(2, 1, 2)) | |
def testGeopackageExtentUpdate(self): | |
''' test http://hub.qgis.org/issues/15273 ''' | |
+ if int(gdal.VersionInfo('VERSION_NUM')) < GDAL_COMPUTE_VERSION(2, 1, 2): | |
+ return | |
tmpfile = os.path.join(self.basetestpath, 'testGeopackageExtentUpdate.gpkg') | |
ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile) | |
lyr = ds.CreateLayer('test', geom_type=ogr.wkbPoint) | |
-- | |
2.8.1 | |
From 053c531177c924dc2b9e71ef792985932818abdc Mon Sep 17 00:00:00 2001 | |
From: "Juergen E. Fischer" <[email protected]> | |
Date: Tue, 1 Nov 2016 13:46:29 +0100 | |
Subject: [PATCH] fix typos | |
(cherry picked from commit 7a326b1b8d7026bc2782afc0fdc5abbaa1065370) | |
--- | |
python/gui/qgsextentgroupbox.sip | 2 +- | |
python/plugins/processing/algs/help/qgis.yaml | 4 ++-- | |
src/gui/qgsextentgroupbox.h | 2 +- | |
3 files changed, 4 insertions(+), 4 deletions(-) | |
diff --git a/python/gui/qgsextentgroupbox.sip b/python/gui/qgsextentgroupbox.sip | |
index 1a5c658..c2b72d0 100644 | |
--- a/python/gui/qgsextentgroupbox.sip | |
+++ b/python/gui/qgsextentgroupbox.sip | |
@@ -58,7 +58,7 @@ class QgsExtentGroupBox : QgsCollapsibleGroupBox | |
//! set output extent to be the same as current extent (may be transformed to output CRS) | |
void setOutputExtentFromCurrent(); | |
- //! set output extent to custom extent (may be transformed to outut CRS) | |
+ //! set output extent to custom extent (may be transformed to output CRS) | |
void setOutputExtentFromUser( const QgsRectangle& extent, const QgsCoordinateReferenceSystem& crs ); | |
signals: | |
diff --git a/python/plugins/processing/algs/help/qgis.yaml b/python/plugins/processing/algs/help/qgis.yaml | |
index bcf266f..3061611 100644 | |
--- a/python/plugins/processing/algs/help/qgis.yaml | |
+++ b/python/plugins/processing/algs/help/qgis.yaml | |
@@ -394,9 +394,9 @@ qgis:splitlineswithlines: > | |
This algorithm split the lines in a line layer using the lines in another line layer to define the breaking points. Intersection between geometries in both layers are considered as split points. | |
qgis:splitvectorlayer: > | |
- This algorithm takes a vector layer and an attribute and generates a set of vector layers in an outut folder. Each of the layers created in that folder contains all features from the input layer with the same value for the specified attribute. | |
+ This algorithm takes a vector layer and an attribute and generates a set of vector layers in an output folder. Each of the layers created in that folder contains all features from the input layer with the same value for the specified attribute. | |
- The number of files generated is equal to the nuber of different values found for the specified attribute. | |
+ The number of files generated is equal to the nubmer of different values found for the specified attribute. | |
qgis:statisticsbycategories: | |
diff --git a/src/gui/qgsextentgroupbox.h b/src/gui/qgsextentgroupbox.h | |
index b8ca133..19c545e 100644 | |
--- a/src/gui/qgsextentgroupbox.h | |
+++ b/src/gui/qgsextentgroupbox.h | |
@@ -70,7 +70,7 @@ class GUI_EXPORT QgsExtentGroupBox : public QgsCollapsibleGroupBox, private Ui:: | |
//! set output extent to be the same as current extent (may be transformed to output CRS) | |
void setOutputExtentFromCurrent(); | |
- //! set output extent to custom extent (may be transformed to outut CRS) | |
+ //! set output extent to custom extent (may be transformed to output CRS) | |
void setOutputExtentFromUser( const QgsRectangle& extent, const QgsCoordinateReferenceSystem& crs ); | |
signals: | |
-- | |
2.8.1 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment