1 change: 0 additions & 1 deletion src/app/qgsfieldcalculator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,6 @@ void QgsFieldCalculator::accept()
rownum++;
}


if ( !calculationSuccess )
{
QMessageBox::critical( 0, tr( "Error" ), tr( "An error occured while evaluating the calculation string:\n%1" ).arg( error ) );
Expand Down
3 changes: 3 additions & 0 deletions src/core/qgsvectorlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3263,17 +3263,20 @@ void QgsVectorLayer::setRendererV2( QgsFeatureRendererV2 *r )
void QgsVectorLayer::beginEditCommand( QString text )
{
undoStack()->beginMacro( text );
emit editCommandStarted( text );
}

void QgsVectorLayer::endEditCommand()
{
undoStack()->endMacro();
emit editCommandEnded();
}

void QgsVectorLayer::destroyEditCommand()
{
undoStack()->endMacro();
undoStack()->undo();
emit editCommandDestroyed();
}


Expand Down
21 changes: 21 additions & 0 deletions src/core/qgsvectorlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -1539,6 +1539,27 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
/** Signal emitted when setLayerTransparency() is called */
void layerTransparencyChanged( int layerTransparency );

/**
* Signal emitted when a new edit command has been started
*
* @param text Description for this edit command
*/
void editCommandStarted( const QString& text );

/**
* Signal emitted, when an edit command successfully ended
* @note This does not mean it is also committed, only that it is written
* to the edit buffer. See {@link beforeCommitChanges()}
*/
void editCommandEnded();

/**
* Signal emitted, whan an edit command is destroyed
* @note This is not a rollback, it is only related to the current edit command.
* See {@link beforeRollBack()}
*/
void editCommandDestroyed();

private slots:
void onRelationsLoaded();

Expand Down
77 changes: 58 additions & 19 deletions src/gui/attributetable/qgsattributetablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ QgsAttributeTableModel::QgsAttributeTableModel( QgsVectorLayerCache *layerCache,
connect( layer(), SIGNAL( featureDeleted( QgsFeatureId ) ), this, SLOT( featureDeleted( QgsFeatureId ) ) );
connect( layer(), SIGNAL( attributeDeleted( int ) ), this, SLOT( attributeDeleted( int ) ) );
connect( layer(), SIGNAL( updatedFields() ), this, SLOT( updatedFields() ) );
connect( layer(), SIGNAL( editCommandEnded() ), this, SLOT( editCommandEnded() ) );
connect( mLayerCache, SIGNAL( featureAdded( QgsFeatureId ) ), this, SLOT( featureAdded( QgsFeatureId ) ) );
connect( mLayerCache, SIGNAL( cachedLayerDeleted() ), this, SLOT( layerDeleted() ) );
}
Expand Down Expand Up @@ -162,6 +163,14 @@ void QgsAttributeTableModel::updatedFields()
emit modelChanged();
}

void QgsAttributeTableModel::editCommandEnded()
{
reload( createIndex( mChangedCellBounds.top(), mChangedCellBounds.left() ),
createIndex( mChangedCellBounds.bottom(), mChangedCellBounds.right() ) );

mChangedCellBounds = QRect();
}

void QgsAttributeTableModel::attributeDeleted( int idx )
{
if ( idx == mCachedField )
Expand Down Expand Up @@ -190,31 +199,39 @@ void QgsAttributeTableModel::layerDeleted()
void QgsAttributeTableModel::attributeValueChanged( QgsFeatureId fid, int idx, const QVariant &value )
{
QgsDebugMsgLevel( QString( "(%4) fid: %1, idx: %2, value: %3" ).arg( fid ).arg( idx ).arg( value.toString() ).arg( mFeatureRequest.filterType() ), 3 );
if ( loadFeatureAtId( fid ) )
// No filter request: skip all possibly heavy checks
if ( mFeatureRequest.filterType() == QgsFeatureRequest::FilterNone )
{
if ( mFeatureRequest.acceptFeature( mFeat ) )
setData( index( idToRow( fid ), fieldCol( idx ) ), value, Qt::EditRole );
}
else
{
if ( loadFeatureAtId( fid ) )
{
if ( !mIdRowMap.contains( fid ) )
if ( mFeatureRequest.acceptFeature( mFeat ) )
{
// Feature changed in such a way, it will be shown now
featureAdded( fid );
if ( !mIdRowMap.contains( fid ) )
{
// Feature changed in such a way, it will be shown now
featureAdded( fid );
}
else
{
if ( idx == mCachedField )
mFieldCache[ fid ] = value;
// Update representation
setData( index( idToRow( fid ), fieldCol( idx ) ), value, Qt::EditRole );
}
}
else
{
if ( idx == mCachedField )
mFieldCache[ fid ] = value;
// Update representation
setData( index( idToRow( fid ), fieldCol( idx ) ), value, Qt::EditRole );
}
}
else
{
if ( mIdRowMap.contains( fid ) )
{
// Feature changed such, that it is no longer shown
featureDeleted( fid );
if ( mIdRowMap.contains( fid ) )
{
// Feature changed such, that it is no longer shown
featureDeleted( fid );
}
// else: we don't care
}
// else: we don't care
}
}
}
Expand Down Expand Up @@ -592,7 +609,29 @@ bool QgsAttributeTableModel::setData( const QModelIndex &index, const QVariant &
if ( !layer()->isModified() )
return false;

emit dataChanged( index, index );
if ( mChangedCellBounds.isNull() )
{
mChangedCellBounds = QRect( index.column(), index.row(), 0, 0 );
}
else
{
if ( index.column() < mChangedCellBounds.left() )
{
mChangedCellBounds.setLeft( index.column() );
}
if ( index.row() < mChangedCellBounds.top() )
{
mChangedCellBounds.setTop( index.row() );
}
if ( index.column() > mChangedCellBounds.right() )
{
mChangedCellBounds.setRight( index.column() );
}
if ( index.row() > mChangedCellBounds.bottom() )
{
mChangedCellBounds.setBottom( index.row() );
}
}

return true;
}
Expand Down
16 changes: 16 additions & 0 deletions src/gui/attributetable/qgsattributetablemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,13 @@ class GUI_EXPORT QgsAttributeTableModel: public QAbstractTableModel
*/
virtual void updatedFields();

/**
* Gets called when an edit command ends
* This will synchronize all fields which have been changed since the last
* edit command in one single go
*/
virtual void editCommandEnded();

/**
* Called whenever a column is removed;
*/
Expand Down Expand Up @@ -274,6 +281,15 @@ class GUI_EXPORT QgsAttributeTableModel: public QAbstractTableModel
int mCachedField;
/** Allows to cache one specific column (used for sorting) */
QHash<QgsFeatureId, QVariant> mFieldCache;

/**
* Holds the bounds of changed cells while an update operation is running
* top = min row
* left = min column
* bottom = max row
* right = max column
*/
QRect mChangedCellBounds;
};


Expand Down