Skip to content

Commit

Permalink
[GRASS] editing fix
Browse files Browse the repository at this point in the history
  • Loading branch information
blazek committed Oct 20, 2015
1 parent f5a93ef commit d2564bb
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 57 deletions.
141 changes: 87 additions & 54 deletions src/providers/grass/qgsgrassprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1297,80 +1297,104 @@ void QgsGrassProvider::onFeatureAdded( QgsFeatureId fid )
mLayer->map()->newCats()[fid] = newCat;
QgsDebugMsg( QString( "newCats[%1] = %2" ).arg( fid ).arg( newCat ) );

QString error;
// if the cat is user defined, the record may alredy exist
if ( mLayer->attributes().contains( newCat ) )
// Currently neither entering new cat nor changing existing cat is allowed
#if 0
// There may be other new features with the same cat which we have to update
Q_FOREACH ( QgsFeatureId addedFid, addedFeatures.keys() )
{
QgsDebugMsg( "record exists" );
// TODO: open warning dialog?
// For now we are expecting that user knows what he is doing.
// We update existing record by non null values and set feature null values to existing values
mLayer->updateAttributes( newCat, feature, error ); // also updates feature by existing non null attributes

// There may be other new features with the same cat which we have to update
Q_FOREACH ( QgsFeatureId addedFid, addedFeatures.keys() )
if ( addedFid == fid )
{
if ( addedFid == fid )
{
continue;
}
int addedCat = mLayer->map()->newCats().value( addedFid ); // it should always exist
QgsDebugMsg( QString( "addedFid = %1 addedCat = %2" ).arg( addedFid ).arg( addedCat ) );
if ( addedCat == newCat )
continue;
}
int addedCat = mLayer->map()->newCats().value( addedFid ); // it should always exist
QgsDebugMsg( QString( "addedFid = %1 addedCat = %2" ).arg( addedFid ).arg( addedCat ) );
if ( addedCat == newCat )
{
QgsFeature addedFeature = addedFeatures[addedFid];
// TODO: better to update form mLayer->attributes() ?
for ( int i = 0; i < feature.fields()->size(); i++ )
{
QgsFeature addedFeature = addedFeatures[addedFid];
// TODO: better to update form mLayer->attributes() ?
for ( int i = 0; i < feature.fields()->size(); i++ )
if ( feature.fields()->field( i ).name() == QgsGrassVectorMap::topoSymbolFieldName() )
{
if ( feature.fields()->field( i ).name() == QgsGrassVectorMap::topoSymbolFieldName() )
{
continue;
}
if ( feature.attributes().at( i ).isNull() )
{
continue;
}
addedFeature.setAttribute( i, feature.attributes().at( i ) );
continue;
}
addedFeatures[addedFid] = addedFeature;
if ( feature.attributes().at( i ).isNull() )
{
continue;
}
addedFeature.setAttribute( i, feature.attributes().at( i ) );
}
addedFeatures[addedFid] = addedFeature;
}
}

// Update all changed attributes
// TODO: table does not get refreshed immediately
QgsChangedAttributesMap &changedAttributes = const_cast<QgsChangedAttributesMap &>( mEditBuffer->changedAttributeValues() );
Q_FOREACH ( QgsFeatureId changedFid, changedAttributes.keys() )
// Update all changed attributes
QgsChangedAttributesMap &changedAttributes = const_cast<QgsChangedAttributesMap &>( mEditBuffer->changedAttributeValues() );
Q_FOREACH ( QgsFeatureId changedFid, changedAttributes.keys() )
{
int changedCat = QgsGrassFeatureIterator::catFromFid( changedFid );
int realChangedCat = changedCat;
if ( mLayer->map()->newCats().contains( changedFid ) )
{
int changedCat = QgsGrassFeatureIterator::catFromFid( changedFid );
int realChangedCat = changedCat;
if ( mLayer->map()->newCats().contains( changedFid ) )
{
realChangedCat = mLayer->map()->newCats().value( changedFid );
}
QgsDebugMsg( QString( "changedFid = %1 changedCat = %2 realChangedCat = %3" )
.arg( changedFid ).arg( changedCat ).arg( realChangedCat ) );
if ( realChangedCat == newCat )
realChangedCat = mLayer->map()->newCats().value( changedFid );
}
QgsDebugMsg( QString( "changedFid = %1 changedCat = %2 realChangedCat = %3" )
.arg( changedFid ).arg( changedCat ).arg( realChangedCat ) );
if ( realChangedCat == newCat )
{
QgsAttributeMap attributeMap = changedAttributes[changedFid];
Q_FOREACH ( int index, attributeMap.keys() )
{
QgsAttributeMap attributeMap = changedAttributes[changedFid];
Q_FOREACH ( int index, attributeMap.keys() )
{
attributeMap[index] = feature.attributes().value( index );
}
changedAttributes[changedFid] = attributeMap;
attributeMap[index] = feature.attributes().value( index );
}
changedAttributes[changedFid] = attributeMap;
}
}
else
#endif

