Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/sw/source/core/text/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 29 kB image not shown  

Quelle  wrong.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#include <swtypes.hxx>

#include <SwGrammarMarkUp.hxx>
#include <ndtxt.hxx>
#include <txtfrm.hxx>
#include <utility>

#include <osl/diagnose.h>

SwWrongArea::SwWrongArea( OUString aType, WrongListType listType,
        css::uno::Reference< css::container::XStringKeyMap > const & xPropertyBag,
        sal_Int32 nPos,
        sal_Int32 nLen)
: maType(std::move(aType)), mxPropertyBag(xPropertyBag), mnPos(nPos), mnLen(nLen), mpSubList(nullptr)
{
    mColor =  getWrongAreaColor(listType, xPropertyBag);
    mLineType = getWrongAreaLineType(listType, xPropertyBag);
}

SwWrongArea::SwWrongArea( OUString aType,
        css::uno::Reference< css::container::XStringKeyMap > const & xPropertyBag,
        sal_Int32 nPos,
        sal_Int32 nLen,
        SwWrongList* pSubList)
: maType(std::move(aType)), mxPropertyBag(xPropertyBag), mnPos(nPos), mnLen(nLen), mpSubList(pSubList), mLineType(WRONGAREA_NONE)
{
    if (pSubList != nullptr)
    {
        mColor =  getWrongAreaColor(pSubList->GetWrongListType(), xPropertyBag);
        mLineType = getWrongAreaLineType(pSubList->GetWrongListType(), xPropertyBag);
    }
}

SwWrongList::SwWrongList( WrongListType eType ) :
    meType       (eType),
    mnBeginInvalid(COMPLETE_STRING),  // everything correct... (the invalid area starts beyond the string)
    mnEndInvalid  (COMPLETE_STRING)
{
    maList.reserve( 5 );
}

SwWrongList::~SwWrongList()
{
    ClearList();
}

SwWrongList* SwWrongList::Clone()
{
    SwWrongList* pClone = new SwWrongList( meType );
    pClone->CopyFrom( *this );
    return pClone;
}

void SwWrongList::CopyFrom( const SwWrongList& rCopy )
{
    maList = rCopy.maList;
    meType = rCopy.meType;
    mnBeginInvalid = rCopy.mnBeginInvalid;
    mnEndInvalid = rCopy.mnEndInvalid;
    for(SwWrongArea & i : maList)
    {
        if( i.mpSubList )
            i.mpSubList = i.mpSubList->Clone();
    }
}

void SwWrongList::ClearList()
{
    for (SwWrongArea & i : maList)
    {
        delete i.mpSubList;
        i.mpSubList = nullptr;
    }
    maList.clear();
}

/** If a word is incorrectly selected, this method returns begin and length of it.

    @param[in,out] rChk starting position of the word to check
    @param[out]    rLn  length of the word

    @return <true> if incorrectly selected, <false> otherwise
 */

bool SwWrongList::InWrongWord( sal_Int32 &rChk, sal_Int32 &rLn ) const
{
    const sal_uInt16 nPos = GetWrongPos( rChk );
    if ( nPos >= Count() )
        return false;
    const sal_Int32 nWrPos = Pos( nPos );
    if ( nWrPos <= rChk )
    {
        rLn = Len( nPos );
        if( nWrPos + rLn <= rChk )
            return false;
        rChk = nWrPos;
        return true;
    }
    return false;
}

/** Calculate first incorrectly selected area.

    @param[in,out] rChk starting position of the word to check
    @param[in,out] rLn  length of the word

    @return <true> if incorrectly selected area was found, <false> otherwise
 */

bool SwWrongList::Check( sal_Int32 &rChk, sal_Int32 &rLn ) const
{
    sal_uInt16 nPos = GetWrongPos( rChk );
    rLn += rChk;

    if( nPos == Count() )
        return false;

    sal_Int32 nWrPos = Pos( nPos );
    sal_Int32 nEnd = nWrPos + Len( nPos );
    if( nEnd == rChk )
    {
        ++nPos;
        if( nPos == Count() )
            return false;

        nWrPos = Pos( nPos );
        nEnd = nWrPos + Len( nPos );
    }
    if( nEnd > rChk && nWrPos < rLn )
    {
        if( nWrPos > rChk )
            rChk = nWrPos;
        if( nEnd < rLn )
            rLn = nEnd;
        rLn -= rChk;
        return 0 != rLn;
    }
    return false;
}

