tdf#131634 Don't redo actions created before text edit begins.

In SdrObjEditView::SdrEndTextEdit(), pSdrUndoManager->Redo() was
invoked until all the redo actions created after text edit began
were converted to undo actions.

Without checking, all the redo actions include the ones created
before text edit began were moved to undo stack, and caused the
SdrTextObj to be destroyed in SdrUndoManager::SetEndTextEditHdl
when removing the undo actions and a use after release problem.

The patch add GetRedoActionCountBeforeTextEdit() so the program
won't invoke pSdrUndoManager->Redo() on actions created before
text edit begin.

Change-Id: Ic010bc6e71ee78ef2cb20a5259dc9d6d6579ccaa
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114102
Tested-by: Jenkins
Reviewed-by: Mark Hung <marklh9@gmail.com>
This commit is contained in:
Mark Hung 2021-04-14 22:30:06 +08:00
parent 748ef40304
commit 7a641c71f8
3 changed files with 7 additions and 1 deletions

View file

@ -33,6 +33,7 @@ private:
Link<SdrUndoManager*, void> maEndTextEditHdl;
SfxUndoAction* mpLastUndoActionBeforeTextEdit;
size_t mnRedoActionCountBeforeTextEdit;
bool mbEndTextEditTriggeredFromUndo;
SfxObjectShell* m_pDocSh;
@ -64,6 +65,7 @@ public:
// by a last undo during text edit
bool isEndTextEditTriggeredFromUndo() const { return mbEndTextEditTriggeredFromUndo; }
void SetDocShell(SfxObjectShell* pDocShell);
size_t GetRedoActionCountBeforeTextEdit() const { return mnRedoActionCountBeforeTextEdit; }
};
#endif // INCLUDED_SVX_SDRUNDOMANAGER_HXX

View file

@ -25,6 +25,7 @@ SdrUndoManager::SdrUndoManager()
: EditUndoManager(20 /*nMaxUndoActionCount*/)
, maEndTextEditHdl()
, mpLastUndoActionBeforeTextEdit(nullptr)
, mnRedoActionCountBeforeTextEdit(0)
, mbEndTextEditTriggeredFromUndo(false)
, m_pDocSh(nullptr)
{
@ -107,6 +108,7 @@ void SdrUndoManager::SetEndTextEditHdl(const Link<SdrUndoManager*, void>& rLink)
{
// text edit start, remember last non-textedit action for later cleanup
mpLastUndoActionBeforeTextEdit = GetUndoActionCount() ? GetUndoAction() : nullptr;
mnRedoActionCountBeforeTextEdit = GetRedoActionCount();
}
else
{
@ -123,6 +125,7 @@ void SdrUndoManager::SetEndTextEditHdl(const Link<SdrUndoManager*, void>& rLink)
// forget marker again
mpLastUndoActionBeforeTextEdit = nullptr;
mnRedoActionCountBeforeTextEdit = 0;
}
}

View file

@ -1441,7 +1441,8 @@ SdrEndTextEditKind SdrObjEditView::SdrEndTextEdit(bool bDontDeleteReally)
// to create a complete text change undo action for the redo buffer. Also mark this
// state when at least one redo was executed; the created extra TextChange needs to
// be undone in addition to the first real undo outside the text edit changes
while (pSdrUndoManager->GetRedoActionCount())
while (pSdrUndoManager->GetRedoActionCount()
> pSdrUndoManager->GetRedoActionCountBeforeTextEdit())
{
bNeedToUndoSavedRedoTextEdit = true;
pSdrUndoManager->Redo();