tdf#132822 close open undo group before clearing undo stack
when changing paragraph. previous para undo info needs to be discarded, but that cannot be done properly if there is an open undo group. So pass the optional undo group guard down to GetNextSentence_Impl which can close it before it needs to set the new paragraph. Change-Id: I595c3598b15b6b1fdace045c3879617ecfea3faa Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96397 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com>
This commit is contained in:
parent
83bacd2fd2
commit
7b137e5c7b
2 changed files with 42 additions and 21 deletions
|
@ -344,14 +344,14 @@ void SpellDialog::UpdateBoxes_Impl(bool bCallFromSelectHdl)
|
|||
m_xDialog->resize_to_request();
|
||||
}
|
||||
|
||||
void SpellDialog::SpellContinue_Impl(bool bUseSavedSentence, bool bIgnoreCurrentError )
|
||||
void SpellDialog::SpellContinue_Impl(std::unique_ptr<UndoChangeGroupGuard>* pGuard, bool bUseSavedSentence, bool bIgnoreCurrentError)
|
||||
{
|
||||
//initially or after the last error of a sentence MarkNextError will fail
|
||||
//then GetNextSentence() has to be called followed again by MarkNextError()
|
||||
//MarkNextError is not initially called if the UndoEdit mode is active
|
||||
bool bNextSentence = false;
|
||||
if(!((!m_xSentenceED->IsUndoEditMode() && m_xSentenceED->MarkNextError( bIgnoreCurrentError, xSpell )) ||
|
||||
( bNextSentence = GetNextSentence_Impl(bUseSavedSentence, m_xSentenceED->IsUndoEditMode()) && m_xSentenceED->MarkNextError( false, xSpell ))))
|
||||
( bNextSentence = GetNextSentence_Impl(pGuard, bUseSavedSentence, m_xSentenceED->IsUndoEditMode()) && m_xSentenceED->MarkNextError( false, xSpell ))))
|
||||
return;
|
||||
|
||||
SpellErrorDescription aSpellErrorDescription;
|
||||
|
@ -389,7 +389,7 @@ IMPL_LINK_NOARG( SpellDialog, InitHdl, void*, void)
|
|||
m_xDialog->freeze();
|
||||
//show or hide AutoCorrect depending on the modules abilities
|
||||
m_xAutoCorrPB->set_visible(rParent.HasAutoCorrection());
|
||||
SpellContinue_Impl();
|
||||
SpellContinue_Impl(nullptr);
|
||||
m_xSentenceED->ResetUndo();
|
||||
m_xUndoPB->set_sensitive(false);
|
||||
|
||||
|
@ -506,6 +506,27 @@ IMPL_LINK_NOARG(SpellDialog, DoubleClickChangeHdl, weld::TreeView&, bool)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* tdf#132822 start an undo group in ctor and close it in the dtor. This can
|
||||
then be passed to SpellContinue_Impl which can delete it in advance of its
|
||||
natural scope to force closing the undo group if SpellContinue_Impl needs to
|
||||
fetch a new paragraph and discard all undo information which can only be
|
||||
done properly if there are no open undo groups */
|
||||
class UndoChangeGroupGuard
|
||||
{
|
||||
private:
|
||||
SentenceEditWindow_Impl& m_rSentenceED;
|
||||
public:
|
||||
UndoChangeGroupGuard(SentenceEditWindow_Impl& rSentenceED)
|
||||
: m_rSentenceED(rSentenceED)
|
||||
{
|
||||
m_rSentenceED.UndoActionStart(SPELLUNDO_CHANGE_GROUP);
|
||||
}
|
||||
~UndoChangeGroupGuard()
|
||||
{
|
||||
m_rSentenceED.UndoActionEnd();
|
||||
}
|
||||
};
|
||||
|
||||
IMPL_LINK_NOARG(SpellDialog, ChangeHdl, weld::Button&, void)
|
||||
{
|
||||
if (m_xSentenceED->IsUndoEditMode())
|
||||
|
@ -514,11 +535,10 @@ IMPL_LINK_NOARG(SpellDialog, ChangeHdl, weld::Button&, void)
|
|||
}
|
||||
else
|
||||
{
|
||||
m_xSentenceED->UndoActionStart( SPELLUNDO_CHANGE_GROUP );
|
||||
auto xGuard(std::make_unique<UndoChangeGroupGuard>(*m_xSentenceED));
|
||||
OUString aString = getReplacementString();
|
||||
m_xSentenceED->ChangeMarkedWord(aString, GetSelectedLang_Impl());
|
||||
SpellContinue_Impl();
|
||||
m_xSentenceED->UndoActionEnd();
|
||||
SpellContinue_Impl(&xGuard);
|
||||
}
|
||||
if(!m_xChangePB->get_sensitive())
|
||||
m_xIgnorePB->grab_focus();
|
||||
|
@ -526,7 +546,7 @@ IMPL_LINK_NOARG(SpellDialog, ChangeHdl, weld::Button&, void)
|
|||
|
||||
IMPL_LINK_NOARG(SpellDialog, ChangeAllHdl, weld::Button&, void)
|
||||
{
|
||||
m_xSentenceED->UndoActionStart( SPELLUNDO_CHANGE_GROUP );
|
||||
auto xGuard(std::make_unique<UndoChangeGroupGuard>(*m_xSentenceED));
|
||||
OUString aString = getReplacementString();
|
||||
LanguageType eLang = GetSelectedLang_Impl();
|
||||
|
||||
|
@ -548,13 +568,12 @@ IMPL_LINK_NOARG(SpellDialog, ChangeAllHdl, weld::Button&, void)
|
|||
}
|
||||
|
||||
m_xSentenceED->ChangeMarkedWord(aString, eLang);
|
||||
SpellContinue_Impl();
|
||||
m_xSentenceED->UndoActionEnd();
|
||||
SpellContinue_Impl(&xGuard);
|
||||
}
|
||||
|
||||
IMPL_LINK( SpellDialog, IgnoreAllHdl, weld::Button&, rButton, void )
|
||||
{
|
||||
m_xSentenceED->UndoActionStart( SPELLUNDO_CHANGE_GROUP );
|
||||
auto xGuard(std::make_unique<UndoChangeGroupGuard>(*m_xSentenceED));
|
||||
// add word to IgnoreAll list
|
||||
Reference< XDictionary > aXDictionary = LinguMgr::GetIgnoreAllList();
|
||||
//in case the error has been changed manually it has to be restored
|
||||
|
@ -594,8 +613,7 @@ IMPL_LINK( SpellDialog, IgnoreAllHdl, weld::Button&, rButton, void )
|
|||
}
|
||||
}
|
||||
|
||||
SpellContinue_Impl();
|
||||
m_xSentenceED->UndoActionEnd();
|
||||
SpellContinue_Impl(&xGuard);
|
||||
}
|
||||
|
||||
IMPL_LINK_NOARG(SpellDialog, UndoHdl, weld::Button&, void)
|
||||
|
@ -644,7 +662,7 @@ IMPL_LINK( SpellDialog, DialogUndoHdl, SpellUndoAction_Impl&, rAction, void )
|
|||
case SPELLUNDO_UNDO_EDIT_MODE :
|
||||
{
|
||||
//refill the dialog with the currently spelled sentence - throw away all changes
|
||||
SpellContinue_Impl(true);
|
||||
SpellContinue_Impl(nullptr, true);
|
||||
}
|
||||
break;
|
||||
case SPELLUNDO_ADD_IGNORE_RULE:
|
||||
|
@ -661,7 +679,7 @@ void SpellDialog::Impl_Restore(bool bUseSavedSentence)
|
|||
m_xSentenceED->SetText(OUString());
|
||||
m_xSentenceED->ResetModified();
|
||||
//Resolves: fdo#39348 refill the dialog with the currently spelled sentence
|
||||
SpellContinue_Impl(bUseSavedSentence);
|
||||
SpellContinue_Impl(nullptr, bUseSavedSentence);
|
||||
m_xIgnorePB->set_label(m_sIgnoreOnceST);
|
||||
}
|
||||
|
||||
|
@ -678,7 +696,7 @@ IMPL_LINK_NOARG(SpellDialog, IgnoreHdl, weld::Button&, void)
|
|||
m_xSentenceED->RestoreCurrentError();
|
||||
|
||||
// the word is being ignored
|
||||
SpellContinue_Impl( false, true );
|
||||
SpellContinue_Impl(nullptr, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -817,7 +835,7 @@ IMPL_LINK(SpellDialog, AddToDictSelectHdl, const OString&, rIdent, void)
|
|||
|
||||
void SpellDialog::AddToDictionaryExecute(const OString& rItemId)
|
||||
{
|
||||
m_xSentenceED->UndoActionStart( SPELLUNDO_CHANGE_GROUP );
|
||||
auto xGuard(std::make_unique<UndoChangeGroupGuard>(*m_xSentenceED));
|
||||
|
||||
//GetErrorText() returns the current error even if the text is already
|
||||
//manually changed
|
||||
|
@ -858,8 +876,7 @@ void SpellDialog::AddToDictionaryExecute(const OString& rItemId)
|
|||
}
|
||||
|
||||
// go on
|
||||
SpellContinue_Impl();
|
||||
m_xSentenceED->UndoActionEnd();
|
||||
SpellContinue_Impl(&xGuard);
|
||||
}
|
||||
|
||||
IMPL_LINK_NOARG(SpellDialog, ModifyHdl, LinkParamNone*, void)
|
||||
|
@ -958,7 +975,7 @@ void SpellDialog::InvalidateDialog()
|
|||
SfxModelessDialogController::Deactivate();
|
||||
}
|
||||
|
||||
bool SpellDialog::GetNextSentence_Impl(bool bUseSavedSentence, bool bRecheck)
|
||||
bool SpellDialog::GetNextSentence_Impl(std::unique_ptr<UndoChangeGroupGuard>* pGuard, bool bUseSavedSentence, bool bRecheck)
|
||||
{
|
||||
bool bRet = false;
|
||||
if(!bUseSavedSentence)
|
||||
|
@ -995,6 +1012,9 @@ bool SpellDialog::GetNextSentence_Impl(bool bUseSavedSentence, bool bRecheck)
|
|||
if(!elem.bIsHidden)
|
||||
sText.append(elem.sText);
|
||||
}
|
||||
// tdf#132822 fire undo-stack UndoActionEnd to close undo stack because we're about to throw away the paragraph entirely
|
||||
if (pGuard)
|
||||
pGuard->reset();
|
||||
m_xSentenceED->SetText(sText.makeStringAndClear());
|
||||
sal_Int32 nStartPosition = 0;
|
||||
sal_Int32 nEndPosition = 0;
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <set>
|
||||
|
||||
namespace svx{ class SpellUndoAction_Impl;}
|
||||
class UndoChangeGroupGuard;
|
||||
|
||||
// forward ---------------------------------------------------------------
|
||||
|
||||
|
@ -189,7 +190,7 @@ private:
|
|||
int InitUserDicts();
|
||||
void UpdateBoxes_Impl(bool bCallFromSelectHdl = false);
|
||||
void Init_Impl();
|
||||
void SpellContinue_Impl(bool UseSavedSentence = false, bool bIgnoreCurrentError = false );
|
||||
void SpellContinue_Impl(std::unique_ptr<UndoChangeGroupGuard>* pGuard = nullptr, bool UseSavedSentence = false, bool bIgnoreCurrentError = false );
|
||||
void LockFocusChanges( bool bLock ) {bFocusLocked = bLock;}
|
||||
void ToplevelFocusChanged();
|
||||
void Impl_Restore(bool bUseSavedSentence);
|
||||
|
@ -198,7 +199,7 @@ private:
|
|||
|
||||
/** Retrieves the next sentence.
|
||||
*/
|
||||
bool GetNextSentence_Impl(bool bUseSavedSentence, bool bRechek /*for rechecking the current sentence*/);
|
||||
bool GetNextSentence_Impl(std::unique_ptr<UndoChangeGroupGuard>* pGuard, bool bUseSavedSentence, bool bRecheck /*for rechecking the current sentence*/);
|
||||
/** Corrects all errors that have been selected to be changed always
|
||||
*/
|
||||
static bool ApplyChangeAllList_Impl(SpellPortions& rSentence, bool& bHasReplaced);
|
||||
|
|
Loading…
Reference in a new issue