diff options
author | Michael Stahl <mstahl@redhat.com> | 2015-09-09 10:30:04 +0200 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2015-09-09 14:13:48 +0200 |
commit | 4c91e94e892943ef5e031d65f6f42864233cb4cd (patch) | |
tree | c9f6e59cf2d776e028692ff19e58af57fea5deeb /sw/source/core/txtnode | |
parent | f9f3e97ca867db59f2fc2e4fdb5583ed49cab49c (diff) |
tdf#92036: sw: fix idle spelling loop
There is a sort of intentional infinite loop in the idle spell checking
handler: while the user is typing a word, it should not be marked as
invalid yet, in order not to annoy them with red underlines.
So the word where the cursor is positioned always remained dirty, unless
you happen to have a grammar checker enabled, which clears the
paragraph's dirty flag from a separate thread.
To avoid the infinite loop, add another spell checking state "PENDING"
which is the same as dirty except that it should cancel the idle spell
checking.
The idle spell checking will run again when the user does the next
editing operation. Notably this means if the user just moves the cursor
out of the wrongly spelled word, it won't be underlined yet, but that
appears a minor issue, and checking when the cursor leaves the word
appears too hard to implement.
Change-Id: Ifb3d6d17f94f9f1cfad82e70dfa79f1594c38647
Diffstat (limited to 'sw/source/core/txtnode')
-rw-r--r-- | sw/source/core/txtnode/ndtxt.cxx | 14 | ||||
-rw-r--r-- | sw/source/core/txtnode/txtedt.cxx | 43 |
2 files changed, 37 insertions, 20 deletions
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx index aa374587d594..08da02c165cd 100644 --- a/sw/source/core/txtnode/ndtxt.cxx +++ b/sw/source/core/txtnode/ndtxt.cxx @@ -428,7 +428,7 @@ SwContentNode *SwTextNode::SplitContentNode( const SwPosition &rPos ) { pNode->SetWrong( GetWrong()->SplitList( nSplitPos ) ); } - SetWrongDirty( true ); + SetWrongDirty(WrongState::TODO); if( GetGrammarCheck() ) { @@ -531,7 +531,7 @@ SwContentNode *SwTextNode::SplitContentNode( const SwPosition &rPos ) { SwWrongList *pList = GetWrong(); SetWrong( 0, false ); - SetWrongDirty( true ); + SetWrongDirty(WrongState::TODO); SwGrammarMarkUp *pList3 = GetGrammarCheck(); SetGrammarCheck( 0, false ); @@ -652,7 +652,7 @@ SwContentNode *SwTextNode::JoinNext() if( pList ) { pList->JoinList( pTextNode->GetWrong(), nOldLen ); - SetWrongDirty( true ); + SetWrongDirty(WrongState::TODO); SetWrong( 0, false ); } else @@ -661,7 +661,7 @@ SwContentNode *SwTextNode::JoinNext() if( pList ) { pList->Move( 0, nOldLen ); - SetWrongDirty( true ); + SetWrongDirty(WrongState::TODO); pTextNode->SetWrong( 0, false ); } } @@ -743,7 +743,7 @@ SwContentNode *SwTextNode::JoinPrev() if( pList ) { pList->JoinList( GetWrong(), Len() ); - SetWrongDirty( true ); + SetWrongDirty(WrongState::TODO); pTextNode->SetWrong( 0, false ); SetWrong( NULL ); } @@ -753,7 +753,7 @@ SwContentNode *SwTextNode::JoinPrev() if( pList ) { pList->Move( 0, nLen ); - SetWrongDirty( true ); + SetWrongDirty(WrongState::TODO); SetWrong( 0, false ); } } @@ -1387,7 +1387,7 @@ const SwTextInputField* SwTextNode::GetOverlappingInputField( const SwTextAttr& void SwTextNode::DelFrms_TextNodePart() { SetWrong( NULL ); - SetWrongDirty( true ); + SetWrongDirty(WrongState::TODO); SetGrammarCheck( NULL ); SetGrammarCheckDirty( true ); diff --git a/sw/source/core/txtnode/txtedt.cxx b/sw/source/core/txtnode/txtedt.cxx index 582c60f189a6..98095cff33c4 100644 --- a/sw/source/core/txtnode/txtedt.cxx +++ b/sw/source/core/txtnode/txtedt.cxx @@ -1311,6 +1311,7 @@ SwRect SwTextFrm::_AutoSpell( const SwContentNode* pActNode, sal_Int32 nActPos ) } bool bFresh = nBegin < nEnd; + bool bPending(false); if( bFresh ) { @@ -1353,13 +1354,19 @@ SwRect SwTextFrm::_AutoSpell( const SwContentNode* pActNode, sal_Int32 nActPos ) pNode->SetWrong( new SwWrongList( WRONGLIST_SPELL ) ); pNode->GetWrong()->SetInvalid( 0, nEnd ); } - if( pNode->GetWrong()->Fresh( nChgStart, nChgEnd, - nBegin, nLen, nInsertPos, nActPos ) ) - pNode->GetWrong()->Insert( OUString(), 0, nBegin, nLen, nInsertPos++ ); - else + SwWrongList::FreshState const eState(pNode->GetWrong()->Fresh( + nChgStart, nChgEnd, nBegin, nLen, nInsertPos, nActPos)); + switch (eState) { - nInvStart = nBegin; - nInvEnd = nBegin + nLen; + case SwWrongList::FreshState::FRESH: + pNode->GetWrong()->Insert(OUString(), 0, nBegin, nLen, nInsertPos++); + break; + case SwWrongList::FreshState::CURSOR: + bPending = true; // fall-through to mark as invalid + case SwWrongList::FreshState::NOTHING: + nInvStart = nBegin; + nInvEnd = nBegin + nLen; + break; } } } @@ -1402,12 +1409,17 @@ SwRect SwTextFrm::_AutoSpell( const SwContentNode* pActNode, sal_Int32 nActPos ) } pNode->GetWrong()->SetInvalid( nInvStart, nInvEnd ); - pNode->SetWrongDirty( COMPLETE_STRING != pNode->GetWrong()->GetBeginInv() ); + pNode->SetWrongDirty( + (COMPLETE_STRING != pNode->GetWrong()->GetBeginInv()) + ? ((bPending) + ? SwTextNode::WrongState::PENDING + : SwTextNode::WrongState::TODO) + : SwTextNode::WrongState::DONE); if( !pNode->GetWrong()->Count() && ! pNode->IsWrongDirty() ) pNode->SetWrong( NULL ); } else - pNode->SetWrongDirty( false ); + pNode->SetWrongDirty(SwTextNode::WrongState::DONE); if( bAddAutoCmpl ) pNode->SetAutoCompleteWordDirty( false ); @@ -2115,7 +2127,7 @@ struct SwParaIdleData_Impl sal_uLong nNumberOfChars; sal_uLong nNumberOfCharsExcludingSpaces; bool bWordCountDirty; - bool bWrongDirty; // Ist das Wrong-Feld auf invalid? + SwTextNode::WrongState eWrongDirty; ///< online spell checking needed/done? bool bGrammarCheckDirty; bool bSmartTagDirty; bool bAutoComplDirty; // die ACompl-Liste muss angepasst werden @@ -2129,7 +2141,7 @@ struct SwParaIdleData_Impl nNumberOfChars ( 0 ), nNumberOfCharsExcludingSpaces ( 0 ), bWordCountDirty ( true ), - bWrongDirty ( true ), + eWrongDirty ( SwTextNode::WrongState::TODO ), bGrammarCheckDirty ( true ), bSmartTagDirty ( true ), bAutoComplDirty ( true ) {}; @@ -2276,17 +2288,22 @@ bool SwTextNode::IsWordCountDirty() const return m_pParaIdleData_Impl && m_pParaIdleData_Impl->bWordCountDirty; } -void SwTextNode::SetWrongDirty( bool bNew ) const +void SwTextNode::SetWrongDirty(WrongState eNew) const { if ( m_pParaIdleData_Impl ) { - m_pParaIdleData_Impl->bWrongDirty = bNew; + m_pParaIdleData_Impl->eWrongDirty = eNew; } } +auto SwTextNode::GetWrongDirty() const -> WrongState +{ + return (m_pParaIdleData_Impl) ? m_pParaIdleData_Impl->eWrongDirty : WrongState::DONE; +} + bool SwTextNode::IsWrongDirty() const { - return m_pParaIdleData_Impl && m_pParaIdleData_Impl->bWrongDirty; + return m_pParaIdleData_Impl && m_pParaIdleData_Impl->eWrongDirty != WrongState::DONE; } void SwTextNode::SetGrammarCheckDirty( bool bNew ) const |