Skip to content
Permalink
Browse files

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

Conflicts:
	src/gui/attributetable/qgsfieldconditionalformatwidget.cpp
  • Loading branch information
NathanW2 committed Aug 25, 2015
2 parents 01d635a + 385a608 commit 9094575b804b1854f44935f5a6f45dfb8edc2c53
Showing with 182 additions and 66 deletions.
  1. +15 −0 python/core/qgsexpression.sip
  2. +1 −1 src/core/composer/qgscomposerobject.cpp
  3. +7 −0 src/core/geometry/qgsgeometry.cpp
  4. +9 −0 src/core/qgsapplication.cpp
  5. +2 −0 src/core/qgsdistancearea.cpp
  6. +15 −2 src/core/qgsexpression.cpp
  7. +20 −1 src/core/qgsexpression.h
  8. +2 −2 src/core/qgsexpressionlexer.ll
  9. +25 −19 src/core/qgsexpressionparser.yy
  10. +7 −6 src/core/qgsvectorlayer.cpp
  11. +4 −2 src/core/symbology-ng/qgsinvertedpolygonrenderer.cpp
  12. +1 −1 src/core/symbology-ng/qgslegendsymbolitemv2.cpp
  13. +2 −2 src/gui/attributetable/qgsfieldconditionalformatwidget.cpp
  14. +1 −0 tests/src/core/testqgscolorschemeregistry.cpp
  15. +1 −0 tests/src/core/testqgscomposergroup.cpp
  16. +8 −0 tests/src/core/testqgscomposermodel.cpp
  17. +2 −0 tests/src/core/testqgscomposermultiframe.cpp
  18. +2 −0 tests/src/core/testqgscomposerobject.cpp
  19. +1 −0 tests/src/core/testqgscomposerpicture.cpp
  20. +3 −0 tests/src/core/testqgscomposerrotation.cpp
  21. +1 −0 tests/src/core/testqgscomposertable.cpp
  22. +1 −0 tests/src/core/testqgscomposertablev2.cpp
  23. +4 −0 tests/src/core/testqgscomposerutils.cpp
  24. +5 −3 tests/src/core/testqgsdatadefined.cpp
  25. +2 −4 tests/src/core/testqgsdiagram.cpp
  26. +8 −4 tests/src/core/testqgsexpression.cpp
  27. +4 −3 tests/src/core/testqgsexpressioncontext.cpp
  28. +3 −0 tests/src/core/testqgsgeometry.cpp
  29. +2 −1 tests/src/core/testqgsmaprotation.cpp
  30. +1 −0 tests/src/core/testqgspainteffect.cpp
  31. +2 −2 tests/src/core/testqgsrasterfilewriter.cpp
  32. +11 −3 tests/src/core/testqgsscaleexpression.cpp
  33. +1 −1 tests/src/core/testqgsvectorlayer.cpp
  34. +9 −9 tests/src/gui/testqgsmaptoolzoom.cpp
@@ -299,9 +299,24 @@ class QgsExpression
static const QList<QgsExpression::Function *>& Functions();
static const QStringList& BuiltinFunctions();

/** Registers a function to the expression engine. This is required to allow expressions to utilise the function.
* @param function function to register
* @returns true on successful registration
* @see unregisterFunction
*/
static bool registerFunction( Function* function );

/** Unregisters a function from the expression engine. The function will no longer be usable in expressions.
* @param name function name
* @see registerFunction
*/
static bool unregisterFunction( QString name );

/** Deletes all registered functions whose ownership have been transferred to the expression engine.
* @note added in QGIS 2.12
*/
static void cleanRegisteredFunctions();

// tells whether the identifier is a name of existing function
static bool isFunctionName( const QString& name );

@@ -55,7 +55,7 @@ QgsComposerObject::QgsComposerObject( QgsComposition* composition )

QgsComposerObject::~QgsComposerObject()
{

qDeleteAll( mDataDefinedProperties );
}

bool QgsComposerObject::writeXML( QDomElement &elem, QDomDocument &doc ) const
@@ -146,6 +146,13 @@ const QgsAbstractGeometryV2* QgsGeometry::geometry() const
void QgsGeometry::setGeometry( QgsAbstractGeometryV2* geometry )
{
detach( false );
if ( d->geometry )
{
delete d->geometry;
d->geometry = 0;
}
removeWkbGeos();

d->geometry = geometry;
}

@@ -22,6 +22,7 @@
#include "qgsmaplayerregistry.h"
#include "qgsnetworkaccessmanager.h"
#include "qgsproviderregistry.h"
#include "qgsexpression.h"

#include <QDir>
#include <QFile>
@@ -629,6 +630,14 @@ void QgsApplication::initQgis()
void QgsApplication::exitQgis()
{
delete QgsProviderRegistry::instance();

//Ensure that all remaining deleteLater QObjects are actually deleted before we exit.
//This isn't strictly necessary (since we're exiting anyway) but doing so prevents a lot of
//LeakSanitiser noise which hides real issues
QgsApplication::sendPostedEvents( 0, QEvent::DeferredDelete );

//delete all registered functions from expression engine (see above comment)
QgsExpression::cleanRegisteredFunctions();
}

QString QgsApplication::showSettings()
@@ -56,6 +56,7 @@ QgsDistanceArea::QgsDistanceArea()

//! Copy constructor
QgsDistanceArea::QgsDistanceArea( const QgsDistanceArea & origDA )
: mCoordTransform( 0 )
{
_copy( origDA );
}
@@ -88,6 +89,7 @@ void QgsDistanceArea::_copy( const QgsDistanceArea & origDA )
// Some calculations and trig. Should not be TOO time consuming.
// Alternatively we could copy the temp vars?
computeAreaInit();
delete mCoordTransform;
mCoordTransform = new QgsCoordinateTransform( origDA.mCoordTransform->sourceCrs(), origDA.mCoordTransform->destCRS() );
}

@@ -1767,14 +1767,16 @@ static QVariant fcnGetLayerProperty( const QVariantList& values, const QgsExpres
return QVariant();
}

bool QgsExpression::registerFunction( QgsExpression::Function* function )
bool QgsExpression::registerFunction( QgsExpression::Function* function, bool transferOwnership )
{
int fnIdx = functionIndex( function->name() );
if ( fnIdx != -1 )
{
return false;
}
QgsExpression::gmFunctions.append( function );
if ( transferOwnership )
QgsExpression::gmOwnedFunctions.append( function );
return true;
}

@@ -1794,7 +1796,11 @@ bool QgsExpression::unregisterFunction( QString name )
return false;
}


void QgsExpression::cleanRegisteredFunctions()
{
qDeleteAll( QgsExpression::gmOwnedFunctions );
QgsExpression::gmOwnedFunctions.clear();
}

QStringList QgsExpression::gmBuiltinFunctions;

@@ -1842,6 +1848,7 @@ const QStringList& QgsExpression::BuiltinFunctions()
}

QList<QgsExpression::Function*> QgsExpression::gmFunctions;
QList<QgsExpression::Function*> QgsExpression::gmOwnedFunctions;

const QList<QgsExpression::Function*>& QgsExpression::Functions()
{
@@ -1978,6 +1985,12 @@ const QList<QgsExpression::Function*>& QgsExpression::Functions()
;

QgsExpressionContextUtils::registerContextFunctions();

//QgsExpression has ownership of all built-in functions
Q_FOREACH ( QgsExpression::Function* func, gmFunctions )
{
gmOwnedFunctions << func;
}
}
return gmFunctions;
}
@@ -490,9 +490,28 @@ class CORE_EXPORT QgsExpression
static QStringList gmBuiltinFunctions;
static const QStringList& BuiltinFunctions();

static bool registerFunction( Function* function );
/** Registers a function to the expression engine. This is required to allow expressions to utilise the function.
* @param function function to register
* @param transferOwnership set to true to transfer ownership of function to expression engine
* @returns true on successful registration
* @see unregisterFunction
*/
static bool registerFunction( Function* function, bool transferOwnership = false );

/** Unregisters a function from the expression engine. The function will no longer be usable in expressions.
* @param name function name
* @see registerFunction
*/
static bool unregisterFunction( QString name );

//! List of functions owned by the expression engine
static QList<Function*> gmOwnedFunctions;

/** Deletes all registered functions whose ownership have been transferred to the expression engine.
* @note added in QGIS 2.12
*/
static void cleanRegisteredFunctions();

// tells whether the identifier is a name of existing function
static bool isFunctionName( const QString& name );

@@ -50,8 +50,8 @@ struct expression_parser_context;

#define B_OP(x) yylval->b_op = QgsExpression::x
#define U_OP(x) yylval->u_op = QgsExpression::x
#define TEXT yylval->text = new QString(); *yylval->text = QString::fromUtf8(yytext);
#define TEXT_FILTER(filter_fn) yylval->text = new QString(); *yylval->text = filter_fn( QString::fromUtf8(yytext) );
#define TEXT yylval->text = new QString( QString::fromUtf8(yytext) );
#define TEXT_FILTER(filter_fn) yylval->text = new QString( filter_fn( QString::fromUtf8(yytext) ) );

