1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <swtypes.hxx>
22 #include <SwGrammarMarkUp.hxx>
27 #include <osl/diagnose.h>
29 SwWrongArea::SwWrongArea( OUString aType
, WrongListType listType
,
30 css::uno::Reference
< css::container::XStringKeyMap
> const & xPropertyBag
,
33 : maType(std::move(aType
)), mxPropertyBag(xPropertyBag
), mnPos(nPos
), mnLen(nLen
), mpSubList(nullptr)
35 mColor
= getWrongAreaColor(listType
, xPropertyBag
);
36 mLineType
= getWrongAreaLineType(listType
, xPropertyBag
);
39 SwWrongArea::SwWrongArea( OUString aType
,
40 css::uno::Reference
< css::container::XStringKeyMap
> const & xPropertyBag
,
43 SwWrongList
* pSubList
)
44 : maType(std::move(aType
)), mxPropertyBag(xPropertyBag
), mnPos(nPos
), mnLen(nLen
), mpSubList(pSubList
), mLineType(WRONGAREA_NONE
)
46 if (pSubList
!= nullptr)
48 mColor
= getWrongAreaColor(pSubList
->GetWrongListType(), xPropertyBag
);
49 mLineType
= getWrongAreaLineType(pSubList
->GetWrongListType(), xPropertyBag
);
53 SwWrongList::SwWrongList( WrongListType eType
) :
55 mnBeginInvalid(COMPLETE_STRING
), // everything correct... (the invalid area starts beyond the string)
56 mnEndInvalid (COMPLETE_STRING
)
61 SwWrongList::~SwWrongList()
66 SwWrongList
* SwWrongList::Clone()
68 SwWrongList
* pClone
= new SwWrongList( meType
);
69 pClone
->CopyFrom( *this );
73 void SwWrongList::CopyFrom( const SwWrongList
& rCopy
)
75 maList
= rCopy
.maList
;
76 meType
= rCopy
.meType
;
77 mnBeginInvalid
= rCopy
.mnBeginInvalid
;
78 mnEndInvalid
= rCopy
.mnEndInvalid
;
79 for(SwWrongArea
& i
: maList
)
82 i
.mpSubList
= i
.mpSubList
->Clone();
86 void SwWrongList::ClearList()
88 for (SwWrongArea
& i
: maList
)
91 i
.mpSubList
= nullptr;
96 /** If a word is incorrectly selected, this method returns begin and length of it.
98 @param[in,out] rChk starting position of the word to check
99 @param[out] rLn length of the word
101 @return <true> if incorrectly selected, <false> otherwise
103 bool SwWrongList::InWrongWord( sal_Int32
&rChk
, sal_Int32
&rLn
) const
105 const sal_uInt16 nPos
= GetWrongPos( rChk
);
106 if ( nPos
>= Count() )
108 const sal_Int32 nWrPos
= Pos( nPos
);
109 if ( nWrPos
<= rChk
)
112 if( nWrPos
+ rLn
<= rChk
)
120 /** Calculate first incorrectly selected area.
122 @param[in,out] rChk starting position of the word to check
123 @param[in,out] rLn length of the word
125 @return <true> if incorrectly selected area was found, <false> otherwise
127 bool SwWrongList::Check( sal_Int32
&rChk
, sal_Int32
&rLn
) const
129 sal_uInt16 nPos
= GetWrongPos( rChk
);
132 if( nPos
== Count() )
135 sal_Int32 nWrPos
= Pos( nPos
);
136 sal_Int32 nEnd
= nWrPos
+ Len( nPos
);
140 if( nPos
== Count() )
143 nWrPos
= Pos( nPos
);
144 nEnd
= nWrPos
+ Len( nPos
);
146 if( nEnd
> rChk
&& nWrPos
< rLn
)
158 /** Find next incorrectly selected position.
160 @param[in] rChk starting position of the word to check
162 @return starting position of incorrectly selected area, <COMPLETE_STRING> otherwise
164 sal_Int32
SwWrongList::NextWrong( sal_Int32 nChk
) const
166 sal_Int32 nRet
= COMPLETE_STRING
;
167 sal_uInt16 nPos
= GetWrongPos( nChk
);
171 if( nRet
< nChk
&& nRet
+ Len( nPos
) <= nChk
)
173 if( ++nPos
< Count() )
176 nRet
= COMPLETE_STRING
;
179 if( nRet
> GetBeginInv() && nChk
< GetEndInv() )
180 nRet
= std::max(nChk
, GetBeginInv());
184 /** Find the first position that is greater or equal to the given value.
186 @note Resulting position might be behind the last element of the array.
187 @param[in] nValue value for comparison
189 @return first position that is greater or equal to the given value
191 sal_uInt16
SwWrongList::GetWrongPos( sal_Int32 nValue
) const
193 sal_uInt16 nMax
= Count();
198 // For smart tag lists, we may not use a binary search. We return the
199 // position of the first smart tag which covers nValue
200 if ( !maList
[0].maType
.isEmpty() || maList
[0].mpSubList
)
202 auto aIter
= std::find_if(maList
.begin(), maList
.end(),
203 [nValue
](const SwWrongArea
& rST
) {
204 return (rST
.mnPos
<= nValue
&& nValue
< rST
.mnPos
+ rST
.mnLen
)
205 || (rST
.mnPos
> nValue
);
207 return o3tl::narrowing
<sal_uInt16
>(std::distance(maList
.begin(), aIter
));
212 while( nMin
<= nMax
)
214 nMid
= nMin
+ ( nMax
- nMin
) / 2;
215 const sal_Int32 nTmp
= Pos( nMid
);
221 else if( nTmp
< nValue
)
223 if( nTmp
+ Len( nMid
) >= nValue
)
239 // nMin now points to an index i into the wrong list which
240 // 1. nValue is inside [ Area[i].pos, Area[i].pos + Area[i].len ] (inclusive!!!)
241 // 2. nValue < Area[i].pos
246 void SwWrongList::Invalidate_( sal_Int32 nBegin
, sal_Int32 nEnd
)
248 if ( nBegin
< GetBeginInv() )
249 mnBeginInvalid
= nBegin
;
250 if ( nEnd
> GetEndInv() || GetEndInv() == COMPLETE_STRING
)
254 void SwWrongList::SetInvalid( sal_Int32 nBegin
, sal_Int32 nEnd
)
256 mnBeginInvalid
= nBegin
;
260 /** Change all values after the given position.
262 Needed after insert/deletion of characters.
264 @param nPos position after that everything should be changed
265 @param nDiff amount how much the positions should be moved
267 void SwWrongList::Move( sal_Int32 nPos
, sal_Int32 nDiff
)
269 sal_uInt16 i
= GetWrongPos( nPos
);
272 const sal_Int32 nEnd
= nPos
- nDiff
;
275 while( nLst
< Count() && Pos( nLst
) < nEnd
)
279 const sal_Int32 nWrPos
= Pos( nLst
- 1 );
280 if ( nWrPos
<= nPos
)
282 sal_Int32 nWrLen
= Len( nLst
- 1 );
283 // calculate new length of word
284 nWrLen
= ( nEnd
> nWrPos
+ nWrLen
) ?
289 maList
[--nLst
].mnLen
= nWrLen
;
294 Remove( i
, nLst
- i
);
298 if( COMPLETE_STRING
== GetBeginInv() )
299 SetInvalid( nPos
? nPos
- 1 : nPos
, nPos
+ 1 );
302 ShiftLeft( mnBeginInvalid
, nPos
, nEnd
);
303 if( mnEndInvalid
!= COMPLETE_STRING
)
304 ShiftLeft( mnEndInvalid
, nPos
, nEnd
);
305 Invalidate_( nPos
? nPos
- 1 : nPos
, nPos
+ 1 );
310 const sal_Int32 nEnd
= nPos
+ nDiff
;
311 if( COMPLETE_STRING
!= GetBeginInv() )
313 if( mnBeginInvalid
> nPos
)
314 mnBeginInvalid
+= nDiff
;
315 if( mnEndInvalid
>= nPos
&& mnEndInvalid
!= COMPLETE_STRING
)
316 mnEndInvalid
+= nDiff
;
318 // If the pointer is in the middle of a wrong word,
319 // invalidation must happen from the beginning of that word.
322 const sal_Int32 nWrPos
= Pos( i
);
325 Invalidate( nWrPos
, nEnd
);
326 const sal_Int32 nWrLen
= Len( i
) + nDiff
;
327 maList
[i
++].mnLen
= nWrLen
;
328 Invalidate( nWrPos
, nWrPos
+ nWrLen
);
332 Invalidate( nPos
, nEnd
);
336 maList
[i
++].mnPos
+= nDiff
;
340 // TODO: Complete documentation
341 /** Remove given range of entries
343 For a given range [nPos, nPos + nLen[ and an index nIndex, this function
344 basically counts the number of SwWrongArea entries starting with nIndex
345 up to nPos + nLen. All these entries are removed.
349 @param nPos starting position of the range
350 @param nLen length of the range
351 @param nIndex index to start lookup at
352 @param nCursorPos ???
354 @return <true> if ???
356 auto SwWrongList::Fresh( sal_Int32
&rStart
, sal_Int32
&rEnd
, sal_Int32 nPos
,
357 sal_Int32 nLen
, sal_uInt16 nIndex
, sal_Int32 nCursorPos
) -> FreshState
359 // length of word must be greater than 0
360 // only report a spelling error if the cursor position is outside the word,
361 // so that the user is not annoyed while typing
362 FreshState eRet
= nLen
363 ? (nCursorPos
> nPos
+ nLen
|| nCursorPos
< nPos
)
366 : FreshState::NOTHING
;
368 sal_Int32 nWrPos
= 0;
369 sal_Int32 nWrEnd
= rEnd
;
370 sal_uInt16 nCnt
= nIndex
;
373 nWrPos
= Pos( nCnt
);
374 if( nWrPos
< nPos
&& rStart
> nWrPos
)
378 while( nCnt
< Count() )
380 nWrPos
= Pos( nCnt
);
381 if ( nWrPos
>= nPos
)
383 nWrEnd
= nWrPos
+ Len( nCnt
++ );
386 if( nCnt
< Count() && nWrPos
== nPos
&& Len( nCnt
) == nLen
)
389 eRet
= FreshState::FRESH
;
393 if (FreshState::FRESH
== eRet
)
397 nWrEnd
= nPos
+ nLen
;
405 nWrPos
= Pos( nCnt
);
406 if( nWrPos
< nPos
&& rStart
> nWrPos
)
410 while( nCnt
< Count() )
412 nWrPos
= Pos( nCnt
);
413 if ( nWrPos
>= nPos
)
415 nWrEnd
= nWrPos
+ Len( nCnt
++ );
421 Remove( nIndex
, nCnt
- nIndex
);
426 void SwWrongList::Invalidate( sal_Int32 nBegin
, sal_Int32 nEnd
)
428 if (COMPLETE_STRING
== GetBeginInv())
429 SetInvalid( nBegin
, nEnd
);
431 Invalidate_( nBegin
, nEnd
);
434 bool SwWrongList::InvalidateWrong( )
438 const sal_Int32 nFirst
= Pos( 0 );
439 const sal_Int32 nLast
= Pos( Count() - 1 ) + Len( Count() - 1 );
440 Invalidate( nFirst
, nLast
);
446 std::unique_ptr
<SwWrongList
> SwWrongList::SplitList( sal_Int32 nSplitPos
)
448 std::unique_ptr
<SwWrongList
> pRet
;
450 while( nLst
< Count() && Pos( nLst
) < nSplitPos
)
454 sal_Int32 nWrPos
= Pos( nLst
- 1 );
455 sal_Int32 nWrLen
= Len( nLst
- 1 );
456 if ( nWrPos
+nWrLen
> nSplitPos
)
458 nWrLen
+= nWrPos
- nSplitPos
;
459 maList
[--nLst
].mnPos
= nSplitPos
;
460 maList
[nLst
].mnLen
= nWrLen
;
465 if( WRONGLIST_GRAMMAR
== GetWrongListType() )
466 pRet
.reset(new SwGrammarMarkUp());
468 pRet
.reset(new SwWrongList( GetWrongListType() ));
469 pRet
->Insert(0, maList
.begin(), ( nLst
>= maList
.size() ? maList
.end() : maList
.begin() + nLst
) );
470 pRet
->SetInvalid( GetBeginInv(), GetEndInv() );
471 pRet
->Invalidate_( nSplitPos
? nSplitPos
- 1 : nSplitPos
, nSplitPos
);
474 if( COMPLETE_STRING
== GetBeginInv() )
478 ShiftLeft( mnBeginInvalid
, 0, nSplitPos
);
479 if( mnEndInvalid
!= COMPLETE_STRING
)
480 ShiftLeft( mnEndInvalid
, 0, nSplitPos
);
483 for (nLst
= 0; nLst
< Count(); ++nLst
)
485 maList
[nLst
].mnPos
-= nSplitPos
;
490 void SwWrongList::JoinList( SwWrongList
* pNext
, sal_Int32 nInsertPos
)
494 OSL_ENSURE( GetWrongListType() == pNext
->GetWrongListType(), "type mismatch with next list" );
496 sal_uInt16 nCnt
= Count();
497 pNext
->Move( 0, nInsertPos
);
498 Insert(nCnt
, pNext
->maList
.begin(), pNext
->maList
.end());
500 Invalidate( pNext
->GetBeginInv(), pNext
->GetEndInv() );
501 if( nCnt
&& Count() > nCnt
)
503 sal_Int32 nWrPos
= Pos( nCnt
);
504 sal_Int32 nWrLen
= Len( nCnt
);
507 nWrPos
+= nInsertPos
;
508 nWrLen
-= nInsertPos
;
509 maList
[nCnt
].mnPos
= nWrPos
;
510 maList
[nCnt
].mnLen
= nWrLen
;
512 if( nWrPos
== Pos( nCnt
- 1 ) + Len( nCnt
- 1 ) )
514 nWrLen
+= Len( nCnt
- 1 );
515 maList
[nCnt
- 1].mnLen
= nWrLen
;
520 Invalidate( nInsertPos
? nInsertPos
- 1 : nInsertPos
, nInsertPos
+ 1 );
523 void SwWrongList::InsertSubList( sal_Int32 nNewPos
, sal_Int32 nNewLen
, sal_uInt16 nWhere
, SwWrongList
* pSubList
)
527 OSL_ENSURE( GetWrongListType() == pSubList
->GetWrongListType(), "type mismatch with sub list" );
529 std::vector
<SwWrongArea
>::iterator i
= maList
.begin();
530 if ( nWhere
>= maList
.size() )
531 i
= maList
.end(); // robust
534 maList
.insert(i
, SwWrongArea( OUString(), nullptr, nNewPos
, nNewLen
, pSubList
) );
537 // New functions: Necessary because SwWrongList has been changed to use std::vector
538 void SwWrongList::Insert(sal_uInt16 nWhere
, std::vector
<SwWrongArea
>::iterator startPos
, std::vector
<SwWrongArea
>::iterator
const & endPos
)
540 std::vector
<SwWrongArea
>::iterator i
= maList
.begin();
541 if ( nWhere
>= maList
.size() )
542 i
= maList
.end(); // robust
545 maList
.insert(i
, startPos
, endPos
); // insert [startPos, endPos[ before i
547 // ownership of the sublist is passed to maList, therefore we have to set the
548 // pSubList-Pointers to 0
549 while ( startPos
!= endPos
)
551 (*startPos
).mpSubList
= nullptr;
556 void SwWrongList::Remove(sal_uInt16 nIdx
, sal_uInt16 nLen
)
558 if ( nIdx
>= maList
.size() ) return;
559 std::vector
<SwWrongArea
>::iterator i1
= maList
.begin();
562 std::vector
<SwWrongArea
>::iterator i2
= i1
;
563 if ( nIdx
+ nLen
>= o3tl::narrowing
<sal_uInt16
>(maList
.size()) )
564 i2
= maList
.end(); // robust
568 std::vector
<SwWrongArea
>::iterator iLoop
= i1
;
569 while ( iLoop
!= i2
)
571 delete (*iLoop
).mpSubList
;
575 #if OSL_DEBUG_LEVEL > 0
576 const int nOldSize
= Count();
579 maList
.erase(i1
, i2
);
581 #if OSL_DEBUG_LEVEL > 0
582 OSL_ENSURE( Count() + nLen
== nOldSize
, "SwWrongList::Remove() trouble" );
586 void SwWrongList::RemoveEntry( sal_Int32 nBegin
, sal_Int32 nEnd
) {
587 std::vector
<SwWrongArea
>::const_iterator
aEnd(maList
.end());
588 auto aDelIter
= std::find_if(maList
.cbegin(), aEnd
,
589 [nBegin
](const SwWrongArea
& rST
) { return rST
.mnPos
>= nBegin
; });
590 auto aIter
= aDelIter
;
591 if( WRONGLIST_GRAMMAR
== GetWrongListType() )
595 aIter
= std::find_if(aDelIter
, aEnd
,
596 [nEnd
](const SwWrongArea
& rST
) { return rST
.mnPos
>= nEnd
; });
601 aIter
= std::find_if(aDelIter
, aEnd
,
602 [nBegin
, nEnd
](const SwWrongArea
& rST
) {
603 return (rST
.mnPos
!= nBegin
) || ((rST
.mnPos
+ rST
.mnLen
) != nEnd
);
606 auto nDel
= o3tl::narrowing
<sal_uInt16
>(std::distance(aDelIter
, aIter
));
609 auto nDelPos
= o3tl::narrowing
<sal_uInt16
>(std::distance(maList
.cbegin(), aDelIter
));
610 Remove( nDelPos
, nDel
);
614 bool SwWrongList::LookForEntry( sal_Int32 nBegin
, sal_Int32 nEnd
) {
615 auto aIter
= std::find_if(maList
.begin(), maList
.end(),
616 [nBegin
](const SwWrongArea
& rST
) { return rST
.mnPos
>= nBegin
; });
617 return aIter
!= maList
.end()
618 && nBegin
== (*aIter
).mnPos
619 && nEnd
== (*aIter
).mnPos
+ (*aIter
).mnLen
;
622 void SwWrongList::Insert( const OUString
& rType
,
623 css::uno::Reference
< css::container::XStringKeyMap
> const & xPropertyBag
,
624 sal_Int32 nNewPos
, sal_Int32 nNewLen
)
626 auto aIter
= std::find_if(maList
.begin(), maList
.end(),
627 [nNewPos
](const SwWrongArea
& rST
) { return nNewPos
<= rST
.mnPos
; });
628 if ( aIter
!= maList
.end() && nNewPos
== (*aIter
).mnPos
)
630 const sal_Int32 nSTPos
= (*aIter
).mnPos
;
632 aIter
= std::find_if(aIter
, maList
.end(),
633 [nSTPos
, nNewLen
](const SwWrongArea
& rST
) { return rST
.mnPos
!= nSTPos
|| nNewLen
< rST
.mnLen
; });
636 maList
.insert(aIter
, SwWrongArea( rType
, meType
, xPropertyBag
, nNewPos
, nNewLen
) );
641 WrongListIteratorBase::WrongListIteratorBase(SwTextFrame
const& rFrame
,
642 SwWrongList
const* (SwTextNode::*pGetWrongList
)() const)
643 : m_pGetWrongList(pGetWrongList
)
644 , m_pMergedPara(rFrame
.GetMergedPara())
647 , m_pWrongList(m_pMergedPara
649 : (rFrame
.GetTextNodeFirst()->*pGetWrongList
)())
653 WrongListIteratorBase::WrongListIteratorBase(SwWrongList
const& rWrongList
)
654 : m_pGetWrongList(nullptr)
655 , m_pMergedPara(nullptr)
658 , m_pWrongList(&rWrongList
)
662 WrongListIterator::WrongListIterator(SwTextFrame
const& rFrame
,
663 SwWrongList
const* (SwTextNode::*pGetWrongList
)() const)
664 : WrongListIteratorBase(rFrame
, pGetWrongList
)
668 WrongListIterator::WrongListIterator(SwWrongList
const& rWrongList
)
669 : WrongListIteratorBase(rWrongList
)
673 bool WrongListIterator::Check(TextFrameIndex
& rStart
, TextFrameIndex
& rLen
)
677 if (rStart
< m_CurrentIndex
)
680 m_CurrentIndex
= TextFrameIndex(0);
682 while (m_CurrentExtent
< m_pMergedPara
->extents
.size())
684 sw::Extent
const& rExtent(m_pMergedPara
->extents
[m_CurrentExtent
]);
685 if (rStart
+ rLen
<= m_CurrentIndex
)
689 else if (rStart
< m_CurrentIndex
)
691 rLen
-= m_CurrentIndex
- rStart
;
692 assert(0 < sal_Int32(rLen
));
693 rStart
= m_CurrentIndex
;
695 if (m_CurrentIndex
<= rStart
&&
696 rStart
< m_CurrentIndex
+ TextFrameIndex(rExtent
.nEnd
- rExtent
.nStart
))
698 SwWrongList
const*const pWrongList((rExtent
.pNode
->*m_pGetWrongList
)());
699 // found the extent containing start - first, call Check
700 sal_Int32
nStart(rExtent
.nStart
+ sal_Int32(rStart
- m_CurrentIndex
)); // (m_CurrentIndex - m_CurrentNodeIndex));
702 if (sal_Int32(rLen
) < rExtent
.nEnd
- nStart
)
704 nLen
= sal_Int32(rLen
);
708 sal_Int32
nInLen(rLen
);
709 nLen
= rExtent
.nEnd
- nStart
;
711 for (size_t i
= m_CurrentExtent
+ 1;
712 i
< m_pMergedPara
->extents
.size(); ++i
)
714 sw::Extent
const& rExtentEnd(m_pMergedPara
->extents
[i
]);
715 if (rExtentEnd
.pNode
!= rExtent
.pNode
)
720 nLen
+= rExtentEnd
.nStart
- m_pMergedPara
->extents
[i
-1].nEnd
;
721 if (nInLen
<= rExtentEnd
.nEnd
- rExtentEnd
.nStart
)
726 nLen
+= rExtentEnd
.nEnd
- rExtentEnd
.nStart
;
727 nInLen
-= rExtentEnd
.nEnd
- rExtentEnd
.nStart
;
730 if (pWrongList
&& pWrongList
->Check(nStart
, nLen
))
732 // check if there's overlap with this extent
733 if (rExtent
.nStart
<= nStart
&& nStart
< rExtent
.nEnd
)
735 // yes - now compute end position / length
736 sal_Int32
const nEnd(nStart
+ nLen
);
737 rStart
= m_CurrentIndex
+ TextFrameIndex(nStart
- rExtent
.nStart
);
738 TextFrameIndex
const nOrigLen(rLen
);
739 if (nEnd
<= rExtent
.nEnd
)
741 rLen
= TextFrameIndex(nEnd
- nStart
);
743 else // have to search other extents for the end...
745 rLen
= TextFrameIndex(rExtent
.nEnd
- nStart
);
746 for (size_t i
= m_CurrentExtent
+ 1;
747 i
< m_pMergedPara
->extents
.size(); ++i
)
749 sw::Extent
const& rExtentEnd(m_pMergedPara
->extents
[i
]);
750 if (rExtentEnd
.pNode
!= rExtent
.pNode
751 || nEnd
<= rExtentEnd
.nStart
)
755 if (nEnd
<= rExtentEnd
.nEnd
)
757 rLen
+= TextFrameIndex(nEnd
- rExtentEnd
.nStart
);
760 rLen
+= TextFrameIndex(rExtentEnd
.nEnd
- rExtentEnd
.nStart
);
763 assert(rLen
<= nOrigLen
); (void) nOrigLen
;
768 m_CurrentIndex
+= TextFrameIndex(rExtent
.nEnd
- rExtent
.nStart
);
773 else if (m_pWrongList
)
775 sal_Int32
nStart(rStart
);
776 sal_Int32
nLen(rLen
);
777 bool const bRet(m_pWrongList
->Check(nStart
, nLen
));
778 rStart
= TextFrameIndex(nStart
);
779 rLen
= TextFrameIndex(nLen
);
786 WrongListIterator::GetWrongElement(TextFrameIndex
const nStart
)
790 if (nStart
< m_CurrentIndex
)
793 m_CurrentIndex
= TextFrameIndex(0);
795 while (m_CurrentExtent
< m_pMergedPara
->extents
.size())
797 sw::Extent
const& rExtent(m_pMergedPara
->extents
[m_CurrentExtent
]);
798 if (m_CurrentIndex
<= nStart
&&
799 nStart
<= m_CurrentIndex
+ TextFrameIndex(rExtent
.nEnd
- rExtent
.nStart
))
801 // note: the returned object isn't wrapped because fntcache.cxx
802 // does not look at its positions, only its formatting props
803 SwWrongList
const*const pWrongList((rExtent
.pNode
->*m_pGetWrongList
)());
806 sal_Int32
const nNStart(rExtent
.nStart
+ sal_Int32(nStart
- m_CurrentIndex
)); // (m_CurrentIndex - m_CurrentNodeIndex));
807 sal_Int16
const nPos(pWrongList
->GetWrongPos(nNStart
));
808 return pWrongList
->GetElement(nPos
);
811 m_CurrentIndex
+= TextFrameIndex(rExtent
.nEnd
- rExtent
.nStart
);
816 else if (m_pWrongList
)
818 sal_Int16
const nPos(m_pWrongList
->GetWrongPos(sal_Int32(nStart
)));
819 return m_pWrongList
->GetElement(nPos
);
824 WrongListIteratorCounter::WrongListIteratorCounter(SwTextFrame
const& rFrame
,
825 SwWrongList
const* (SwTextNode::*pGetWrongList
)() const)
826 : WrongListIteratorBase(rFrame
, pGetWrongList
)
830 WrongListIteratorCounter::WrongListIteratorCounter(SwWrongList
const& rWrongList
)
831 : WrongListIteratorBase(rWrongList
)
835 sal_uInt16
WrongListIteratorCounter::GetElementCount()
841 m_CurrentIndex
= TextFrameIndex(0);
842 SwNode
const* pNode(nullptr);
843 sal_uInt16
InCurrentNode(0);
844 while (m_CurrentExtent
< m_pMergedPara
->extents
.size())
846 sw::Extent
const& rExtent(m_pMergedPara
->extents
[m_CurrentExtent
]);
847 if (rExtent
.pNode
!= pNode
)
850 pNode
= rExtent
.pNode
;
852 SwWrongList
const*const pWrongList((rExtent
.pNode
->*m_pGetWrongList
)());
853 for (; pWrongList
&& InCurrentNode
< pWrongList
->Count(); ++InCurrentNode
)
855 SwWrongArea
const*const pWrong(pWrongList
->GetElement(InCurrentNode
));
856 TextFrameIndex
const nExtentEnd(
857 m_CurrentIndex
+ TextFrameIndex(rExtent
.nEnd
- rExtent
.nStart
));
858 if (nExtentEnd
<= TextFrameIndex(pWrong
->mnPos
))
860 break; // continue outer loop
862 if (m_CurrentIndex
< TextFrameIndex(pWrong
->mnPos
+ pWrong
->mnLen
))
867 m_CurrentIndex
+= TextFrameIndex(rExtent
.nEnd
- rExtent
.nStart
);
872 else if (m_pWrongList
)
874 return m_pWrongList
->Count();
879 std::optional
<std::pair
<TextFrameIndex
, TextFrameIndex
>>
880 WrongListIteratorCounter::GetElementAt(sal_uInt16 nIndex
)
885 m_CurrentIndex
= TextFrameIndex(0);
886 SwNode
const* pNode(nullptr);
887 sal_uInt16
InCurrentNode(0);
888 while (m_CurrentExtent
< m_pMergedPara
->extents
.size())
890 sw::Extent
const& rExtent(m_pMergedPara
->extents
[m_CurrentExtent
]);
891 if (rExtent
.pNode
!= pNode
)
894 pNode
= rExtent
.pNode
;
896 SwWrongList
const*const pWrongList((rExtent
.pNode
->*m_pGetWrongList
)());
897 for (; pWrongList
&& InCurrentNode
< pWrongList
->Count(); ++InCurrentNode
)
899 SwWrongArea
const*const pWrong(pWrongList
->GetElement(InCurrentNode
));
900 TextFrameIndex
const nExtentEnd(
901 m_CurrentIndex
+ TextFrameIndex(rExtent
.nEnd
- rExtent
.nStart
));
902 if (nExtentEnd
<= TextFrameIndex(pWrong
->mnPos
))
904 break; // continue outer loop
906 if (m_CurrentIndex
< TextFrameIndex(pWrong
->mnPos
+ pWrong
->mnLen
))
910 return std::optional
<std::pair
<TextFrameIndex
, TextFrameIndex
>>(
911 std::pair
<TextFrameIndex
, TextFrameIndex
>(
912 m_CurrentIndex
- TextFrameIndex(rExtent
.nStart
-
913 std::max(rExtent
.nStart
, pWrong
->mnPos
)),
914 m_CurrentIndex
- TextFrameIndex(rExtent
.nStart
-
915 std::min(pWrong
->mnPos
+ pWrong
->mnLen
, rExtent
.nEnd
))));
920 m_CurrentIndex
+= TextFrameIndex(rExtent
.nEnd
- rExtent
.nStart
);
923 return std::optional
<std::pair
<TextFrameIndex
, TextFrameIndex
>>();
925 else if (m_pWrongList
)
927 SwWrongArea
const*const pWrong(m_pWrongList
->GetElement(nIndex
));
928 return std::optional
<std::pair
<TextFrameIndex
, TextFrameIndex
>>(
929 std::pair
<TextFrameIndex
, TextFrameIndex
>(
930 TextFrameIndex(pWrong
->mnPos
),
931 TextFrameIndex(pWrong
->mnPos
+ pWrong
->mnLen
)));
933 return std::optional
<std::pair
<TextFrameIndex
, TextFrameIndex
>>();
938 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */