Skip to content

Commit 9069f3b

Browse files
committedDec 15, 2012
Update undo/redo widget and vector layer rollback
- Allows for any number of undo/redo commands with only one refresh - Significantly decreases time needed to cancel or redo many edits - Disable undo/redo dock's widgets and toolbar actions when layer not in editing mode
1 parent 051fe31 commit 9069f3b

File tree

4 files changed

+50
-22
lines changed

4 files changed

+50
-22
lines changed
 

‎src/app/qgisapp.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5238,7 +5238,8 @@ bool QgisApp::toggleEditing( QgsMapLayer *layer, bool allowCancel )
52385238
res = false;
52395239
}
52405240

5241-
vlayer->triggerRepaint();
5241+
// canvas refreshes handled in QgsUndoWidget::indexChanged
5242+
//vlayer->triggerRepaint();
52425243
break;
52435244

52445245
default:
@@ -7215,11 +7216,16 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
72157216
mActionToggleEditing->setEnabled( canChangeAttributes && !vlayer->isReadOnly() );
72167217
mActionToggleEditing->setChecked( vlayer->isEditable() );
72177218
mActionSaveEdits->setEnabled( canChangeAttributes && vlayer->isEditable() );
7219+
mUndoWidget->dockContents()->setEnabled( vlayer->isEditable() );
7220+
updateUndoActions();
72187221
}
72197222
else
72207223
{
72217224
mActionToggleEditing->setEnabled( false );
72227225
mActionSaveEdits->setEnabled( false );
7226+
mUndoWidget->dockContents()->setEnabled( false );
7227+
mActionUndo->setEnabled( false );
7228+
mActionRedo->setEnabled( false );
72237229
}
72247230

72257231
if ( dprovider->capabilities() & QgsVectorDataProvider::AddFeatures )

‎src/app/qgsundowidget.cpp

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ QgsUndoWidget::QgsUndoWidget( QWidget * parent, QgsMapCanvas * mapCanvas )
3737
mMapCanvas = mapCanvas;
3838
mUndoView = NULL;
3939
mUndoStack = NULL;
40+
mPreviousIndex = 0;
41+
mPreviousCount = 0;
4042
}
4143

4244

@@ -80,13 +82,25 @@ void QgsUndoWidget::redoChanged( bool value )
8082
emit undoStackChanged();
8183
}
8284

83-
84-
void QgsUndoWidget::indexChanged( int value )
85+
void QgsUndoWidget::indexChanged( int curIndx )
8586
{
86-
Q_UNUSED( value );
87-
//redoButton->setDisabled( !value );
88-
//canvas refresh
89-
mMapCanvas->refresh();
87+
// this is called twice when a non-current command is clicked in QUndoView
88+
// first call has offset, second call will have offset of 0
89+
int curCount = 0;
90+
if ( mUndoStack )
91+
{
92+
curCount = mUndoStack->count();
93+
}
94+
bool cmdAdded = ( curIndx == curCount && mPreviousCount == ( curCount - 1 ) );
95+
int offset = qAbs( mPreviousIndex - curIndx );
96+
// avoid refresh when only a command was added to stack (i.e. no undo/redo action)
97+
if ( offset > 1 || ( offset == 1 && !cmdAdded ) )
98+
{
99+
mMapCanvas->refresh();
100+
}
101+
102+
mPreviousIndex = curIndx;
103+
mPreviousCount = curCount;
90104
}
91105

92106
void QgsUndoWidget::undo( )
@@ -111,20 +125,19 @@ void QgsUndoWidget::setUndoStack( QUndoStack* undoStack )
111125
}
112126

113127
mUndoStack = undoStack;
128+
mPreviousIndex = mUndoStack->index();
129+
mPreviousCount = mUndoStack->count();
114130