static QString stripText(QString text)
{
@@ -149,6 +149,8 @@ struct expression_parser_context
%destructor { delete $$; } <node>
%destructor { delete $$; } <nodelist>
%destructor { delete $$; } <text>
%destructor { delete $$; } <whenthen>
%destructor { delete $$; } <whenthenlist>

%%

@@ -181,26 +183,29 @@ expression:
| FUNCTION '(' exp_list ')'
{
int fnIndex = QgsExpression::functionIndex(*$1);
delete $1;
if (fnIndex == -1)
{
// this should not actually happen because already in lexer we check whether an identifier is a known function
// (if the name is not known the token is parsed as a column)
exp_error(parser_ctx, "Function is not known");
delete $3;
YYERROR;
}
if ( QgsExpression::Functions()[fnIndex]->params() != -1
&& QgsExpression::Functions()[fnIndex]->params() != $3->count() )
{
exp_error(parser_ctx, "Function is called with wrong number of arguments");
delete $3;
YYERROR;
}
$$ = new QgsExpression::NodeFunction(fnIndex, $3);
delete $1;
}

| FUNCTION '(' ')'
{
int fnIndex = QgsExpression::functionIndex(*$1);
delete $1;
if (fnIndex == -1)
{
// this should not actually happen because already in lexer we check whether an identifier is a known function
@@ -214,7 +219,6 @@ expression:
YYERROR;
}
$$ = new QgsExpression::NodeFunction(fnIndex, new QgsExpression::NodeList());
delete $1;
}

| expression IN '(' exp_list ')' { $$ = new QgsExpression::NodeInOperator($1, $4, false); }
@@ -236,30 +240,31 @@ expression:
if (fnIndex == -1)
{
if ( !QgsExpression::hasSpecialColumn( *$1 ) )
{
{
exp_error(parser_ctx, "Special column is not known");
YYERROR;
}
// $var is equivalent to _specialcol_( "$var" )
QgsExpression::NodeList* args = new QgsExpression::NodeList();
QgsExpression::NodeLiteral* literal = new QgsExpression::NodeLiteral( *$1 );
args->append( literal );
$$ = new QgsExpression::NodeFunction( QgsExpression::functionIndex( "_specialcol_" ), args );
delete $1;
YYERROR;
}
// $var is equivalent to _specialcol_( "$var" )
QgsExpression::NodeList* args = new QgsExpression::NodeList();
QgsExpression::NodeLiteral* literal = new QgsExpression::NodeLiteral( *$1 );
args->append( literal );
$$ = new QgsExpression::NodeFunction( QgsExpression::functionIndex( "_specialcol_" ), args );
}
else
{
$$ = new QgsExpression::NodeFunction( fnIndex, NULL );
delete $1;
}
else
{
$$ = new QgsExpression::NodeFunction( fnIndex, NULL );
}
delete $1;
}

// variables
| VARIABLE
{
// @var is equivalent to var( "var" )
QgsExpression::NodeList* args = new QgsExpression::NodeList();
QgsExpression::NodeLiteral* literal = new QgsExpression::NodeLiteral( QString(*$1).mid(1) );
args->append( literal );
// @var is equivalent to var( "var" )
QgsExpression::NodeList* args = new QgsExpression::NodeList();
QgsExpression::NodeLiteral* literal = new QgsExpression::NodeLiteral( QString(*$1).mid(1) );
args->append( literal );
$$ = new QgsExpression::NodeFunction( QgsExpression::functionIndex( "var" ), args );
delete $1;
}
@@ -308,6 +313,7 @@ QgsExpression::Node* parseExpression(const QString& str, QString& parserErrorMsg
else // error?
{
parserErrorMsg = ctx.errorMsg;
delete ctx.rootNode;
return NULL;
}
}
@@ -186,6 +186,7 @@ QgsVectorLayer::~QgsVectorLayer()
delete mCache;
delete mLabel;
delete mDiagramLayerSettings;
delete mDiagramRenderer;

delete mActions;

@@ -2244,7 +2245,7 @@ bool QgsVectorLayer::deleteAttributes( QList<int> attrs )

qSort( attrs.begin(), attrs.end(), qGreater<int>() );