/** Find next incorrectly selected position.

    @param[in] rChk starting position of the word to check

    @return starting position of incorrectly selected area, <COMPLETE_STRING> otherwise
 */

sal_Int32 SwWrongList::NextWrong( sal_Int32 nChk ) const
{
    sal_Int32 nRet = COMPLETE_STRING;
    sal_uInt16 nPos = GetWrongPos( nChk );
    if( nPos < Count() )
    {
        nRet = Pos( nPos );
        if( nRet < nChk && nRet + Len( nPos ) <= nChk )
        {
            if( ++nPos < Count() )
                nRet = Pos( nPos );
            else
                nRet = COMPLETE_STRING;
        }
    }
    if( nRet > GetBeginInv() && nChk < GetEndInv() )
        nRet = std::max(nChk, GetBeginInv());
    return nRet;
}

/** Find the first position that is greater or equal to the given value.

    @note Resulting position might be behind the last element of the array.
    @param[in] nValue value for comparison

    @return first position that is greater or equal to the given value
 */

sal_uInt16 SwWrongList::GetWrongPos( sal_Int32 nValue ) const
{
    sal_uInt16 nMax = Count();
    sal_uInt16 nMin = 0;

    if( nMax > 0 )
    {
        // For smart tag lists, we may not use a binary search. We return the
        // position of the first smart tag which covers nValue
        if ( !maList[0].maType.isEmpty() || maList[0].mpSubList )
        {
            auto aIter = std::find_if(maList.begin(), maList.end(),
                [nValue](const SwWrongArea& rST) {
                    return (rST.mnPos <= nValue && nValue < rST.mnPos + rST.mnLen)
                        || (rST.mnPos > nValue);
                });
            return o3tl::narrowing<sal_uInt16>(std::distance(maList.begin(), aIter));
        }

        --nMax;
        sal_uInt16 nMid = 0;
        while( nMin <= nMax )
        {
            nMid = nMin + ( nMax - nMin ) / 2;
            const sal_Int32 nTmp = Pos( nMid );
            if( nTmp == nValue )
            {
                nMin = nMid;
                break;
            }
            else if( nTmp < nValue )
            {
                if( nTmp + Len( nMid ) >= nValue )
                {
                    nMin = nMid;
                    break;
                }
                nMin = nMid + 1;
            }
            else if( nMid == 0 )
            {
                break;
            }
            else
                nMax = nMid - 1;
        }
    }

    // nMin now points to an index i into the wrong list which
    // 1. nValue is inside [ Area[i].pos, Area[i].pos + Area[i].len ] (inclusive!!!)
    // 2. nValue < Area[i].pos

    return nMin;
}

void SwWrongList::Invalidate_( sal_Int32 nBegin, sal_Int32 nEnd )
{
    if ( nBegin < GetBeginInv() )
        mnBeginInvalid = nBegin;
    if ( nEnd > GetEndInv() || GetEndInv() == COMPLETE_STRING )
        mnEndInvalid = nEnd;
}

void SwWrongList::SetInvalid( sal_Int32 nBegin, sal_Int32 nEnd )
{
    mnBeginInvalid = nBegin;
    mnEndInvalid = nEnd;
}

/** Change all values after the given position.

   Needed after insert/deletion of characters.

   @param nPos  position after that everything should be changed
   @param nDiff amount how much the positions should be moved
 */

