summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2021-11-08 08:27:52 +0100
committerMiklos Vajna <vmiklos@collabora.com>2021-11-10 09:26:59 +0100
commit903deab52b26b820bf0d1bb660e2f19ada53df4b (patch)
treee54b1e79c0db693904c783a3295b4088ad4dd5b1
parentcd31d274c5971d6ffcc5914be684fca53c1fe257 (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.hxx6
-rw-r--r--sw/qa/core/doc/doc.cxx32
-rw-r--r--sw/source/core/doc/DocumentContentOperationsManager.cxx10
-rw-r--r--sw/source/core/doc/extinput.cxx12
-rw-r--r--sw/source/core/edit/editsh.cxx1
-rw-r--r--sw/source/core/inc/DocumentContentOperationsManager.hxx6
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);