Skip to content

Commit

Permalink
[GRASS] prevent changing attributes of different layer
Browse files Browse the repository at this point in the history
  • Loading branch information
blazek committed Oct 21, 2015
1 parent 86505e0 commit 29b061c
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 5 deletions.
12 changes: 8 additions & 4 deletions src/providers/grass/qgsgrassfeatureiterator.cpp
Expand Up @@ -649,6 +649,11 @@ int QgsGrassFeatureIterator::catFromFid( QgsFeatureId fid )
return fid % 1000000000;
}

QVariant QgsGrassFeatureIterator::nonEditableValue( int layerNumber )
{
return tr( "<not editable (layer %1)>" ).arg( layerNumber );
}

void QgsGrassFeatureIterator::setFeatureAttributes( int cat, QgsFeature *feature, QgsGrassVectorMap::TopoSymbol symbol )
{
QgsDebugMsgLevel( QString( "setFeatureAttributes cat = %1" ).arg( cat ), 3 );
Expand Down Expand Up @@ -701,15 +706,14 @@ void QgsGrassFeatureIterator::setFeatureAttributes( int cat, QgsFeature *feature
}
else
{
// TODO: use real layer keyColumn(), but to get it the layer must be first opened and attributes loaded
int keyColumn = 0;
if ( *iter == keyColumn )
// We are setting cat of different layer in cat column of this layer
if ( *iter == mSource->mLayer->keyColumn() )
{
value = QVariant( cat );
}
else
{
value = tr( "<not editable (layer %1)>" ).arg( layerNumber );
value = nonEditableValue( layerNumber );
}
}
QgsDebugMsgLevel( QString( "iter = %1 value = %2" ).arg( *iter ).arg( value.toString() ), 3 );
Expand Down
3 changes: 3 additions & 0 deletions src/providers/grass/qgsgrassfeatureiterator.h
Expand Up @@ -96,6 +96,9 @@ class GRASS_LIB_EXPORT QgsGrassFeatureIterator : public QObject, public QgsAbstr
// Get GRASS cat from QGIS fid
static int catFromFid( QgsFeatureId fid );

// get attribute value to be used in different layer when it is edited
static QVariant nonEditableValue( int layerNumber );

public slots:
/** Cancel iterator, iterator will be closed on next occasion, probably when next getFeature() gets called.
* This function can be called directly from other threads (setting bool is atomic) */
Expand Down
27 changes: 26 additions & 1 deletion src/providers/grass/qgsgrassprovider.cpp
Expand Up @@ -1709,8 +1709,33 @@ void QgsGrassProvider::onAttributeValueChanged( QgsFeatureId fid, int idx, const
{
QgsDebugMsg( QString( "fid = %1 idx = %2 value = %3" ).arg( fid ).arg( idx ).arg( value.toString() ) );

int oldLid = QgsGrassFeatureIterator::lidFromFid( fid );
int layerField = QgsGrassFeatureIterator::layerFromFid( fid );
int cat = QgsGrassFeatureIterator::catFromFid( fid );
QgsDebugMsg( QString( "layerField = %1" ).arg( layerField ) );

if ( !FID_IS_NEW( fid ) && layerField != mLayerField )
{
QgsDebugMsg( "changing attributes in different layer is not allowed" );
// reset the value
QgsChangedAttributesMap &changedAttributes = const_cast<QgsChangedAttributesMap &>( mEditBuffer->changedAttributeValues() );
if ( idx == mLayer->keyColumn() )
{
// should not happen because cat field is not editable
changedAttributes[fid][idx] = cat;
}
else
{
changedAttributes[fid][idx] = QgsGrassFeatureIterator::nonEditableValue( layerField );
}
// update table
// TODO: This would be too slow with buld update (field calculator for example), causing update
// of the whole table after each change. How to update single row?
//emit dataChanged();
return;
}

int oldLid = QgsGrassFeatureIterator::lidFromFid( fid );

int realLine = oldLid;
int realCat = cat;
if ( mLayer->map()->newLids().contains( oldLid ) ) // if it was changed already
Expand Down

0 comments on commit 29b061c

Please sign in to comment.