void SwWrongList::Move( sal_Int32 nPos, sal_Int32 nDiff )
{
    sal_uInt16 i = GetWrongPos( nPos );
    if( nDiff < 0 )
    {
        const sal_Int32 nEnd = nPos - nDiff;
        sal_uInt16 nLst = i;
        bool bJump = false;
        while( nLst < Count() && Pos( nLst ) < nEnd )
            ++nLst;
        if( nLst > i )
        {
            const sal_Int32 nWrPos = Pos( nLst - 1 );
            if ( nWrPos <= nPos )
            {
                sal_Int32 nWrLen = Len( nLst - 1 );
                // calculate new length of word
                nWrLen = ( nEnd > nWrPos + nWrLen ) ?
                        nPos - nWrPos :
                        nWrLen + nDiff;
                if( nWrLen )
                {
                    maList[--nLst].mnLen = nWrLen;
                    bJump = true;
                }
            }
        }
        Remove( i, nLst - i );

        if ( bJump )
            ++i;
        if( COMPLETE_STRING == GetBeginInv() )
            SetInvalid( nPos ? nPos - 1 : nPos, nPos + 1 );
        else
        {
            ShiftLeft( mnBeginInvalid, nPos, nEnd );
            if( mnEndInvalid != COMPLETE_STRING )
                ShiftLeft( mnEndInvalid, nPos, nEnd );
            Invalidate_( nPos ? nPos - 1 : nPos, nPos + 1 );
        }
    }
    else
    {
        const sal_Int32 nEnd = nPos + nDiff;
        if( COMPLETE_STRING != GetBeginInv() )
        {
            if( mnBeginInvalid > nPos )
                mnBeginInvalid += nDiff;
            if( mnEndInvalid >= nPos && mnEndInvalid != COMPLETE_STRING )
                mnEndInvalid += nDiff;
        }
        // If the pointer is in the middle of a wrong word,
        // invalidation must happen from the beginning of that word.
        if( i < Count() )
        {
            const sal_Int32 nWrPos = Pos( i );
            if (nPos >= nWrPos)
            {
                Invalidate( nWrPos, nEnd );
                const sal_Int32 nWrLen = Len( i ) + nDiff;
                maList[i++].mnLen = nWrLen;
                Invalidate( nWrPos, nWrPos + nWrLen );
            }
        }
        else
            Invalidate( nPos, nEnd );
    }
    while( i < Count() )
    {
        maList[i++].mnPos += nDiff;
    }
}

// TODO: Complete documentation
/** Remove given range of entries

   For a given range [nPos, nPos + nLen[ and an index nIndex, this function
   basically counts the number of SwWrongArea entries starting with nIndex
   up to nPos + nLen. All these entries are removed.

   @param rStart     ???
   @param rEnd       ???
   @param nPos       starting position of the range
   @param nLen       length of the range
   @param nIndex     index to start lookup at
   @param nCursorPos ???

   @return <true> if ???
 */

auto SwWrongList::Fresh( sal_Int32 &rStart, sal_Int32 &rEnd, sal_Int32 nPos,
     sal_Int32 nLen, sal_uInt16 nIndex, sal_Int32 nCursorPos ) -> FreshState
{
    // length of word must be greater than 0
    // only report a spelling error if the cursor position is outside the word,
    // so that the user is not annoyed while typing
    FreshState eRet = nLen
        ? (nCursorPos > nPos + nLen || nCursorPos < nPos)
            ? FreshState::FRESH
            : FreshState::CURSOR
        : FreshState::NOTHING;

    sal_Int32 nWrPos = 0;
    sal_Int32 nWrEnd = rEnd;
    sal_uInt16 nCnt = nIndex;
    if( nCnt < Count() )
    {
        nWrPos = Pos( nCnt );
        if( nWrPos < nPos && rStart > nWrPos )
            rStart = nWrPos;
    }

    while( nCnt < Count() )
    {
        nWrPos = Pos( nCnt );
        if ( nWrPos >= nPos )
            break;
        nWrEnd = nWrPos + Len( nCnt++ );
    }

    if( nCnt < Count() && nWrPos == nPos && Len( nCnt ) == nLen )
    {
        ++nCnt;
        eRet = FreshState::FRESH;
    }
    else
    {
        if (FreshState::FRESH == eRet)
        {
            if( rStart > nPos )
                rStart = nPos;
            nWrEnd = nPos + nLen;
        }
    }

    nPos += nLen;

    if( nCnt < Count() )
    {
        nWrPos = Pos( nCnt );
        if( nWrPos < nPos && rStart > nWrPos )
            rStart = nWrPos;
    }

    while( nCnt < Count() )
    {
        nWrPos = Pos( nCnt );
        if ( nWrPos >= nPos )
            break;
        nWrEnd = nWrPos + Len( nCnt++ );
    }

    if( rEnd < nWrEnd )
        rEnd = nWrEnd;

    Remove( nIndex, nCnt - nIndex );

    return eRet;
}