if ( mLayer->hasTable() )
{
if ( mLayer->hasTable() )
QString error;
// The record may exist if cat is manually defined by user (currently editing of cat column is disabled )
bool recordExists = mLayer->recordExists( newCat, error );
if ( !error.isEmpty() )
{
mLayer->insertAttributes( newCat, feature, error );
QgsGrass::warning( error );
}
else
{
error.clear();
if ( !recordExists )
{
QgsDebugMsg( "record does not exist" );
if ( mLayer->attributes().contains( newCat ) )
{
QgsDebugMsg( "attributes exist -> reinsert" );
mLayer->reinsertAttributes( newCat, error );
}
else
{
mLayer->insertAttributes( newCat, feature, error );
}
}
else
{
// Currently disabled
#if 0
// Manual entry of cat is not currently allowed
// TODO: open warning dialog?
// For now we are expecting that user knows what he is doing.
// We update existing record by non null values and set feature null values to existing values
mLayer->updateAttributes( newCat, feature, error ); // also updates feature by existing non null attributes
#endif
}
if ( !error.isEmpty() )
{
QgsGrass::warning( error );
}
}
}

// update table
emit dataChanged();
}
Expand Down Expand Up @@ -1507,7 +1531,16 @@ void QgsGrassProvider::onFeatureDeleted( QgsFeatureId fid )

int oldLid = QgsGrassFeatureIterator::lidFromFid( fid );
int cat = QgsGrassFeatureIterator::catFromFid( fid );
int layerField = QgsGrassFeatureIterator::layerFromFid( fid );
int layerField = 0;
if ( FID_IS_NEW( fid ) )
{
layerField = mLayerField;
}
else
{
layerField = QgsGrassFeatureIterator::layerFromFid( fid );
}

int realLine = oldLid;
int realCat = cat;
if ( mLayer->map()->newLids().contains( oldLid ) ) // if it was changed already
Expand Down
4 changes: 2 additions & 2 deletions src/providers/grass/qgsgrassvectormap.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class GRASS_LIB_EXPORT QgsGrassVectorMap : public QObject
QHash<int, int> & newLids() { return mNewLids; }
QHash<int, QgsAbstractGeometryV2*> & oldGeometries() { return mOldGeometries; }
QHash<int, int> & oldTypes() { return mOldTypes; }
QHash<int, int> & newCats() { return mNewCats; }
QHash<QgsFeatureId, int> & newCats() { return mNewCats; }

/** Get geometry of line.
* @return geometry (point,line or polygon(GV_FACE)) or 0 */
Expand Down Expand Up @@ -193,7 +193,7 @@ class GRASS_LIB_EXPORT QgsGrassVectorMap : public QObject
QHash<int, int> mOldTypes;
// New categories attached to new features or old features without category
// fid -> cat, the fid may be old fid without category or new (negative) feature id
QHash<int, int> mNewCats;
QHash<QgsFeatureId, int> mNewCats;

// Mutex used to avoid concurrent read/write, used only in editing mode
QMutex mReadWriteMutex;
Expand Down
35 changes: 34 additions & 1 deletion src/providers/grass/qgsgrassvectormaplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -696,12 +696,14 @@ void QgsGrassVectorMapLayer::addColumn( const QgsField &field, QString &error )
{
// the column is already in attributes (delete column undo)
QgsDebugMsg( "insert old values" );
printCachedAttributes();
QStringList errors;
Q_FOREACH ( int cat, mAttributes.keys() )
{
QVariant value = mAttributes.value( cat ).value( index );
QString valueString = quotedValue( value );
QString query = QString( "UPDATE %1 SET %2 = %3" ).arg( mFieldInfo->table, field.name(), valueString );
QString query = QString( "UPDATE %1 SET %2 = %3 WHERE %4 = %5" )
.arg( mFieldInfo->table ).arg( field.name() ).arg( valueString ).arg( keyColumnName() ).arg( cat );
QString err;
executeSql( query, err );
if ( !err.isEmpty() )
Expand Down Expand Up @@ -856,6 +858,7 @@ void QgsGrassVectorMapLayer::insertAttributes( int cat, const QgsFeature &featur
}
mAttributes[cat] = values;
}
printCachedAttributes();
}

void QgsGrassVectorMapLayer::reinsertAttributes( int cat, QString &error )
Expand Down Expand Up @@ -902,10 +905,12 @@ void QgsGrassVectorMapLayer::reinsertAttributes( int cat, QString &error )
{
QgsDebugMsg( "cat not found in mAttributes -> don't restore" );
}
printCachedAttributes();
}

void QgsGrassVectorMapLayer::updateAttributes( int cat, QgsFeature &feature, QString &error, bool nullValues )
{
Q_UNUSED( nullValues )
QgsDebugMsg( QString( "mField = %1 cat = %2" ).arg( mField ).arg( cat ) );

if ( !mHasTable )
Expand Down Expand Up @@ -933,6 +938,8 @@ void QgsGrassVectorMapLayer::updateAttributes( int cat, QgsFeature &feature, QSt

int cacheIndex = mAttributeFields.indexFromName( name );

// Merging old and new attributes currently not allowed (entering changing cat)
#if 0
if ( valueVariant.isNull() && !nullValues )
{
// update feature null values by existing values
Expand All @@ -942,6 +949,7 @@ void QgsGrassVectorMapLayer::updateAttributes( int cat, QgsFeature &feature, QSt
}
continue;
}
#endif

updates << name + " = " + quotedValue( valueVariant );

Expand Down Expand Up @@ -973,6 +981,7 @@ void QgsGrassVectorMapLayer::updateAttributes( int cat, QgsFeature &feature, QSt
mAttributes[cat][index] = cacheUpdates[index];
}
}
printCachedAttributes();
}

void QgsGrassVectorMapLayer::deleteAttribute( int cat, QString &error )
Expand Down Expand Up @@ -1123,4 +1132,28 @@ void QgsGrassVectorMapLayer::changeAttributeValue( int cat, QgsField field, QVar
return;
}
mAttributes[cat][index] = value;
printCachedAttributes();
}

void QgsGrassVectorMapLayer::printCachedAttributes()
{
#ifdef QGISDEBUG
QgsDebugMsgLevel( QString( "mAttributes.size() = %1" ).arg( mAttributes.size() ), 4 );
QStringList names;
for ( int i = 0; i < mAttributeFields.size(); i++ )
{
names << mAttributeFields[i].name();
}
QgsDebugMsgLevel( names.join( "|" ), 4 );

Q_FOREACH ( int cat, mAttributes.keys() )
{
QStringList values;
for ( int i = 0; i < mAttributes.value( cat ).size(); i++ )
{
values << mAttributes.value( cat ).value( i ).toString();
}
QgsDebugMsgLevel( QString( "cat = %1 : %2" ).arg( cat ).arg( values.join( "|" ) ), 4 );
}
#endif
}
3 changes: 3 additions & 0 deletions src/providers/grass/qgsgrassvectormaplayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ class GRASS_LIB_EXPORT QgsGrassVectorMapLayer : public QObject
// update fields to real state
void updateFields();

// for debug only
void printCachedAttributes();

private:
QString quotedValue( QVariant value );
dbDriver * openDriver( QString &error );
Expand Down

0 comments on commit d2564bb

Please sign in to comment.