sw/qa/extras/uiwriter/data/cursor_position_after_undo.odt |binary
 sw/qa/extras/uiwriter/uiwriter8.cxx                       |   41 ++++++++++++++
 sw/source/core/edit/edundo.cxx                            |    4 -
 sw/source/uibase/inc/wrtsh.hxx                            |   12 +++-
 sw/source/uibase/shells/basesh.cxx                        |    2 
 5 files changed, 53 insertions(+), 6 deletions(-)

New commits:
commit 8aa39da7f223f38474b4f7e2b22f6c54f019c433
Author:     Jim Raykowski <rayk...@gmail.com>
AuthorDate: Tue Dec 27 10:00:01 2022 -0900
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Mon Jan 9 14:45:05 2023 +0000

    Outline folding: Fix cursor position after undo redo
    
    This patch makes the cursor position to be the same after undo redo as
    when outline folding is not active.
    
    Change-Id: I9e1f827455afb2675f3085c1560b1e2a246f4524
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144873
    Tested-by: Jenkins
    Reviewed-by: Jim Raykowski <rayk...@gmail.com>
    (cherry picked from commit 156fd06dbca2fcca3246dba964a58a7ef698cf21)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145133
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/sw/qa/extras/uiwriter/data/cursor_position_after_undo.odt 
b/sw/qa/extras/uiwriter/data/cursor_position_after_undo.odt
new file mode 100644
index 000000000000..d6c300be61c0
Binary files /dev/null and 
b/sw/qa/extras/uiwriter/data/cursor_position_after_undo.odt differ
diff --git a/sw/qa/extras/uiwriter/uiwriter8.cxx 
b/sw/qa/extras/uiwriter/uiwriter8.cxx
index a5f41319c65f..42eaad1fb53a 100644
--- a/sw/qa/extras/uiwriter/uiwriter8.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter8.cxx
@@ -2547,6 +2547,47 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf151801)
     CPPUNIT_ASSERT_EQUAL(sReplaced, getParagraph(1)->getString());
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testCursorPositionAfterUndo)
+{
+    createSwDoc("cursor_position_after_undo.odt");
+    SwDoc* pDoc = getSwDoc();
+    SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+
+    // switch on "Outline Folding" mode
+    dispatchCommand(mxComponent, ".uno:ShowOutlineContentVisibilityButton", 
{});
+    
CPPUNIT_ASSERT(pWrtShell->GetViewOptions()->IsShowOutlineContentVisibilityButton());
+
+    // move the cursor to the beginning of the 3rd word in the 3rd paragraph, 
"tincidunt"
+    pWrtShell->FwdPara();
+    pWrtShell->FwdPara();
+    pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 16, 
/*bBasicCall=*/false);
+
+    // select the word
+    dispatchCommand(mxComponent, ".uno:SelectWord", {});
+
+    // check the word is select
+    SwShellCursor* pShellCursor = pWrtShell->getShellCursor(false);
+    CPPUNIT_ASSERT_EQUAL(OUString("tincidunt"), pShellCursor->GetText());
+
+    // remember the cursor position for comparsion
+    SwPosition aCursorPos(*pWrtShell->GetCursor()->GetPoint());
+
+    // delete the selected word
+    pWrtShell->Delete();
+
+    // undo delete
+    dispatchCommand(mxComponent, ".uno:Undo", {});
+
+    // without the fix in place, the cursor would have been set to the start 
of the outline node
+    // - Expected: SwPosition (node 11, offset 25)
+    // - Actual  : SwPosition (node 9, offset 0)
+    CPPUNIT_ASSERT_EQUAL(aCursorPos, *pWrtShell->GetCursor()->GetPoint());
+
+    // switch off "Outline Folding" mode
+    dispatchCommand(mxComponent, ".uno:ShowOutlineContentVisibilityButton", 
{});
+    
CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowOutlineContentVisibilityButton());
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/edit/edundo.cxx b/sw/source/core/edit/edundo.cxx
index 9516488cbc61..576b092214df 100644
--- a/sw/source/core/edit/edundo.cxx
+++ b/sw/source/core/edit/edundo.cxx
@@ -104,7 +104,7 @@ void 
SwEditShell::HandleUndoRedoContext(::sw::UndoRedoContext & rContext)
 
 void SwEditShell::Undo(sal_uInt16 const nCount, sal_uInt16 nOffset)
 {
-    MakeAllOutlineContentTemporarilyVisible a(GetDoc());
+    MakeAllOutlineContentTemporarilyVisible a(GetDoc(), true);
 
     CurrShell aCurr( this );
 
@@ -161,7 +161,7 @@ void SwEditShell::Undo(sal_uInt16 const nCount, sal_uInt16 
nOffset)
 
 void SwEditShell::Redo(sal_uInt16 const nCount)
 {
-    MakeAllOutlineContentTemporarilyVisible a(GetDoc());
+    MakeAllOutlineContentTemporarilyVisible a(GetDoc(), true);
 
     CurrShell aCurr( this );
 
diff --git a/sw/source/uibase/inc/wrtsh.hxx b/sw/source/uibase/inc/wrtsh.hxx
index 98b3d9038204..801e52bef7ab 100644
--- a/sw/source/uibase/inc/wrtsh.hxx
+++ b/sw/source/uibase/inc/wrtsh.hxx
@@ -681,9 +681,10 @@ class MakeAllOutlineContentTemporarilyVisible
 private:
     SwWrtShell* m_pWrtSh = nullptr;
     bool m_bDone = false;
+    bool m_bScrollToCursor = false;
 public:
     static sal_uInt32 nLock;
-    MakeAllOutlineContentTemporarilyVisible(SwDoc* pDoc)
+    MakeAllOutlineContentTemporarilyVisible(SwDoc* pDoc, bool bScrollToCursor 
= false)
     {
         ++nLock;
         if (nLock > 1)
@@ -692,8 +693,10 @@ public:
             if ((m_pWrtSh = pDocSh->GetWrtShell()) && 
m_pWrtSh->GetViewOptions() &&
                     
m_pWrtSh->GetViewOptions()->IsShowOutlineContentVisibilityButton())
             {
-                m_pWrtSh->StartAllAction();
+                m_pWrtSh->LockView(true);
+                m_pWrtSh->LockPaint();
                 m_pWrtSh->MakeAllFoldedOutlineContentVisible();
+                m_bScrollToCursor = bScrollToCursor;
                 m_bDone = true;
             }
     }
@@ -706,7 +709,10 @@ public:
         if (m_bDone && m_pWrtSh)
         {
             m_pWrtSh->MakeAllFoldedOutlineContentVisible(false);
-            m_pWrtSh->EndAllAction();
+            m_pWrtSh->UnlockPaint();
+            m_pWrtSh->LockView(false);
+            if (m_bScrollToCursor)
+                m_pWrtSh->UpdateCursor(SwCursorShell::SCROLLWIN);
         }
     }
 };
diff --git a/sw/source/uibase/shells/basesh.cxx 
b/sw/source/uibase/shells/basesh.cxx
index 31f2c247b545..4c0d71e5e364 100644
--- a/sw/source/uibase/shells/basesh.cxx
+++ b/sw/source/uibase/shells/basesh.cxx
@@ -586,7 +586,7 @@ void SwBaseShell::StateClpbrd(SfxItemSet &rSet)
 
 void SwBaseShell::ExecUndo(SfxRequest &rReq)
 {
-    MakeAllOutlineContentTemporarilyVisible a(GetShell().GetDoc());
+    MakeAllOutlineContentTemporarilyVisible a(GetShell().GetDoc(), true);
 
     SwWrtShell &rWrtShell = GetShell();
 

Reply via email to