void SwWrongList::Invalidate( sal_Int32 nBegin, sal_Int32 nEnd )
{
    if (COMPLETE_STRING == GetBeginInv())
        SetInvalid( nBegin, nEnd );
    else
        Invalidate_( nBegin, nEnd );
}

bool SwWrongList::InvalidateWrong( )
{
    if( Count() )
    {
        const sal_Int32 nFirst = Pos( 0 );
        const sal_Int32 nLast = Pos( Count() - 1 ) + Len( Count() - 1 );
        Invalidate( nFirst, nLast );
        return true;
    }
    return false;
}

std::unique_ptr<SwWrongList> SwWrongList::SplitList( sal_Int32 nSplitPos )
{
    std::unique_ptr<SwWrongList> pRet;
    sal_uInt16 nLst = 0;
    while( nLst < Count() && Pos( nLst ) < nSplitPos )
        ++nLst;
    if( nLst )
    {
        sal_Int32 nWrPos = Pos( nLst - 1 );
        sal_Int32 nWrLen = Len( nLst - 1 );
        if ( nWrPos+nWrLen > nSplitPos )
        {
            nWrLen += nWrPos - nSplitPos;
            maList[--nLst].mnPos = nSplitPos;
            maList[nLst].mnLen = nWrLen;
        }
    }
    if( nLst )
    {
        if( WRONGLIST_GRAMMAR == GetWrongListType() )
            pRet.reset(new SwGrammarMarkUp());
        else
            pRet.reset(new SwWrongList( GetWrongListType() ));
        pRet->Insert(0, maList.begin(), ( nLst >= maList.size() ? maList.end() : maList.begin() + nLst ) );
        pRet->SetInvalid( GetBeginInv(), GetEndInv() );
        pRet->Invalidate_( nSplitPos ? nSplitPos - 1 : nSplitPos, nSplitPos );
        Remove( 0, nLst );
    }
    if( COMPLETE_STRING == GetBeginInv() )
        SetInvalid( 0, 1 );
    else
    {
        ShiftLeft( mnBeginInvalid, 0, nSplitPos );
        if( mnEndInvalid != COMPLETE_STRING )
            ShiftLeft( mnEndInvalid, 0, nSplitPos );
        Invalidate_( 0, 1 );
    }
    for (nLst = 0; nLst < Count(); ++nLst )
    {
        maList[nLst].mnPos -= nSplitPos;
    }
    return pRet;
}

void SwWrongList::JoinList( SwWrongList* pNext, sal_Int32 nInsertPos )
{
    if (pNext)
    {
        OSL_ENSURE( GetWrongListType() == pNext->GetWrongListType(), "type mismatch with next list" );

        sal_uInt16 nCnt = Count();
        pNext->Move( 0, nInsertPos );
        Insert(nCnt, pNext->maList.begin(), pNext->maList.end());

        Invalidate( pNext->GetBeginInv(), pNext->GetEndInv() );
        if( nCnt && Count() > nCnt )
        {
            sal_Int32 nWrPos = Pos( nCnt );
            sal_Int32 nWrLen = Len( nCnt );
            if( !nWrPos )
            {
                nWrPos += nInsertPos;
                nWrLen -= nInsertPos;
                maList[nCnt].mnPos = nWrPos;
                maList[nCnt].mnLen = nWrLen;
            }
            if( nWrPos == Pos( nCnt - 1 ) + Len( nCnt - 1 ) )
            {
                nWrLen += Len( nCnt - 1 );
                maList[nCnt - 1].mnLen = nWrLen;
                Remove( nCnt, 1 );
            }
        }
    }
    Invalidate( nInsertPos ? nInsertPos - 1 : nInsertPos, nInsertPos + 1 );
}

