From bbbc2b654175edbccb1ce54ae6dbb15f8a042360 Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Mon, 4 Jun 2012 18:02:59 +0200 Subject: [PATCH] Fix to #8159: Undo doesn't restore environment depth correctly The idea is to record undo at the place where the document is modified: 1/ in Buffer::updateBuffer, add a recordUndo, with the caveat that a const_cast has to be used (because updateBuffer is const but modifies the document, go figure). 2/ in GuiApplication::dispatch, add an extra undo group that encompasses the updateBuffer call. Some other undo groups may be redundant now, but it is not a problem since they do not cost anything. --- src/Buffer.cpp | 12 +++++++++++- src/frontends/qt4/GuiApplication.cpp | 11 ++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/Buffer.cpp b/src/Buffer.cpp index b6d9da14ae..cabfe63d1c 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -4434,7 +4434,17 @@ void Buffer::updateBuffer(ParIterator & parit, UpdateType utype) const pit_type const lastpit = parit.lastpit(); for ( ; parit.pit() <= lastpit ; ++parit.pit()) { // reduce depth if necessary - parit->params().depth(min(parit->params().depth(), maxdepth)); + if (parit->params().depth() > maxdepth) { + /** FIXME: this function is const, but + * nevertheless it modifies the buffer. To be + * cleaner, one should modify the buffer in + * another function, which is actually + * non-const. This would however be costly in + * terms of code duplication. + */ + const_cast(this)->undo().recordUndo(parit); + parit->params().depth(maxdepth); + } maxdepth = parit->getMaxDepthAfter(); if (utype == OutputUpdate) { diff --git a/src/frontends/qt4/GuiApplication.cpp b/src/frontends/qt4/GuiApplication.cpp index 2cec2e333a..b00fe2d508 100644 --- a/src/frontends/qt4/GuiApplication.cpp +++ b/src/frontends/qt4/GuiApplication.cpp @@ -1132,8 +1132,13 @@ static docstring makeDispatchMessage(docstring const & msg, void GuiApplication::dispatch(FuncRequest const & cmd) { - if (current_view_ && current_view_->currentBufferView()) + Buffer * buffer = 0; + if (current_view_ && current_view_->currentBufferView()) { current_view_->currentBufferView()->cursor().saveBeforeDispatchPosXY(); + buffer = ¤t_view_->currentBufferView()->buffer(); + if (buffer) + buffer->undo().beginUndoGroup(); + } DispatchResult dr; // redraw the screen at the end (first of the two drawing steps). @@ -1141,6 +1146,10 @@ void GuiApplication::dispatch(FuncRequest const & cmd) dr.screenUpdate(Update::FitCursor); dispatch(cmd, dr); updateCurrentView(cmd, dr); + + // the buffer may have been closed by one action + if (theBufferList().isLoaded(buffer)) + buffer->undo().endUndoGroup(); } -- 2.39.5