summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
Diffstat (limited to 'sw')
-rw-r--r--sw/inc/crsrsh.hxx12
-rw-r--r--sw/inc/viewsh.hxx7
-rw-r--r--sw/qa/extras/uiwriter/uiwriter6.cxx10
-rw-r--r--sw/source/core/crsr/crsrsh.cxx21
-rw-r--r--sw/source/core/crsr/viscrs.cxx27
-rw-r--r--sw/source/core/inc/txtfrm.hxx2
-rw-r--r--sw/source/core/txtnode/txtedt.cxx8
7 files changed, 51 insertions, 36 deletions
diff --git a/sw/inc/crsrsh.hxx b/sw/inc/crsrsh.hxx
index f5e52e398f3d..2417fb507cae 100644
--- a/sw/inc/crsrsh.hxx
+++ b/sw/inc/crsrsh.hxx
@@ -23,6 +23,7 @@
#include <rtl/ustring.hxx>
#include <tools/link.hxx>
+#include <vcl/idle.hxx>
#include <vcl/keycod.hxx>
#include <o3tl/typed_flags_set.hxx>
@@ -243,8 +244,14 @@ private:
bool m_bMacroExecAllowed : 1;
+ // SwViewShell::LayoutIdle needs to be called on cursor update to repeat a spell check,
+ // because previous attempt marked a word as pending, because the word had cursor
+ bool m_bNeedLayoutOnCursorUpdate : 1 = false;
+
SwFrame* m_oldColFrame;
+ Idle m_aLayoutIdle; // An idle to schedule another SwViewShell::LayoutIdle call
+
void MoveCursorToNum();
void ParkPams( SwPaM* pDelRg, SwShellCursor** ppDelRing );
@@ -285,6 +292,9 @@ private:
const SwRangeRedline* GotoRedline_( SwRedlineTable::size_type nArrPos, bool bSelect );
void sendLOKCursorUpdates();
+
+ DECL_LINK(DoLayoutIdle, Timer*, void); // calls SwViewShell::LayoutIdle
+
protected:
inline SwMoveFnCollection const & MakeFindRange( SwDocPositions, SwDocPositions, SwPaM* ) const;
@@ -308,6 +318,8 @@ protected:
protected:
virtual void SwClientNotify(const SwModify&, const SfxHint&) override;
+ virtual void OnSpellWrongStatePending() override { m_bNeedLayoutOnCursorUpdate = true; }
+
public:
SwCursorShell( SwDoc& rDoc, vcl::Window *pWin, const SwViewOption *pOpt );
// disguised copy constructor
diff --git a/sw/inc/viewsh.hxx b/sw/inc/viewsh.hxx
index b53a3ed7b719..01a3cc259929 100644
--- a/sw/inc/viewsh.hxx
+++ b/sw/inc/viewsh.hxx
@@ -609,6 +609,13 @@ public:
void GetFirstLastVisPageNumbers(SwVisiblePageNumbers& rVisiblePageNumbers, SwView& rView);
virtual void dumpAsXml(xmlTextWriterPtr pWriter) const;
+
+ // SwTextFrame::AutoSpell_ calls this, to notify the shell, that a word has a spelling error,
+ // but that couldn't be drawn, because the cursor was in that word (so that the user is not
+ // annoyed while typing). The shell's task is to re-run the spell check (i.e., call LayoutIdle,
+ // which internally does the spell check), when the cursor leaves that word (implemented in
+ // SwCursorShell).
+ virtual void OnSpellWrongStatePending() {}
};
// manages global ShellPointer
diff --git a/sw/qa/extras/uiwriter/uiwriter6.cxx b/sw/qa/extras/uiwriter/uiwriter6.cxx
index a27f506095b3..a9dc5530dab6 100644
--- a/sw/qa/extras/uiwriter/uiwriter6.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter6.cxx
@@ -2227,16 +2227,9 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf124603)
bool bPending = !pNode->GetWrong() || !pNode->GetWrong()->Count();
CPPUNIT_ASSERT(bPending);
- // Move right, leave the bad word
+ // Move right, leave the bad word - since the fix for tdf#136294, this triggers the check
pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
- // tdf#92036 still pending spell checking
- bPending = !pNode->GetWrong() || !pNode->GetWrong()->Count();
- CPPUNIT_ASSERT(bPending);
-
- // Move down to trigger spell checking
-
- pWrtShell->Down(/*bSelect=*/false, 1);
Scheduler::ProcessEventsToIdle();
CPPUNIT_ASSERT(pNode->GetWrong());
// This was 0 (pending spell checking)
@@ -2286,6 +2279,7 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf45949)
// Move down to trigger spell checking
pWrtShell->Down(/*bSelect=*/false, 1);
+ Scheduler::ProcessEventsToIdle();
// Without the fix in place, this test would have failed with
// - Expected: 3
diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index f0dd6e938c14..db1e6cfd7e47 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -1917,6 +1917,15 @@ void SwCursorShell::UpdateCursor( sal_uInt16 eFlags, bool bIdleEnd )
return; // if not then no update
}
+ if (m_bNeedLayoutOnCursorUpdate)
+ {
+ // A previous spell check skipped a word that had a spelling error, because that word
+ // had cursor. Now schedule the idle to call SwViewShell::LayoutIdle, to repeat the
+ // spell check, in the hope that the cursor has left the word.
+ m_aLayoutIdle.Start();
+ m_bNeedLayoutOnCursorUpdate = false;
+ }
+
#if !ENABLE_WASM_STRIP_ACCESSIBILITY
SwNotifyAccAboutInvalidTextSelections aInvalidateTextSelections( *this );
#endif
@@ -3312,6 +3321,7 @@ SwCursorShell::SwCursorShell( SwCursorShell& rShell, vcl::Window *pInitWin )
, m_eEnhancedTableSel(SwTable::SEARCH_NONE)
, m_nMarkedListLevel( 0 )
, m_oldColFrame(nullptr)
+ , m_aLayoutIdle("SwCursorShell m_aLayoutIdle")
{
CurrShell aCurr( this );
// only keep the position of the current cursor of the copy shell
@@ -3327,6 +3337,9 @@ SwCursorShell::SwCursorShell( SwCursorShell& rShell, vcl::Window *pInitWin )
m_bSetCursorInReadOnly = true;
m_pVisibleCursor = new SwVisibleCursor( this );
m_bMacroExecAllowed = rShell.IsMacroExecAllowed();
+
+ m_aLayoutIdle.SetPriority(TaskPriority::LOWEST);
+ m_aLayoutIdle.SetInvokeHandler(LINK(this, SwCursorShell, DoLayoutIdle));
}
/// default constructor
@@ -3349,6 +3362,7 @@ SwCursorShell::SwCursorShell( SwDoc& rDoc, vcl::Window *pInitWin,
, m_eEnhancedTableSel(SwTable::SEARCH_NONE)
, m_nMarkedListLevel( 0 )
, m_oldColFrame(nullptr)
+ , m_aLayoutIdle("SwCursorShell m_aLayoutIdle")
{
CurrShell aCurr( this );
// create initial cursor and set it to first content position
@@ -3373,10 +3387,15 @@ SwCursorShell::SwCursorShell( SwDoc& rDoc, vcl::Window *pInitWin,
m_pVisibleCursor = new SwVisibleCursor( this );
m_bMacroExecAllowed = true;
+
+ m_aLayoutIdle.SetPriority(TaskPriority::LOWEST);
+ m_aLayoutIdle.SetInvokeHandler(LINK(this, SwCursorShell, DoLayoutIdle));
}
SwCursorShell::~SwCursorShell()
{
+ m_aLayoutIdle.Stop();
+
// if it is not the last view then at least the field should be updated
if( !unique() )
CheckTableBoxContent( m_pCurrentCursor->GetPoint() );
@@ -3405,6 +3424,8 @@ SwCursorShell::~SwCursorShell()
EndListeningAll();
}
+IMPL_LINK_NOARG(SwCursorShell, DoLayoutIdle, Timer*, void) { LayoutIdle(); }
+
SwShellCursor* SwCursorShell::getShellCursor( bool bBlock )
{
if( m_pTableCursor )
diff --git a/sw/source/core/crsr/viscrs.cxx b/sw/source/core/crsr/viscrs.cxx
index 0a0f5f186d93..8a69bc597be2 100644
--- a/sw/source/core/crsr/viscrs.cxx
+++ b/sw/source/core/crsr/viscrs.cxx
@@ -1069,33 +1069,6 @@ void SwShellCursor::SaveTableBoxContent( const SwPosition* pPos )
bool SwShellCursor::UpDown( bool bUp, sal_uInt16 nCnt )
{
- // tdf#124603 trigger pending spell checking of the node
- if ( nCnt == 1 )
- {
- SwTextNode* pNode = GetPoint()->GetNode().GetTextNode();
- if( pNode && sw::WrongState::PENDING == pNode->GetWrongDirty() )
- {
- SwWrtShell* pShell = pNode->GetDoc().GetDocShell()->GetWrtShell();
- if ( pShell && !pShell->IsSelection() && !pShell->IsSelFrameMode() )
- {
- const SwViewOption* pVOpt = pShell->GetViewOptions();
- if ( pVOpt && pVOpt->IsOnlineSpell() )
- {
- const bool bOldViewLock = pShell->IsViewLocked();
- pShell->LockView( true );
-
- SwTextFrame* pFrame(
- static_cast<SwTextFrame*>(pNode->getLayoutFrame(GetShell()->GetLayout())));
- SwRect aRepaint(pFrame->AutoSpell_(*pNode, 0));
- if (aRepaint.HasArea())
- pShell->InvalidateWindows(aRepaint);
-
- pShell->LockView( bOldViewLock );
- }
- }
- }
- }
-
return SwCursor::UpDown( bUp, nCnt,
&GetPtPos(), GetShell()->GetUpDownX(),
*GetShell()->GetLayout());
diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx
index addf6f6fb7f9..5905c60352a8 100644
--- a/sw/source/core/inc/txtfrm.hxx
+++ b/sw/source/core/inc/txtfrm.hxx
@@ -353,7 +353,7 @@ public:
*/
void Init();
- /// Is called by DoIdleJob_(), ExecSpellPopup() and UpDown()
+ /// Is called by DoIdleJob_() and ExecSpellPopup()
SwRect AutoSpell_(SwTextNode &, sal_Int32);
/// Is called by DoIdleJob_()
diff --git a/sw/source/core/txtnode/txtedt.cxx b/sw/source/core/txtnode/txtedt.cxx
index 2f3e7aa6db86..a1bfb0c0f3c1 100644
--- a/sw/source/core/txtnode/txtedt.cxx
+++ b/sw/source/core/txtnode/txtedt.cxx
@@ -1490,6 +1490,14 @@ SwRect SwTextFrame::AutoSpell_(SwTextNode & rNode, sal_Int32 nActPos)
: sw::WrongState::DONE);
if( !pNode->GetWrong()->Count() && ! pNode->IsWrongDirty() )
pNode->ClearWrong();
+
+ if (bPending && getRootFrame())
+ {
+ if (SwViewShell* pViewSh = getRootFrame()->GetCurrShell())
+ {
+ pViewSh->OnSpellWrongStatePending();
+ }
+ }
}
else
pNode->SetWrongDirty(sw::WrongState::DONE);