void SwWrongList::InsertSubList( sal_Int32 nNewPos, sal_Int32 nNewLen, sal_uInt16 nWhere, SwWrongList* pSubList )
{
    if (pSubList)
    {
        OSL_ENSURE( GetWrongListType() == pSubList->GetWrongListType(), "type mismatch with sub list" );
    }
    std::vector<SwWrongArea>::iterator i = maList.begin();
    if ( nWhere >= maList.size() )
        i = maList.end(); // robust
    else
        i += nWhere;
    maList.insert(i, SwWrongArea( OUString(), nullptr, nNewPos, nNewLen, pSubList ) );
}

// New functions: Necessary because SwWrongList has been changed to use std::vector
void SwWrongList::Insert(sal_uInt16 nWhere, std::vector<SwWrongArea>::iterator startPos, std::vector<SwWrongArea>::iterator const & endPos)
{
    std::vector<SwWrongArea>::iterator i = maList.begin();
    if ( nWhere >= maList.size() )
        i = maList.end(); // robust
    else
        i += nWhere;
    maList.insert(i, startPos, endPos); // insert [startPos, endPos[ before i

    // ownership of the sublist is passed to maList, therefore we have to set the
    // pSubList-Pointers to 0
    while ( startPos != endPos )
    {
        (*startPos).mpSubList = nullptr;
        ++startPos;
    }
}

void SwWrongList::Remove(sal_uInt16 nIdx, sal_uInt16 nLen )
{
    if ( nIdx >= maList.size() ) return;
    std::vector<SwWrongArea>::iterator i1 = maList.begin();
    i1 += nIdx;

    std::vector<SwWrongArea>::iterator i2 = i1;
    if ( nIdx + nLen >= o3tl::narrowing<sal_uInt16>(maList.size()) )
        i2 = maList.end(); // robust
    else
        i2 += nLen;

    std::vector<SwWrongArea>::iterator iLoop = i1;
    while ( iLoop != i2 )
    {
        delete (*iLoop).mpSubList;
        ++iLoop;
    }

#if OSL_DEBUG_LEVEL > 0
    const int nOldSize = Count();
#endif

    maList.erase(i1, i2);

#if OSL_DEBUG_LEVEL > 0
    OSL_ENSURE( Count() + nLen == nOldSize, "SwWrongList::Remove() trouble" );
#endif
}

void SwWrongList::RemoveEntry( sal_Int32 nBegin, sal_Int32 nEnd ) {
    std::vector<SwWrongArea>::const_iterator aEnd(maList.end());
    auto aDelIter = std::find_if(maList.cbegin(), aEnd,
        [nBegin](const SwWrongArea& rST) { return rST.mnPos >= nBegin; });
    auto aIter = aDelIter;
    if( WRONGLIST_GRAMMAR == GetWrongListType() )
    {
        if( nBegin < nEnd )
        {
            aIter = std::find_if(aDelIter, aEnd,
                [nEnd](const SwWrongArea& rST) { return rST.mnPos >= nEnd; });
        }
    }
    else
    {
        aIter = std::find_if(aDelIter, aEnd,
            [nBegin, nEnd](const SwWrongArea& rST) {
                return (rST.mnPos != nBegin) || ((rST.mnPos + rST.mnLen) != nEnd);
            });
    }
    auto nDel = o3tl::narrowing<sal_uInt16>(std::distance(aDelIter, aIter));
    if( nDel )
    {
        auto nDelPos = o3tl::narrowing<sal_uInt16>(std::distance(maList.cbegin(), aDelIter));
        Remove( nDelPos, nDel );
    }
}

bool SwWrongList::LookForEntry( sal_Int32 nBegin, sal_Int32 nEnd ) {
    auto aIter = std::find_if(maList.begin(), maList.end(),
        [nBegin](const SwWrongArea& rST) { return rST.mnPos >= nBegin; });
    return aIter != maList.end()
           && nBegin == (*aIter).mnPos
           && nEnd == (*aIter).mnPos + (*aIter).mnLen;
}

