diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2021-11-08 08:27:52 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2021-11-10 09:26:59 +0100 |
commit | 903deab52b26b820bf0d1bb660e2f19ada53df4b (patch) | |
tree | e54b1e79c0db693904c783a3295b4088ad4dd5b1 | |
parent | cd31d274c5971d6ffcc5914be684fca53c1fe257 (diff) |
sw: try grouping undo actions of IME-edited text
This is a problem since commit e7760d428bc82ccfcae14f1907b78f9f1013b88c
(Fix tdf#87500 - Freeze with English/Japanese mixture undo.,
2015-09-08), that started not grouping IME-edited text completely.
This means that in case you go via SwEditWin::Command() instead of
SwEditWin::KeyInput() to type a 4 characters word, then it'll create 4
undo actions.
Fix the problem by tracking who was the last caller of
sw::DocumentContentOperationsManager::InsertString(), so we can only
disable grouping switching between IME and non-IME, and we can have
grouping for a series of IME input.
(cherry picked from commit 6680e51716e383c68bb1ec9cc0a05d698d3b6a3d)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124834
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
(cherry picked from commit b8e0b887efb35b0afd85b81349d5f8e2f7d1c359)
Conflicts:
sw/qa/core/doc/doc.cxx
sw/source/core/doc/extinput.cxx
Change-Id: I31bd02db4fe653ab63e41a77c75b8bebfc749ff1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124921
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
-rw-r--r-- | sw/inc/IDocumentContentOperations.hxx | 6 | ||||
-rw-r--r-- | sw/qa/core/doc/doc.cxx | 32 | ||||
-rw-r--r-- | sw/source/core/doc/DocumentContentOperationsManager.cxx | 10 | ||||
-rw-r--r-- | sw/source/core/doc/extinput.cxx | 12 | ||||
-rw-r--r-- | sw/source/core/edit/editsh.cxx | 1 | ||||
-rw-r--r-- | sw/source/core/inc/DocumentContentOperationsManager.hxx | 6 |
6 files changed, 65 insertions, 2 deletions
diff --git a/sw/inc/IDocumentContentOperations.hxx b/sw/inc/IDocumentContentOperations.hxx index b6857c346a33..5c7703d5e381 100644 --- a/sw/inc/IDocumentContentOperations.hxx +++ b/sw/inc/IDocumentContentOperations.hxx @@ -149,6 +149,12 @@ public: virtual bool InsertString(const SwPaM &rRg, const OUString&, const SwInsertFlags nInsertMode = SwInsertFlags::EMPTYEXPAND ) = 0; + /// States that the last inserted string came from IME. + virtual void SetIME(bool bIME) = 0; + + /// Did the last inserted string come from IME? + virtual bool GetIME() const = 0; + /** change text to Upper/Lower/Hiragana/Katakana/... */ virtual void TransliterateText(const SwPaM& rPaM, utl::TransliterationWrapper&) = 0; diff --git a/sw/qa/core/doc/doc.cxx b/sw/qa/core/doc/doc.cxx index d30cbe47cc3b..88fae0b0aab8 100644 --- a/sw/qa/core/doc/doc.cxx +++ b/sw/qa/core/doc/doc.cxx @@ -17,12 +17,14 @@ #include <vcl/errinf.hxx> #include <vcl/event.hxx> #include <editeng/langitem.hxx> +#include <vcl/scheduler.hxx> #include <wrtsh.hxx> #include <fmtanchr.hxx> #include <edtwin.hxx> #include <view.hxx> #include <ndtxt.hxx> +#include <UndoManager.hxx> static char const DATA_DIRECTORY[] = "/sw/qa/core/doc/data/"; @@ -126,6 +128,36 @@ CPPUNIT_TEST_FIXTURE(SwCoreDocTest, testLocaleIndependentTemplate) ErrorRegistry::Reset(); } +CPPUNIT_TEST_FIXTURE(SwCoreDocTest, testIMEGrouping) +{ +// TODO figure out why the ext text input in this test code reaches the wrong window on +// non-headless. +#if !defined MACOSX && !defined _WIN32 + // Given an empty document: + SwDoc* pDoc = createDoc(); + // Make sure no idle is in action, so the ExtTextInput events go to SwEditWin. + Scheduler::ProcessEventsToIdle(); + + // When pressing two keys via IME: + SwDocShell* pDocShell = pDoc->GetDocShell(); + SwEditWin& rEditWin = pDocShell->GetView()->GetEditWin(); + rEditWin.PostExtTextInputEvent(VclEventId::ExtTextInput, "a"); + rEditWin.PostExtTextInputEvent(VclEventId::EndExtTextInput, ""); + rEditWin.PostExtTextInputEvent(VclEventId::ExtTextInput, "b"); + rEditWin.PostExtTextInputEvent(VclEventId::EndExtTextInput, ""); + + // Then make sure that gets grouped together to a single undo action: + SwWrtShell* pWrtShell = pDocShell->GetWrtShell(); + SwTextNode* pTextNode = pWrtShell->GetCursor()->GetNode().GetTextNode(); + CPPUNIT_ASSERT_EQUAL(OUString("ab"), pTextNode->GetText()); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 1 + // - Actual : 2 + // i.e. 2 subsequent IME events got their own undo actions. + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDoc->GetUndoManager().GetUndoActionCount()); +#endif +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx index 909c88632f5e..99233fee6df8 100644 --- a/sw/source/core/doc/DocumentContentOperationsManager.cxx +++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx @@ -2784,6 +2784,16 @@ bool DocumentContentOperationsManager::InsertString( const SwPaM &rRg, const OUS return true; } +void DocumentContentOperationsManager::SetIME(bool bIME) +{ + m_bIME = bIME; +} + +bool DocumentContentOperationsManager::GetIME() const +{ + return m_bIME; +} + void DocumentContentOperationsManager::TransliterateText( const SwPaM& rPaM, utl::TransliterationWrapper& rTrans ) diff --git a/sw/source/core/doc/extinput.cxx b/sw/source/core/doc/extinput.cxx index 9f60ec1fabcf..6c3cf951fa72 100644 --- a/sw/source/core/doc/extinput.cxx +++ b/sw/source/core/doc/extinput.cxx @@ -59,7 +59,12 @@ SwExtTextInput::~SwExtTextInput() { // Prevent IME edited text being grouped with non-IME edited text. bool bKeepGroupUndo = pDoc->GetIDocumentUndoRedo().DoesGroupUndo(); - pDoc->GetIDocumentUndoRedo().DoGroupUndo(false); + bool bWasIME = pDoc->GetIDocumentUndoRedo().GetUndoActionCount() == 0 || pDoc->getIDocumentContentOperations().GetIME(); + if (!bWasIME) + { + pDoc->GetIDocumentUndoRedo().DoGroupUndo(false); + } + pDoc->getIDocumentContentOperations().SetIME(true); if( nEndCnt < nSttCnt ) { std::swap(nSttCnt, nEndCnt); @@ -117,7 +122,10 @@ SwExtTextInput::~SwExtTextInput() pTNd->EraseText( rIdx, nLenghtOfOldString ); } - pDoc->GetIDocumentUndoRedo().DoGroupUndo(bKeepGroupUndo); + if (!bWasIME) + { + pDoc->GetIDocumentUndoRedo().DoGroupUndo(bKeepGroupUndo); + } if (eInputLanguage != LANGUAGE_DONTKNOW) { sal_uInt16 nWhich = RES_CHRATR_LANGUAGE; diff --git a/sw/source/core/edit/editsh.cxx b/sw/source/core/edit/editsh.cxx index 8f84ce42ed75..235a7fe2b81a 100644 --- a/sw/source/core/edit/editsh.cxx +++ b/sw/source/core/edit/editsh.cxx @@ -94,6 +94,7 @@ void SwEditShell::Insert2(const OUString &rStr, const bool bForceExpandHints ) for(SwPaM& rCurrentCursor : getShellCursor( true )->GetRingContainer()) { //OPT: GetSystemCharSet + GetDoc()->getIDocumentContentOperations().SetIME(false); const bool bSuccess = GetDoc()->getIDocumentContentOperations().InsertString(rCurrentCursor, rStr, nInsertFlags); OSL_ENSURE( bSuccess, "Doc->Insert() failed." ); diff --git a/sw/source/core/inc/DocumentContentOperationsManager.hxx b/sw/source/core/inc/DocumentContentOperationsManager.hxx index 2d600b6ff8ba..ad45dc774650 100644 --- a/sw/source/core/inc/DocumentContentOperationsManager.hxx +++ b/sw/source/core/inc/DocumentContentOperationsManager.hxx @@ -61,6 +61,10 @@ public: bool InsertString(const SwPaM &rRg, const OUString&, const SwInsertFlags nInsertMode = SwInsertFlags::EMPTYEXPAND ) override; + void SetIME(bool bIME) override; + + bool GetIME() const override; + void TransliterateText(const SwPaM& rPaM, utl::TransliterationWrapper&) override; SwFlyFrameFormat* InsertGraphic(const SwPaM &rRg, const OUString& rGrfName, const OUString& rFltName, const Graphic* pGraphic, @@ -159,6 +163,8 @@ public: private: SwDoc& m_rDoc; + bool m_bIME = false; + bool DeleteAndJoinImpl(SwPaM&, const bool); bool DeleteAndJoinWithRedlineImpl(SwPaM&, const bool unused = false); bool DeleteRangeImpl(SwPaM&, const bool unused = false); |