diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2021-11-08 08:27:52 +0100 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2021-11-09 10:05:16 +0100 |
commit | b8e0b887efb35b0afd85b81349d5f8e2f7d1c359 (patch) | |
tree | 97894f073302c5a23986039d3eca1f0af7738589 | |
parent | c274eeaa46206a42b3356d18f7a0d6dc5fb92cda (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)
Change-Id: I31bd02db4fe653ab63e41a77c75b8bebfc749ff1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124834
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Mike Kaganski <mike.kaganski@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 14724eae3731..d9a6a8b518e9 100644 --- a/sw/inc/IDocumentContentOperations.hxx +++ b/sw/inc/IDocumentContentOperations.hxx @@ -163,6 +163,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 14f724328fe0..bda78bda8e48 100644 --- a/sw/qa/core/doc/doc.cxx +++ b/sw/qa/core/doc/doc.cxx @@ -18,6 +18,7 @@ #include <editeng/langitem.hxx> #include <sfx2/viewfrm.hxx> #include <sfx2/dispatch.hxx> +#include <vcl/scheduler.hxx> #include <wrtsh.hxx> #include <fmtanchr.hxx> @@ -29,6 +30,7 @@ #include <swdtflvr.hxx> #include <cmdid.h> #include <unotxdoc.hxx> +#include <UndoManager.hxx> char const DATA_DIRECTORY[] = "/sw/qa/core/doc/data/"; @@ -165,6 +167,36 @@ CPPUNIT_TEST_FIXTURE(SwCoreDocTest, testTextBoxMakeFlyFrame) assertXPath(pLayout, "/root/page/body/txt/anchored/fly", 1); } +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 = createSwDoc(); + // 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 aefd7feb881e..c3251b6232f2 100644 --- a/sw/source/core/doc/DocumentContentOperationsManager.cxx +++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx @@ -2818,6 +2818,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 09f4dba1e016..500f5d157b6c 100644 --- a/sw/source/core/doc/extinput.cxx +++ b/sw/source/core/doc/extinput.cxx @@ -61,7 +61,12 @@ SwExtTextInput::~SwExtTextInput() // Prevent IME edited text being grouped with non-IME edited text. bool bKeepGroupUndo = rDoc.GetIDocumentUndoRedo().DoesGroupUndo(); - rDoc.GetIDocumentUndoRedo().DoGroupUndo(false); + bool bWasIME = rDoc.GetIDocumentUndoRedo().GetUndoActionCount() == 0 || rDoc.getIDocumentContentOperations().GetIME(); + if (!bWasIME) + { + rDoc.GetIDocumentUndoRedo().DoGroupUndo(false); + } + rDoc.getIDocumentContentOperations().SetIME(true); if( nEndCnt < nSttCnt ) { std::swap(nSttCnt, nEndCnt); @@ -119,7 +124,10 @@ SwExtTextInput::~SwExtTextInput() pTNd->EraseText( rIdx, nLenghtOfOldString ); } - rDoc.GetIDocumentUndoRedo().DoGroupUndo(bKeepGroupUndo); + if (!bWasIME) + { + rDoc.GetIDocumentUndoRedo().DoGroupUndo(bKeepGroupUndo); + } if (m_eInputLanguage == LANGUAGE_DONTKNOW) return; diff --git a/sw/source/core/edit/editsh.cxx b/sw/source/core/edit/editsh.cxx index 85c065d60fed..967ce1f2e203 100644 --- a/sw/source/core/edit/editsh.cxx +++ b/sw/source/core/edit/editsh.cxx @@ -88,6 +88,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 3df39532978c..ab5d260bce7f 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); |