void SwWrongList::Insert( const OUString& rType,
                          css::uno::Reference< css::container::XStringKeyMap > const & xPropertyBag,
                          sal_Int32 nNewPos, sal_Int32 nNewLen )
{
    auto aIter = std::find_if(maList.begin(), maList.end(),
        [nNewPos](const SwWrongArea& rST) { return nNewPos <= rST.mnPos; });
    if ( aIter != maList.end() && nNewPos == (*aIter).mnPos )
    {
        const sal_Int32 nSTPos = (*aIter).mnPos;

        aIter = std::find_if(aIter, maList.end(),
            [nSTPos, nNewLen](const SwWrongArea& rST) { return rST.mnPos != nSTPos || nNewLen < rST.mnLen; });
    }

    maList.insert(aIter, SwWrongArea( rType, meType, xPropertyBag, nNewPos, nNewLen) );
}

namespace sw {

WrongListIteratorBase::WrongListIteratorBase(SwTextFrame const& rFrame,
        SwWrongList const* (SwTextNode::*pGetWrongList)() const)
    : m_pGetWrongList(pGetWrongList)
    , m_pMergedPara(rFrame.GetMergedPara())
    , m_CurrentExtent(0)
    , m_CurrentIndex(0)
    , m_pWrongList(m_pMergedPara
                    ? nullptr
                    : (rFrame.GetTextNodeFirst()->*pGetWrongList)())
{
}

WrongListIteratorBase::WrongListIteratorBase(SwWrongList const& rWrongList)
    : m_pGetWrongList(nullptr)
    , m_pMergedPara(nullptr)
    , m_CurrentExtent(0)
    , m_CurrentIndex(0)
    , m_pWrongList(&rWrongList)
{
}

WrongListIterator::WrongListIterator(SwTextFrame const& rFrame,
        SwWrongList const* (SwTextNode::*pGetWrongList)() const)
    : WrongListIteratorBase(rFrame, pGetWrongList)
{
}

WrongListIterator::WrongListIterator(SwWrongList const& rWrongList)
    : WrongListIteratorBase(rWrongList)
{
}

bool WrongListIterator::Check(TextFrameIndex & rStart, TextFrameIndex & rLen)
{
    if (m_pMergedPara)
    {
        if (rStart < m_CurrentIndex)
        {   // rewind
            m_CurrentExtent = 0;
            m_CurrentIndex = TextFrameIndex(0);
        }
        while (m_CurrentExtent < m_pMergedPara->extents.size())
        {
            sw::Extent const& rExtent(m_pMergedPara->extents[m_CurrentExtent]);
            if (rStart + rLen <= m_CurrentIndex)
            {
                return false;
            }
            else if (rStart < m_CurrentIndex)
            {
                rLen -= m_CurrentIndex - rStart;
                assert(0 < sal_Int32(rLen));
                rStart = m_CurrentIndex;
            }
            if (m_CurrentIndex <= rStart &&
                rStart < m_CurrentIndex + TextFrameIndex(rExtent.nEnd - rExtent.nStart))
            {
                SwWrongList const*const pWrongList((rExtent.pNode->*m_pGetWrongList)());
                // found the extent containing start - first, call Check
                sal_Int32 nStart(rExtent.nStart + sal_Int32(rStart - m_CurrentIndex)); // (m_CurrentIndex - m_CurrentNodeIndex));
                sal_Int32 nLen;
                if (sal_Int32(rLen) < rExtent.nEnd - nStart)
                {
                    nLen = sal_Int32(rLen);
                }
                else
                {
                    sal_Int32 nInLen(rLen);
                    nLen = rExtent.nEnd - nStart;
                    nInLen -= nLen;
                    for (size_t i = m_CurrentExtent + 1;
                         i < m_pMergedPara->extents.size(); ++i)
                    {
                        sw::Extent const& rExtentEnd(m_pMergedPara->extents[i]);
                        if (rExtentEnd.pNode != rExtent.pNode)
                        {
                            break;
                        }
                        // add gap too
                        nLen += rExtentEnd.nStart - m_pMergedPara->extents[i-1].nEnd;
                        if (nInLen <= rExtentEnd.nEnd - rExtentEnd.nStart)
                        {
                            nLen += nInLen;
                            break;
                        }
                        nLen += rExtentEnd.nEnd - rExtentEnd.nStart;
                        nInLen -= rExtentEnd.nEnd - rExtentEnd.nStart;
                    }
                }
                if (pWrongList && pWrongList->Check(nStart, nLen))
                {
                    // check if there's overlap with this extent
                    if (rExtent.nStart <= nStart && nStart < rExtent.nEnd)
                    {
                        // yes - now compute end position / length
                        sal_Int32 const nEnd(nStart + nLen);
                        rStart = m_CurrentIndex + TextFrameIndex(nStart - rExtent.nStart);
                        TextFrameIndex const nOrigLen(rLen);
                        if (nEnd <= rExtent.nEnd)
                        {
                            rLen = TextFrameIndex(nEnd - nStart);
                        }
                        else // have to search other extents for the end...
                        {
                            rLen = TextFrameIndex(rExtent.nEnd - nStart);
                            for (size_t i = m_CurrentExtent + 1;
                                 i < m_pMergedPara->extents.size(); ++i)
                            {
                                sw::Extent const& rExtentEnd(m_pMergedPara->extents[i]);
                                if (rExtentEnd.pNode != rExtent.pNode
                                    || nEnd <= rExtentEnd.nStart)
                                {
                                    break;
                                }
                                if (nEnd <= rExtentEnd.nEnd)
                                {
                                    rLen += TextFrameIndex(nEnd - rExtentEnd.nStart);
                                    break;
                                }
                                rLen += TextFrameIndex(rExtentEnd.nEnd - rExtentEnd.nStart);
                            }
                        }
                        assert(rLen <= nOrigLen); (void) nOrigLen;
                        return true;
                    }
                }
            }
            m_CurrentIndex += TextFrameIndex(rExtent.nEnd - rExtent.nStart);
            ++m_CurrentExtent;
        }
        return false;
    }
    else if (m_pWrongList)
    {
        sal_Int32 nStart(rStart);
        sal_Int32 nLen(rLen);
        bool const bRet(m_pWrongList->Check(nStart, nLen));
        rStart = TextFrameIndex(nStart);
        rLen = TextFrameIndex(nLen);
        return bRet;
    }
    return false;
}

const SwWrongArea*
WrongListIterator::GetWrongElement(TextFrameIndex const nStart)
{
    if (m_pMergedPara)
    {
        if (nStart < m_CurrentIndex)
        {   // rewind
            m_CurrentExtent = 0;
            m_CurrentIndex = TextFrameIndex(0);
        }
        while (m_CurrentExtent < m_pMergedPara->extents.size())
        {
            sw::Extent const& rExtent(m_pMergedPara->extents[m_CurrentExtent]);
            if (m_CurrentIndex <= nStart &&
                nStart <= m_CurrentIndex + TextFrameIndex(rExtent.nEnd - rExtent.nStart))
            {
                // note: the returned object isn't wrapped because fntcache.cxx
                // does not look at its positions, only its formatting props
                SwWrongList const*const pWrongList((rExtent.pNode->*m_pGetWrongList)());
                if (pWrongList)
                {
                    sal_Int32 const nNStart(rExtent.nStart + sal_Int32(nStart - m_CurrentIndex)); // (m_CurrentIndex - m_CurrentNodeIndex));
                    sal_Int16 const nPos(pWrongList->GetWrongPos(nNStart));
                    return pWrongList->GetElement(nPos);
                }
            }
            m_CurrentIndex += TextFrameIndex(rExtent.nEnd - rExtent.nStart);
            ++m_CurrentExtent;
        }
        return nullptr;
    }
    else if (m_pWrongList)
    {
        sal_Int16 const nPos(m_pWrongList->GetWrongPos(sal_Int32(nStart)));
        return m_pWrongList->GetElement(nPos);
    }
    return nullptr;
}

WrongListIteratorCounter::WrongListIteratorCounter(SwTextFrame const& rFrame,
        SwWrongList const* (SwTextNode::*pGetWrongList)() const)
    : WrongListIteratorBase(rFrame, pGetWrongList)
{
}

WrongListIteratorCounter::WrongListIteratorCounter(SwWrongList const& rWrongList)
    : WrongListIteratorBase(rWrongList)
{
}

sal_uInt16 WrongListIteratorCounter::GetElementCount()
{
    if (m_pMergedPara)
    {
        sal_uInt16 nRet(0);
        m_CurrentExtent = 0;
        m_CurrentIndex = TextFrameIndex(0);
        SwNode const* pNode(nullptr);
        sal_uInt16 InCurrentNode(0);
        while (m_CurrentExtent < m_pMergedPara->extents.size())
        {
            sw::Extent const& rExtent(m_pMergedPara->extents[m_CurrentExtent]);
            if (rExtent.pNode != pNode)
            {
                InCurrentNode = 0;
                pNode = rExtent.pNode;
            }
            assert(rExtent.pNode);
            SwWrongList const*const pWrongList((rExtent.pNode->*m_pGetWrongList)());
            for (; pWrongList && InCurrentNode < pWrongList->Count(); ++InCurrentNode)
            {
                SwWrongArea const*const pWrong(pWrongList->GetElement(InCurrentNode));
                TextFrameIndex const nExtentEnd(
                    m_CurrentIndex + TextFrameIndex(rExtent.nEnd - rExtent.nStart));
                if (nExtentEnd <= TextFrameIndex(pWrong->mnPos))
                {
                    break// continue outer loop
                }
                if (m_CurrentIndex < TextFrameIndex(pWrong->mnPos + pWrong->mnLen))
                {
                    ++nRet;
                }
            }
            m_CurrentIndex += TextFrameIndex(rExtent.nEnd - rExtent.nStart);
            ++m_CurrentExtent;
        }
        return nRet;
    }
    else if (m_pWrongList)
    {
        return m_pWrongList->Count();
    }
    return 0;
}

std::optional<std::pair<TextFrameIndex, TextFrameIndex>>
WrongListIteratorCounter::GetElementAt(sal_uInt16 nIndex)
{
    if (m_pMergedPara)
    {
        m_CurrentExtent = 0;
        m_CurrentIndex = TextFrameIndex(0);
        SwNode const* pNode(nullptr);
        sal_uInt16 InCurrentNode(0);
        while (m_CurrentExtent < m_pMergedPara->extents.size())
        {
            sw::Extent const& rExtent(m_pMergedPara->extents[m_CurrentExtent]);
            if (rExtent.pNode != pNode)
            {
                InCurrentNode = 0;
                pNode = rExtent.pNode;
            }
            assert(rExtent.pNode);
            SwWrongList const*const pWrongList((rExtent.pNode->*m_pGetWrongList)());
            for (; pWrongList && InCurrentNode < pWrongList->Count(); ++InCurrentNode)
            {
                SwWrongArea const*const pWrong(pWrongList->GetElement(InCurrentNode));
                TextFrameIndex const nExtentEnd(
                    m_CurrentIndex + TextFrameIndex(rExtent.nEnd - rExtent.nStart));
                if (nExtentEnd <= TextFrameIndex(pWrong->mnPos))
                {
                    break// continue outer loop
                }
                if (m_CurrentIndex < TextFrameIndex(pWrong->mnPos + pWrong->mnLen))
                {
                    if (nIndex == 0)
                    {
                        return std::optional<std::pair<TextFrameIndex, TextFrameIndex>>(
                            std::pair<TextFrameIndex, TextFrameIndex>(
                                m_CurrentIndex - TextFrameIndex(rExtent.nStart -
                                    std::max(rExtent.nStart, pWrong->mnPos)),
                                m_CurrentIndex - TextFrameIndex(rExtent.nStart -
                                    std::min(pWrong->mnPos + pWrong->mnLen, rExtent.nEnd))));
                    }
                    --nIndex;
                }
            }
            m_CurrentIndex += TextFrameIndex(rExtent.nEnd - rExtent.nStart);
            ++m_CurrentExtent;
        }
        return std::optional<std::pair<TextFrameIndex, TextFrameIndex>>();
    }
    else if (m_pWrongList)
    {
        SwWrongArea const*const pWrong(m_pWrongList->GetElement(nIndex));
        return std::optional<std::pair<TextFrameIndex, TextFrameIndex>>(
            std::pair<TextFrameIndex, TextFrameIndex>(
                    TextFrameIndex(pWrong->mnPos),
                    TextFrameIndex(pWrong->mnPos + pWrong->mnLen)));
    }
    return std::optional<std::pair<TextFrameIndex, TextFrameIndex>>();
}

// namespace sw

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=96 H=88 G=91

¤ Dauer der Verarbeitung: 0.45 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.