115131
mUndoView = new QUndoView( dockWidgetContents );
116132
mUndoView->setStack( undoStack );
117133
mUndoView->setObjectName( "undoView" );
118134
gridLayout->addWidget( mUndoView, 0, 0, 1, 2 );
119135
setWidget( dockWidgetContents );
120-
connect( mUndoStack, SIGNAL( canUndoChanged( bool ) ), this, SLOT( undoChanged( bool ) ) );
121-
connect( mUndoStack, SIGNAL( canRedoChanged( bool ) ), this, SLOT( redoChanged( bool ) ) );
122-
123-
// indexChanged() triggers a refresh. but it gets triggered also when a new action
124-
// is done, resulting in two refreshes. For now let's trigger the refresh from
125-
// vector layer: it causes potentially multiple refreshes when moving more commands
126-
// back, but avoids double refresh in common case when adding commands to the stack
127-
//connect(mUndoStack, SIGNAL(indexChanged(int)), this, SLOT(indexChanged(int)));
136+
connect( mUndoStack, SIGNAL( canUndoChanged( bool ) ), this, SLOT( undoChanged( bool ) ) );
137+
connect( mUndoStack, SIGNAL( canRedoChanged( bool ) ), this, SLOT( redoChanged( bool ) ) );
138+
139+
// gets triggered also when a new command is added to stack, and twice when clicking a command in QUndoView
140+
connect( mUndoStack, SIGNAL( indexChanged( int ) ), this, SLOT( indexChanged( int ) ) );
128141

129142
undoButton->setDisabled( !mUndoStack->canUndo() );
130143
redoButton->setDisabled( !mUndoStack->canRedo() );

‎src/app/qgsundowidget.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ class QgsUndoWidget : public QDockWidget
5858
*/
5959
void destroyStack();
6060

61+
/**
62+
* Access to dock's contents
63+
* @note added in 1.9
64+
*/
65+
QWidget* dockContents() { return dockWidgetContents; }
66+
6167
public slots:
6268
/**
6369
* Changes undo stack which is displayed by undo view
@@ -77,7 +83,7 @@ class QgsUndoWidget : public QDockWidget
7783
/**
7884
* Slot to handle index changed signal
7985
*/
80-
void indexChanged( int value );
86+
void indexChanged( int curIndx );
8187

8288
/**
8389
* Undo operation called from button push
@@ -97,6 +103,8 @@ class QgsUndoWidget : public QDockWidget
97103
QUndoStack * mUndoStack;
98104
QgsMapCanvas* mMapCanvas;
99105

106+
int mPreviousIndex;
107+
int mPreviousCount;
100108
};
101109

102110

‎src/core/qgsvectorlayer.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4256,10 +4256,9 @@ bool QgsVectorLayer::rollBack()
42564256

42574257
if ( isModified() )
42584258
{
4259-
while ( undoStack()->canUndo() )
4260-
{
4261-
undoStack()->undo();
4262-
}
4259+
// new undo stack roll back method
4260+
// old method of calling every undo could cause many canvas refreshes
4261+
undoStack()->setIndex( 0 );
42634262

42644263
Q_ASSERT( mAddedAttributeIds.isEmpty() );
42654264
Q_ASSERT( mDeletedAttributeIds.isEmpty() );
@@ -5240,7 +5239,8 @@ void QgsVectorLayer::redoEditCommand( QgsUndoCommand* cmd )
52405239
setModified( true );
52415240

52425241
// it's not ideal to trigger refresh from here
5243-
triggerRepaint();
5242+
// canvas refreshes handled in QgsUndoWidget::indexChanged
5243+
//triggerRepaint();
52445244
}
52455245

52465246
void QgsVectorLayer::undoEditCommand( QgsUndoCommand* cmd )
@@ -5363,7 +5363,8 @@ void QgsVectorLayer::undoEditCommand( QgsUndoCommand* cmd )
53635363
setModified( true );
53645364

53655365
// it's not ideal to trigger refresh from here
5366-
triggerRepaint();
5366+
// canvas refreshes handled in QgsUndoWidget::indexChanged
5367+
//triggerRepaint();
53675368
}
53685369

53695370
void QgsVectorLayer::setCheckedState( int idx, QString checked, QString unchecked )

0 commit comments

Comments
 (0)
Please sign in to comment.