Skip to content
Permalink
Browse files

Convert values to target field format

For the field calculator and virtual fields.

Fix #11000
Fix #10995
Fix #10993
  • Loading branch information
m-kuhn committed Oct 6, 2014
1 parent 11e3044 commit 7318c73012a2c7245f5ac7a268a457ae84f0a4de
@@ -110,6 +110,65 @@ public:

/**Formats string for display*/
QString displayString( const QVariant& v ) const;


/**
* Converts the provided variant to a compatible format
*
* @param v The value to convert
*
* @return True if the conversion was successful
*/
QVariant convertCompatible( QVariant& v ) const;
%MethodCode
PyObject *sipParseErr = NULL;

{
QVariant * a0;
int a0State = 0;
const QgsField *sipCpp;

if (sipParseArgs(&sipParseErr, sipArgs, "BJ1", &sipSelf, sipType_QgsField, &sipCpp, sipType_QVariant,&a0, &a0State))
{
bool sipRes;

Py_BEGIN_ALLOW_THREADS
try
{
QgsDebugMsg( a0->toString() );
sipRes = sipCpp->convertCompatible(*a0);
QgsDebugMsg( a0->toString() );
}
catch (...)
{
Py_BLOCK_THREADS

sipReleaseType(a0,sipType_QVariant,a0State);
sipRaiseUnknownException();
return NULL;
}

Py_END_ALLOW_THREADS

PyObject* res = sipConvertFromType( a0, sipType_QVariant, NULL );
sipReleaseType(a0,sipType_QVariant,a0State);

if ( !sipRes )
{
PyErr_SetString(PyExc_ValueError,
QString( "Value %1 (%2) could not be converted to field type %3." ).arg( a0->toString() ).arg ( a0->typeName() ).arg( sipCpp->type() ).toUtf8().constData() );
sipError = sipErrorFail;
}

return res;
}
}

/* Raise an exception if the arguments couldn't be parsed. */
sipNoMethod(sipParseErr, sipName_QgsField, sipName_convertCompatible, doc_QgsField_convertCompatible);

return NULL;
%End
}; // class QgsField


@@ -127,6 +127,8 @@ void QgsFieldCalculator::accept()
return;
}

const QgsField& field = mVectorLayer->pendingFields()[mAttributeId];

QApplication::setOverrideCursor( Qt::WaitCursor );

mVectorLayer->beginEditCommand( "Field calculator" );
@@ -198,7 +200,7 @@ void QgsFieldCalculator::accept()
bool newField = !mUpdateExistingGroupBox->isChecked();
QVariant emptyAttribute;
if ( newField )
emptyAttribute = QVariant( mVectorLayer->pendingFields()[mAttributeId].type() );
emptyAttribute = QVariant( field.type() );

QgsFeatureIterator fit = mVectorLayer->getFeatures( QgsFeatureRequest().setFlags( useGeometry ? QgsFeatureRequest::NoFlags : QgsFeatureRequest::NoGeometry ) );
while ( fit.nextFeature( feature ) )
@@ -210,9 +212,9 @@ void QgsFieldCalculator::accept()
continue;
}
}

exp.setCurrentRowNumber( rownum );
QVariant value = exp.evaluate( &feature );
field.convertCompatible( value );
if ( exp.hasEvalError() )
{
calculationSuccess = false;
@@ -17,6 +17,7 @@
#include "qgsfield.h"

#include <QSettings>
#include <QtCore/qmath.h>

#if 0
QgsField::QgsField( QString nam, QString typ, int len, int prec, bool num,
@@ -128,6 +129,27 @@ QString QgsField::displayString( const QVariant& v ) const
return v.toString();
}

bool QgsField::convertCompatible( QVariant& v ) const
{
if ( v.isNull() )
{
v.convert( mType );
return true;
}

if ( !v.convert( mType ) )
{
return false;
}

if ( mType == QVariant::Double && mPrecision > 0 )
{
v = qRound64( v.toDouble() * qPow( 10, mPrecision ) ) / qPow( 10, mPrecision );
return true;
}

return true;
}

////////////////////////////////////////////////////////////////////////////

@@ -129,6 +129,15 @@ class CORE_EXPORT QgsField
/** Formats string for display*/
QString displayString( const QVariant& v ) const;

/**
* Converts the provided variant to a compatible format
*
* @param v The value to convert
*
* @return True if the conversion was successful
*/
bool convertCompatible( QVariant& v ) const;

private:

//! Name
@@ -559,6 +559,7 @@ void QgsVectorLayerFeatureIterator::addVirtualAttributes( QgsFeature& f )
{
QgsExpression* exp = it.value();
QVariant val = exp->evaluate( f );
mSource->mFields.at( it.key() ).convertCompatible( val );;
f.setAttribute( it.key(), val );
}
}

0 comments on commit 7318c73

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