sw/source/uibase/dialog/SwSpellDialogChildWindow.cxx |   86 +++++++++----------
 1 file changed, 44 insertions(+), 42 deletions(-)

New commits:
commit ef63a5f8ea78833e38920cbe0dddb0e80750b1c4
Author:     Justin Luth <[email protected]>
AuthorDate: Fri Sep 26 18:48:36 2025 -0400
Commit:     Justin Luth <[email protected]>
CommitDate: Sat Sep 27 03:15:01 2025 +0200

    tdf#91151 SwSpellDialog: update spellState cursor position more often
    
    First of all, we need to split out the updating code
    so that we don't hackily call a "LoseFocus" function
    just because it happens to accomplish the task of updating spellState.
    The bulk of this patch is simply refactoring that.
    
    Then the fix was to unconditionally keep the spell state updated
    as each paragraph is processed.
    
    Doing this prevents the unnecessary "resume" request
    seen in the bug report,
    and that also helps to avoid early "finished" states.
    
    This unit test is similar to the bug report's test conditions:
    make -srj1 UITest_writer_tests4 \
      UITEST_TEST_NAME=spellDialog.SpellingAndGrammarDialog.test_tdf46852\
      SAL_USE_VCLPLUGIN=gen
    
    Change-Id: I67614c2146e2998624f6bf28a299bc3a16748cab
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191558
    Reviewed-by: Justin Luth <[email protected]>
    Tested-by: Jenkins

diff --git a/sw/source/uibase/dialog/SwSpellDialogChildWindow.cxx 
b/sw/source/uibase/dialog/SwSpellDialogChildWindow.cxx
index 97ff72af1290..4a10b6e6ce25 100644
--- a/sw/source/uibase/dialog/SwSpellDialogChildWindow.cxx
+++ b/sw/source/uibase/dialog/SwSpellDialogChildWindow.cxx
@@ -132,6 +132,46 @@ static void lcl_LeaveDrawText(SwWrtShell& rSh)
     }
 }
 
+static void lcl_updateSpellStateCursorPos(SpellState& rSpellState, const 
SwWrtShell& rWrtShell)
+{
+    rSpellState.m_eSelMode = rWrtShell.GetView().GetShellMode();
+    rSpellState.m_pPointNode = nullptr;
+    rSpellState.m_pMarkNode = nullptr;
+    rSpellState.m_nPointPos = 0;
+    rSpellState.m_nMarkPos = 0;
+    rSpellState.m_pOutliner = nullptr;
+
+    switch(rSpellState.m_eSelMode)
+    {
+        case ShellMode::Text:
+        case ShellMode::ListText:
+        case ShellMode::TableText:
+        case ShellMode::TableListText:
+        {
+            // store a node pointer and a pam-position to be able to check on 
next GetFocus();
+            const SwPaM& rCursor = *rWrtShell.GetCursor();
+            rSpellState.m_pPointNode = &rCursor.GetPointNode();
+            rSpellState.m_pMarkNode = &rCursor.GetMarkNode();
+            rSpellState.m_nPointPos = rCursor.GetPoint()->GetContentIndex();
+            rSpellState.m_nMarkPos = rCursor.GetMark()->GetContentIndex();
+
+        }
+        break;
+        case ShellMode::DrawText:
+        {
+            const SdrView& rSdrView = *rWrtShell.GetDrawView();
+            const SdrOutliner* pOutliner = rSdrView.GetTextEditOutliner();
+            rSpellState.m_pOutliner = pOutliner;
+            const OutlinerView* pOLV = rSdrView.GetTextEditOutlinerView();
+            OSL_ENSURE(pOutliner && pOLV, "no Outliner/OutlinerView in 
SwSpellDialogChildWindow::LoseFocus()");
+            if (pOLV)
+                rSpellState.m_aESelection = pOLV->GetSelection();
+        }
+        break;
+        default:;// prevent warning
+    }
+}
+
 SwSpellDialogChildWindow::SwSpellDialogChildWindow (
             vcl::Window* _pParent,
             sal_uInt16 nId,
@@ -391,13 +431,14 @@ The code below would only be part of the solution.
                     }
                     m_pSpellState->m_xStartRange = nullptr;
                     LockFocusNotification( false );
-                    // take care that the now valid selection is stored
-                    LoseFocus();
                 }
                 else
                     bCloseMessage = false; // no closing message if a wrap 
around has been denied
             }
         }
+
+        lcl_updateSpellStateCursorPos(*m_pSpellState, *pWrtShell);
+
         if( aRet.empty() && bCloseMessage )
         {
             LockFocusNotification( true );
@@ -411,8 +452,6 @@ The code below would only be part of the solution.
                                                   sInfo ) );
             xBox->run();
             LockFocusNotification( false );
-            // take care that the now valid selection is stored
-            LoseFocus();
             xSpellController->getDialog()->grab_focus();
         }
     }
@@ -571,44 +610,7 @@ void SwSpellDialogChildWindow::LoseFocus()
         return;
     SwWrtShell* pWrtShell = GetWrtShell_Impl();
     if(pWrtShell)
-    {
-        m_pSpellState->m_eSelMode = pWrtShell->GetView().GetShellMode();
-        m_pSpellState->m_pPointNode = m_pSpellState->m_pMarkNode = nullptr;
-        m_pSpellState->m_nPointPos = m_pSpellState->m_nMarkPos = 0;
-        m_pSpellState->m_pOutliner = nullptr;
-
-        switch(m_pSpellState->m_eSelMode)
-        {
-            case ShellMode::Text:
-            case ShellMode::ListText:
-            case ShellMode::TableText:
-            case ShellMode::TableListText:
-            {
-                // store a node pointer and a pam-position to be able to check 
on next GetFocus();
-                SwPaM* pCursor = pWrtShell->GetCursor();
-                m_pSpellState->m_pPointNode = &pCursor->GetPointNode();
-                m_pSpellState->m_pMarkNode = &pCursor->GetMarkNode();
-                m_pSpellState->m_nPointPos = 
pCursor->GetPoint()->GetContentIndex();
-                m_pSpellState->m_nMarkPos = 
pCursor->GetMark()->GetContentIndex();
-
-            }
-            break;
-            case ShellMode::DrawText:
-            {
-                SdrView*     pSdrView = pWrtShell->GetDrawView();
-                SdrOutliner* pOutliner = pSdrView->GetTextEditOutliner();
-                m_pSpellState->m_pOutliner = pOutliner;
-                OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView();
-                OSL_ENSURE(pOutliner && pOLV, "no Outliner/OutlinerView in 
SwSpellDialogChildWindow::LoseFocus()");
-                if(pOLV)
-                {
-                    m_pSpellState->m_aESelection = pOLV->GetSelection();
-                }
-            }
-            break;
-            default:;// prevent warning
-        }
-    }
+        lcl_updateSpellStateCursorPos(*m_pSpellState, *pWrtShell);
     else
         m_pSpellState->m_eSelMode = ShellMode::Object;
 }

Reply via email to