Q_FOREACH( int attr, attrs )
Q_FOREACH ( int attr, attrs )
{
if ( deleteAttribute( attr ) )
{
@@ -3003,7 +3004,7 @@ void QgsVectorLayer::uniqueValues( int index, QList<QVariant> &uniqueValues, int
if ( mEditBuffer )
{
QSet<QString> vals;
Q_FOREACH( const QVariant& v, uniqueValues )
Q_FOREACH ( const QVariant& v, uniqueValues )
{
vals << v.toString();
}
@@ -3833,7 +3834,7 @@ void QgsVectorLayer::invalidateSymbolCountedFlag()

void QgsVectorLayer::onRelationsLoaded()
{
Q_FOREACH( QgsAttributeEditorElement* elem, mAttributeEditorElements )
Q_FOREACH ( QgsAttributeEditorElement* elem, mAttributeEditorElements )
{
if ( elem->type() == QgsAttributeEditorElement::AeTypeContainer )
{
@@ -3842,7 +3843,7 @@ void QgsVectorLayer::onRelationsLoaded()
continue;

QList<QgsAttributeEditorElement*> relations = cont->findElements( QgsAttributeEditorElement::AeTypeRelation );
Q_FOREACH( QgsAttributeEditorElement* relElem, relations )
Q_FOREACH ( QgsAttributeEditorElement* relElem, relations )
{
QgsAttributeEditorRelation* rel = dynamic_cast< QgsAttributeEditorRelation* >( relElem );
if ( !rel )
@@ -3911,7 +3912,7 @@ QDomElement QgsAttributeEditorContainer::toDomElement( QDomDocument& doc ) const
QDomElement elem = doc.createElement( "attributeEditorContainer" );
elem.setAttribute( "name", mName );

Q_FOREACH( QgsAttributeEditorElement* child, mChildren )
Q_FOREACH ( QgsAttributeEditorElement* child, mChildren )
{
elem.appendChild( child->toDomElement( doc ) );
}
@@ -3932,7 +3933,7 @@ QList<QgsAttributeEditorElement*> QgsAttributeEditorContainer::findElements( Qgs
{
QList<QgsAttributeEditorElement*> results;

Q_FOREACH( QgsAttributeEditorElement* elem, mChildren )
Q_FOREACH ( QgsAttributeEditorElement* elem, mChildren )
{
if ( elem->type() == type )
{
@@ -337,7 +337,7 @@ QgsFeatureRendererV2* QgsInvertedPolygonRenderer::clone() const
}
else
{
newRenderer = new QgsInvertedPolygonRenderer( mSubRenderer->clone() );
newRenderer = new QgsInvertedPolygonRenderer( mSubRenderer.data() );
}
newRenderer->setPreprocessingEnabled( preprocessingEnabled() );
copyPaintEffect( newRenderer );
@@ -351,7 +351,9 @@ QgsFeatureRendererV2* QgsInvertedPolygonRenderer::create( QDomElement& element )
QDomElement embeddedRendererElem = element.firstChildElement( "renderer-v2" );
if ( !embeddedRendererElem.isNull() )
{
r->setEmbeddedRenderer( QgsFeatureRendererV2::load( embeddedRendererElem ) );
QgsFeatureRendererV2* renderer = QgsFeatureRendererV2::load( embeddedRendererElem );
r->setEmbeddedRenderer( renderer );
delete renderer;
}
r->setPreprocessingEnabled( element.attribute( "preprocessing", "0" ).toInt() == 1 );
return r;
@@ -57,7 +57,7 @@ QgsLegendSymbolItemV2& QgsLegendSymbolItemV2::operator=( const QgsLegendSymbolIt
if ( this == &other )
return *this;

setSymbol( other.mSymbol ? other.mSymbol->clone() : 0 );
setSymbol( other.mSymbol );
mLabel = other.mLabel;
mKey = other.mKey;
mCheckable = other.mCheckable;
@@ -27,8 +27,8 @@ QgsFieldConditionalFormatWidget::QgsFieldConditionalFormatWidget( QWidget *paren
btnBackgroundColor->setShowNoColor( true );
btnTextColor->setAllowAlpha( true );
btnTextColor->setShowNoColor( true );
mModel = new QStandardItemModel();
mPresetsModel = new QStandardItemModel();
mPresetsModel = new QStandardItemModel( listView );
mModel = new QStandardItemModel( listView );
listView->setModel( mModel );
mPresetsList->setModel( mPresetsModel );

@@ -165,6 +165,7 @@ void TestQgsColorSchemeRegistry::removeScheme()
QVERIFY( registry->schemes().length() == 0 );
//try removing a scheme not in the registry
QVERIFY( !registry->removeColorScheme( recentScheme ) );
delete recentScheme;
}

void TestQgsColorSchemeRegistry::matchingSchemes()

0 comments on commit 9094575

Please sign in to comment.
You can’t perform that action at this time.