mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
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
This commit is contained in:
parent
051fe31e22
commit
9069f3bb90
@ -5238,7 +5238,8 @@ bool QgisApp::toggleEditing( QgsMapLayer *layer, bool allowCancel )
|
||||
res = false;
|
||||
}
|
||||
|
||||
vlayer->triggerRepaint();
|
||||
// canvas refreshes handled in QgsUndoWidget::indexChanged
|
||||
//vlayer->triggerRepaint();
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -7215,11 +7216,16 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
|
||||
mActionToggleEditing->setEnabled( canChangeAttributes && !vlayer->isReadOnly() );
|
||||
mActionToggleEditing->setChecked( vlayer->isEditable() );
|
||||
mActionSaveEdits->setEnabled( canChangeAttributes && vlayer->isEditable() );
|
||||
mUndoWidget->dockContents()->setEnabled( vlayer->isEditable() );
|
||||
updateUndoActions();
|
||||
}
|
||||
else
|
||||
{
|
||||
mActionToggleEditing->setEnabled( false );
|
||||
mActionSaveEdits->setEnabled( false );
|
||||
mUndoWidget->dockContents()->setEnabled( false );
|
||||
mActionUndo->setEnabled( false );
|
||||
mActionRedo->setEnabled( false );
|
||||
}
|
||||
|
||||
if ( dprovider->capabilities() & QgsVectorDataProvider::AddFeatures )
|
||||
|
@ -37,6 +37,8 @@ QgsUndoWidget::QgsUndoWidget( QWidget * parent, QgsMapCanvas * mapCanvas )
|
||||
mMapCanvas = mapCanvas;
|
||||
mUndoView = NULL;
|
||||
mUndoStack = NULL;
|
||||
mPreviousIndex = 0;
|
||||
mPreviousCount = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -80,13 +82,25 @@ void QgsUndoWidget::redoChanged( bool value )
|
||||
emit undoStackChanged();
|
||||
}
|
||||
|
||||
|
||||
void QgsUndoWidget::indexChanged( int value )
|
||||
void QgsUndoWidget::indexChanged( int curIndx )
|
||||
{
|
||||
Q_UNUSED( value );
|
||||
//redoButton->setDisabled( !value );
|
||||
//canvas refresh
|
||||
mMapCanvas->refresh();
|
||||
// this is called twice when a non-current command is clicked in QUndoView
|
||||
// first call has offset, second call will have offset of 0
|
||||
int curCount = 0;
|
||||
if ( mUndoStack )
|
||||
{
|
||||
curCount = mUndoStack->count();
|
||||
}
|
||||
bool cmdAdded = ( curIndx == curCount && mPreviousCount == ( curCount - 1 ) );
|
||||
int offset = qAbs( mPreviousIndex - curIndx );
|
||||
// avoid refresh when only a command was added to stack (i.e. no undo/redo action)
|
||||
if ( offset > 1 || ( offset == 1 && !cmdAdded ) )
|
||||
{
|
||||
mMapCanvas->refresh();
|
||||
}
|
||||
|
||||
mPreviousIndex = curIndx;
|
||||
mPreviousCount = curCount;
|
||||
}
|
||||
|
||||
void QgsUndoWidget::undo( )
|
||||
@ -111,20 +125,19 @@ void QgsUndoWidget::setUndoStack( QUndoStack* undoStack )
|
||||
}
|
||||
|
||||
mUndoStack = undoStack;
|
||||
mPreviousIndex = mUndoStack->index();
|
||||
mPreviousCount = mUndoStack->count();
|
||||
|
||||
mUndoView = new QUndoView( dockWidgetContents );
|
||||
mUndoView->setStack( undoStack );
|
||||
mUndoView->setObjectName( "undoView" );
|
||||
gridLayout->addWidget( mUndoView, 0, 0, 1, 2 );
|
||||
setWidget( dockWidgetContents );
|
||||
connect( mUndoStack, SIGNAL( canUndoChanged( bool ) ), this, SLOT( undoChanged( bool ) ) );
|
||||
connect( mUndoStack, SIGNAL( canRedoChanged( bool ) ), this, SLOT( redoChanged( bool ) ) );
|
||||
connect( mUndoStack, SIGNAL( canUndoChanged( bool ) ), this, SLOT( undoChanged( bool ) ) );
|
||||
connect( mUndoStack, SIGNAL( canRedoChanged( bool ) ), this, SLOT( redoChanged( bool ) ) );
|
||||
|
||||
// indexChanged() triggers a refresh. but it gets triggered also when a new action
|
||||
// is done, resulting in two refreshes. For now let's trigger the refresh from
|
||||
// vector layer: it causes potentially multiple refreshes when moving more commands
|
||||
// back, but avoids double refresh in common case when adding commands to the stack
|
||||
//connect(mUndoStack, SIGNAL(indexChanged(int)), this, SLOT(indexChanged(int)));
|
||||
// gets triggered also when a new command is added to stack, and twice when clicking a command in QUndoView
|
||||
connect( mUndoStack, SIGNAL( indexChanged( int ) ), this, SLOT( indexChanged( int ) ) );
|
||||
|
||||
undoButton->setDisabled( !mUndoStack->canUndo() );
|
||||
redoButton->setDisabled( !mUndoStack->canRedo() );
|
||||
|
@ -58,6 +58,12 @@ class QgsUndoWidget : public QDockWidget
|
||||
*/
|
||||
void destroyStack();
|
||||
|
||||
/**
|
||||
* Access to dock's contents
|
||||
* @note added in 1.9
|
||||
*/
|
||||
QWidget* dockContents() { return dockWidgetContents; }
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* Changes undo stack which is displayed by undo view
|
||||
@ -77,7 +83,7 @@ class QgsUndoWidget : public QDockWidget
|
||||
/**
|
||||
* Slot to handle index changed signal
|
||||
*/
|
||||
void indexChanged( int value );
|
||||
void indexChanged( int curIndx );
|
||||
|
||||
/**
|
||||
* Undo operation called from button push
|
||||
@ -97,6 +103,8 @@ class QgsUndoWidget : public QDockWidget
|
||||
QUndoStack * mUndoStack;
|
||||
QgsMapCanvas* mMapCanvas;
|
||||
|
||||
int mPreviousIndex;
|
||||
int mPreviousCount;
|
||||
};
|
||||
|
||||
|
||||
|
@ -4256,10 +4256,9 @@ bool QgsVectorLayer::rollBack()
|
||||
|
||||
if ( isModified() )
|
||||
{
|
||||
while ( undoStack()->canUndo() )
|
||||
{
|
||||
undoStack()->undo();
|
||||
}
|
||||
// new undo stack roll back method
|
||||
// old method of calling every undo could cause many canvas refreshes
|
||||
undoStack()->setIndex( 0 );
|
||||
|
||||
Q_ASSERT( mAddedAttributeIds.isEmpty() );
|
||||
Q_ASSERT( mDeletedAttributeIds.isEmpty() );
|
||||
@ -5240,7 +5239,8 @@ void QgsVectorLayer::redoEditCommand( QgsUndoCommand* cmd )
|
||||
setModified( true );
|
||||
|
||||
// it's not ideal to trigger refresh from here
|
||||
triggerRepaint();
|
||||
// canvas refreshes handled in QgsUndoWidget::indexChanged
|
||||
//triggerRepaint();
|
||||
}
|
||||
|
||||
void QgsVectorLayer::undoEditCommand( QgsUndoCommand* cmd )
|
||||
@ -5363,7 +5363,8 @@ void QgsVectorLayer::undoEditCommand( QgsUndoCommand* cmd )
|
||||
setModified( true );
|
||||
|
||||
// it's not ideal to trigger refresh from here
|
||||
triggerRepaint();
|
||||
// canvas refreshes handled in QgsUndoWidget::indexChanged
|
||||
//triggerRepaint();
|
||||
}
|
||||
|
||||
void QgsVectorLayer::setCheckedState( int idx, QString checked, QString unchecked )
|
||||
|
Loading…
x
Reference in New Issue
Block a user