Skip to content

Commit

Permalink
Use client side default values when creating new features
Browse files Browse the repository at this point in the history
Sponsored by DB Fahrwegdienste GmbH
  • Loading branch information
nyalldawson committed Aug 30, 2016
1 parent 546cd67 commit 3a14e77
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 13 deletions.
19 changes: 17 additions & 2 deletions src/app/qgisapp.cpp
Expand Up @@ -7380,6 +7380,11 @@ void QgisApp::editPaste( QgsMapLayer *destinationLayer )
remap.insert( idx, dst );
}

QgsExpressionContext context;
context << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope()
<< QgsExpressionContextUtils::layerScope( pasteVectorLayer );

int dstAttrCount = pasteVectorLayer->fields().count();

QgsFeatureList::iterator featureIt = features.begin();
Expand All @@ -7391,8 +7396,18 @@ void QgisApp::editPaste( QgsMapLayer *destinationLayer )
// pre-initialized with default values
for ( int dst = 0; dst < dstAttr.count(); ++dst )
{
QVariant defVal( pasteVectorLayer->dataProvider()->defaultValue( dst ) );
if ( !defVal.isNull() )
QVariant defVal;
if ( !pasteVectorLayer->defaultValueExpression( dst ).isEmpty() )
{
// client side default expression set - use this in preference to provider default
defVal = pasteVectorLayer->defaultValue( dst, *featureIt, &context );
}
else
{
defVal = pasteVectorLayer->dataProvider()->defaultValue( dst );
}

if ( defVal.isValid() && !defVal.isNull() )
{
dstAttr[ dst ] = defVal;
}
Expand Down
13 changes: 12 additions & 1 deletion src/app/qgsmergeattributesdialog.cpp
Expand Up @@ -522,14 +522,21 @@ QgsAttributes QgsMergeAttributesDialog::mergedAttributes() const
return QgsAttributes();
}

QgsExpressionContext context;
context << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope()
<< QgsExpressionContextUtils::layerScope( mVectorLayer );

int widgetIndex = 0;
QgsAttributes results( mFields.count() );
for ( int fieldIdx = 0; fieldIdx < mFields.count(); ++fieldIdx )
{
if ( mHiddenAttributes.contains( fieldIdx ) )
{
//hidden attribute, set to default value
if ( mVectorLayer->dataProvider() )
if ( !mVectorLayer->defaultValueExpression( fieldIdx ).isEmpty() )
results[fieldIdx] = mVectorLayer->defaultValue( fieldIdx, mFeatureList.at( 0 ), &context );
else if ( mVectorLayer->dataProvider() )
results[fieldIdx] = mVectorLayer->dataProvider()->defaultValue( fieldIdx );
else
results[fieldIdx] = QVariant();
Expand All @@ -551,6 +558,10 @@ QgsAttributes QgsMergeAttributesDialog::mergedAttributes() const
{
results[fieldIdx] = currentItem->data( Qt::DisplayRole );
}
else if ( !mVectorLayer->defaultValueExpression( fieldIdx ).isEmpty() )
{
results[fieldIdx] = mVectorLayer->defaultValue( fieldIdx, mFeatureList.at( 0 ), &context );
}
else if ( mVectorLayer->dataProvider() )
{
results[fieldIdx] = mVectorLayer->dataProvider()->defaultValue( fieldIdx );
Expand Down
23 changes: 13 additions & 10 deletions src/core/qgsofflineediting.cpp
Expand Up @@ -746,14 +746,12 @@ void QgsOfflineEditing::applyFeaturesAdded( QgsVectorLayer* offlineLayer, QgsVec
QString sql = QString( "SELECT \"fid\" FROM 'log_added_features' WHERE \"layer_id\" = %1" ).arg( layerId );
QList<int> newFeatureIds = sqlQueryInts( db, sql );

// get default value for each field
const QgsFields& remoteFlds = remoteLayer->fields();
QVector<QVariant> defaultValues( remoteFlds.count() );
for ( int i = 0; i < remoteFlds.count(); ++i )
{
if ( remoteFlds.fieldOrigin( i ) == QgsFields::OriginProvider )
defaultValues[i] = remoteLayer->dataProvider()->defaultValue( remoteFlds.fieldOriginIndex( i ) );
}
QgsFields remoteFlds = remoteLayer->fields();

QgsExpressionContext context;
context << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope()
<< QgsExpressionContextUtils::layerScope( remoteLayer );

// get new features from offline layer
QgsFeatureList features;
Expand Down Expand Up @@ -789,8 +787,13 @@ void QgsOfflineEditing::applyFeaturesAdded( QgsVectorLayer* offlineLayer, QgsVec
// (important especially e.g. for postgis primary key generated from a sequence)
for ( int k = 0; k < newAttrs.count(); ++k )
{
if ( newAttrs.at( k ).isNull() && !defaultValues.at( k ).isNull() )
newAttrs[k] = defaultValues.at( k );
if ( !newAttrs.at( k ).isNull() )
continue;

if ( !remoteLayer->defaultValueExpression( k ).isEmpty() )
newAttrs[k] = remoteLayer->defaultValue( k, f, &context );
else if ( remoteFlds.fieldOrigin( k ) == QgsFields::OriginProvider )
newAttrs[k] = remoteLayer->dataProvider()->defaultValue( remoteFlds.fieldOriginIndex( k ) );
}

f.setAttributes( newAttrs );
Expand Down

0 comments on commit 3a14e77

Please sign in to comment.