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

Quelle  findfrm.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 <pagefrm.hxx>
#include <colfrm.hxx>
#include <rootfrm.hxx>
#include <cellfrm.hxx>
#include <rowfrm.hxx>
#include <swtable.hxx>
#include <notxtfrm.hxx>
#include <tabfrm.hxx>
#include <sectfrm.hxx>
#include <frmatr.hxx>
#include <flyfrm.hxx>
#include <ftnfrm.hxx>
#include <txtftn.hxx>
#include <fmtftn.hxx>
#include <fmtpdsc.hxx>
#include <fmtclbl.hxx>
#include <txtfrm.hxx>
#include <bodyfrm.hxx>
#include <calbck.hxx>
#include <viewopt.hxx>
#include <ndtxt.hxx>
#include <osl/diagnose.h>
#include <sal/log.hxx>
#include <IDocumentSettingAccess.hxx>
#include <formatflysplit.hxx>
#include <flyfrms.hxx>


/// Searches the first ContentFrame in BodyText below the page.
SwLayoutFrame *SwFootnoteBossFrame::FindBodyCont()
{
    SwFrame *pLay = Lower();
    while ( pLay && !pLay->IsBodyFrame() )
        pLay = pLay->GetNext();
    return static_cast<SwLayoutFrame*>(pLay);
}

/// Searches the last ContentFrame in BodyText below the page.
SwContentFrame *SwPageFrame::FindLastBodyContent()
{
    SwContentFrame *pRet = FindFirstBodyContent();
    SwContentFrame *pNxt = pRet;
    while ( pNxt && pNxt->IsInDocBody() && IsAnLower( pNxt ) )
    {   pRet = pNxt;
        pNxt = pNxt->FindNextCnt();
    }
    return pRet;
}

SwSectionFrame* SwPageFrame::GetEndNoteSection()
{
    SwLayoutFrame* pBody = FindBodyCont();
    if (!pBody)
    {
        return nullptr;
    }

    SwFrame* pLast = pBody->GetLastLower();
    if (!pLast || !pLast->IsSctFrame())
    {
        return nullptr;
    }

    auto pLastSection = static_cast<SwSectionFrame*>(pLast);
    if (!pLastSection->IsEndNoteSection())
    {
        return nullptr;
    }

    return pLastSection;
}

/**
 * Checks if the frame contains one or more ContentFrame's anywhere in his
 * subsidiary structure; if so the first found ContentFrame is returned.
 */

const SwContentFrame *SwLayoutFrame::ContainsContent() const
{
    //Search downwards the layout leaf and if there is no content, jump to the
    //next leaf until content is found or we leave "this".
    //Sections: Content next to sections would not be found this way (empty
    //sections directly next to ContentFrame) therefore we need to recursively
    //search for them even if it's more complex.

    const SwLayoutFrame *pLayLeaf = this;
    do
    {
        const SwFrame* pLower = pLayLeaf->Lower();
        while ( (!pLayLeaf->IsSctFrame() || pLayLeaf == this ) &&
                pLower && pLower->IsLayoutFrame() )
        {
            pLayLeaf = static_cast<const SwLayoutFrame*>(pLower);
            pLower = pLayLeaf->Lower();
        }

        if( pLayLeaf->IsSctFrame() && pLayLeaf != this )
        {
            const SwContentFrame *pCnt = pLayLeaf->ContainsContent();
            if( pCnt )
                return pCnt;
            if( pLayLeaf->GetNext() )
            {
                if( pLayLeaf->GetNext()->IsLayoutFrame() )
                {
                    pLayLeaf = static_cast<const SwLayoutFrame*>(pLayLeaf->GetNext());
                    continue;
                }
                else
                    return static_cast<const SwContentFrame*>(pLayLeaf->GetNext());
            }
        }
        else if ( pLower )
            return static_cast<const SwContentFrame*>(pLower);

        pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
        if( !IsAnLower( pLayLeaf) )
            return nullptr;
    } while( pLayLeaf );
    return nullptr;
}

/**
 * Calls ContainsAny first to reach the innermost cell. From there we walk back
 * up to the first SwCellFrame. Since we use SectionFrames, ContainsContent()->GetUpper()
 * is not enough anymore.
 */

const SwCellFrame *SwLayoutFrame::FirstCell() const
{
    const SwFrame* pCnt = ContainsAny();
    while( pCnt && !pCnt->IsCellFrame() )
        pCnt = pCnt->GetUpper();
    return static_cast<const SwCellFrame*>(pCnt);
}

/** return ContentFrames, sections, and tables.
 *
 * @param _bInvestigateFootnoteForSections controls investigation of content of footnotes for sections.
 * @see ContainsContent
 */

const SwFrame *SwLayoutFrame::ContainsAny( const bool _bInvestigateFootnoteForSections ) const
{
    //Search downwards the layout leaf and if there is no content, jump to the
    //next leaf until content is found, we leave "this" or until we found
    //a SectionFrame or a TabFrame.

    const SwLayoutFrame *pLayLeaf = this;
    const bool bNoFootnote = IsSctFrame() && !_bInvestigateFootnoteForSections;
    do
    {
        const SwFrame* pLower = pLayLeaf->Lower();
        while ( ( (!pLayLeaf->IsSctFrame() && !pLayLeaf->IsTabFrame())
                 || pLayLeaf == this ) &&
                pLower && pLower->IsLayoutFrame() )
        {
            pLayLeaf = static_cast<const SwLayoutFrame*>(pLower);
            pLower = pLayLeaf->Lower();
        }

        if( ( pLayLeaf->IsTabFrame() || pLayLeaf->IsSctFrame() )
            && pLayLeaf != this )
        {
            // Now we also return "deleted" SectionFrames so they can be
            // maintained on SaveContent and RestoreContent
            return pLayLeaf;
        }
        else if ( pLower )
            return static_cast<const SwContentFrame*>(pLower);

        pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
        if( bNoFootnote && pLayLeaf && pLayLeaf->IsInFootnote() )
        {
            do
            {
                pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
            } while( pLayLeaf && pLayLeaf->IsInFootnote() );
        }
        if( !IsAnLower( pLayLeaf) )
            return nullptr;
    } while( pLayLeaf );
    return nullptr;
}

bool SwLayoutFrame::ContainsDeleteForbiddenLayFrame() const
{
    if (IsDeleteForbidden())
    {
        return true;
    }
    for (SwFrame const* pFrame = Lower(); pFrame; pFrame = pFrame->GetNext())
    {
        if (!pFrame->IsLayoutFrame())
        {
            continue;
        }
        SwLayoutFrame const*const pLay(static_cast<SwLayoutFrame const*>(pFrame));
        if (pLay->ContainsDeleteForbiddenLayFrame() || pLay->IsColLocked())
        {
            return true;
        }
    }
    return false;
}

const SwFrame* SwFrame::GetLower() const
{
    return IsLayoutFrame() ? static_cast<const SwLayoutFrame*>(this)->Lower() : nullptr;
}

SwFrame* SwFrame::GetLower()
{
    return IsLayoutFrame() ? static_cast<SwLayoutFrame*>(this)->Lower() : nullptr;
}

SwContentFrame* SwFrame::FindPrevCnt( )
{
    if ( GetPrev() && GetPrev()->IsContentFrame() )
        return static_cast<SwContentFrame*>(GetPrev());
    else
        return FindPrevCnt_();
}

const SwContentFrame* SwFrame::FindPrevCnt() const
{
    if ( GetPrev() && GetPrev()->IsContentFrame() )
        return static_cast<const SwContentFrame*>(GetPrev());
    else
        return const_cast<SwFrame*>(this)->FindPrevCnt_();
}

SwContentFrame *SwFrame::FindNextCnt( const bool _bInSameFootnote )
{
    if ( mpNext && mpNext->IsContentFrame() )
        return static_cast<SwContentFrame*>(mpNext);
    else
        return FindNextCnt_( _bInSameFootnote );
}

const SwContentFrame *SwFrame::FindNextCnt( const bool _bInSameFootnote ) const
{
    if ( mpNext && mpNext->IsContentFrame() )
        return static_cast<SwContentFrame*>(mpNext);
    else
        return const_cast<SwFrame*>(this)->FindNextCnt_( _bInSameFootnote );
}

bool SwLayoutFrame::IsAnLower( const SwFrame *pAssumed ) const
{
    const SwFrame *pUp = pAssumed;
    while ( pUp )
    {
        if (!pUp->IsInDtor())
        {
            if (pUp == this)
                return true;
            if (pUp->IsFlyFrame())
                pUp = static_cast<const SwFlyFrame*>(pUp)->GetAnchorFrame();
            else
                pUp = pUp->GetUpper();
        }
        else
            break;
    }
    return false;
}

/** method to check relative position of layout frame to
    a given layout frame.

    OD 08.11.2002 - refactoring of pseudo-local method <lcl_Apres(..)> in
    <txtftn.cxx> for #104840#.

    @param _aCheckRefLayFrame
    constant reference of an instance of class <SwLayoutFrame> which
    is used as the reference for the relative position check.

    @return true, if <this> is positioned before the layout frame <p>
*/

bool SwLayoutFrame::IsBefore( const SwLayoutFrame* _pCheckRefLayFrame ) const
{
    OSL_ENSURE( !IsRootFrame() , " called at a .");
    OSL_ENSURE( !_pCheckRefLayFrame->IsRootFrame() , " called with a .");

    bool bReturn;

    // check, if on different pages
    const SwPageFrame *pMyPage = FindPageFrame();
    const SwPageFrame *pCheckRefPage = _pCheckRefLayFrame->FindPageFrame();
    if( pMyPage != pCheckRefPage )
    {
        // being on different page as check reference
        bReturn = pMyPage->GetPhyPageNum() < pCheckRefPage->GetPhyPageNum();
    }
    else
    {
        // being on same page as check reference
        // --> search my supreme parent <pUp>, which doesn't contain check reference.
        const SwLayoutFrame* pUp = this;
        while ( pUp->GetUpper() &&
                !pUp->GetUpper()->IsAnLower( _pCheckRefLayFrame )
              )
            pUp = pUp->GetUpper();
        if( !pUp->GetUpper() )
        {
            // can occur, if <this> is a fly frm
            bReturn = false;
        }
        else
        {
            // travel through the next's of <pUp> and check if one of these
            // contain the check reference.
            const SwLayoutFrame* pUpNext = static_cast<const SwLayoutFrame*>(pUp->GetNext());
            while ( pUpNext &&
                    !pUpNext->IsAnLower( _pCheckRefLayFrame ) )
            {
                pUpNext = static_cast<const SwLayoutFrame*>(pUpNext->GetNext());
            }
            bReturn = pUpNext != nullptr;
        }
    }

    return bReturn;
}

// Local helper functions for GetNextLayoutLeaf

static const SwFrame* lcl_FindLayoutFrame( const SwFrame* pFrame, bool bNext )
{
    const SwFrame* pRet = nullptr;
    if ( pFrame->IsFlyFrame() )
    {
        auto pFlyFrame = static_cast<const SwFlyFrame*>(pFrame);
        if (pFlyFrame->IsFlySplitAllowed())
        {
            // This is a flow frame, look up the follow/precede.
            auto pFlyAtContent = static_cast<const SwFlyAtContentFrame*>(pFlyFrame);
            pRet = bNext ? pFlyAtContent->GetFollow() : pFlyAtContent->GetPrecede();
        }
        else
        {
            pRet = bNext ? pFlyFrame->GetNextLink() : pFlyFrame->GetPrevLink();
        }
    }
    else
        pRet = bNext ? pFrame->GetNext() : pFrame->GetPrev();

    return pRet;
}

static const SwFrame* lcl_GetLower( const SwFrame* pFrame, bool bFwd )
{
    if ( !pFrame->IsLayoutFrame() )
        return nullptr;

    return bFwd ?
           static_cast<const SwLayoutFrame*>(pFrame)->Lower() :
           static_cast<const SwLayoutFrame*>(pFrame)->GetLastLower();
}

/**
 * Finds the next layout leaf. This is a layout frame, which does not
 * have a lower which is a LayoutFrame. That means, pLower can be 0 or a
 * content frame.
 *
 * However, pLower may be a TabFrame
 */

const SwLayoutFrame *SwFrame::ImplGetNextLayoutLeaf( bool bFwd ) const
{
    const SwFrame       *pFrame = this;
    const SwLayoutFrame *pLayoutFrame = nullptr;
    const SwFrame       *p = nullptr;
    bool bGoingUp = !bFwd;          // false for forward, true for backward
    // The anchor is this frame, unless we traverse the anchor of a split fly.
    const SwFrame* pAnchor = this;
    do {

         bool bGoingFwdOrBwd = false;

         bool bGoingDown = !bGoingUp;
         if (bGoingDown)
         {
            p = lcl_GetLower( pFrame, bFwd );
            bGoingDown = nullptr != p;
         }
         if ( !bGoingDown )
         {
             // I cannot go down, because either I'm currently going up or
             // because the is no lower.
             // I'll try to go forward:
             p = lcl_FindLayoutFrame( pFrame, bFwd );
             bGoingFwdOrBwd = nullptr != p;
             if ( !bGoingFwdOrBwd )
             {
                 // I cannot go forward, because there is no next frame.
                 // I'll try to go up:
                 p = pFrame->GetUpper();

                 if (!p && pFrame->IsFlyFrame())
                 {
                     const SwFlyFrame* pFlyFrame = pFrame->FindFlyFrame();
                     if (pFlyFrame->IsFlySplitAllowed())
                     {
                         p = const_cast<SwFlyFrame*>(pFlyFrame)->FindAnchorCharFrame();
                         // Remember the anchor frame, so if we look for the leaf of a frame in a
                         // split fly (anchored in the master of a text frame, but rendered on the
                         // next page), we won't return a frame on the next page, rather return
                         // nullptr.
                         pAnchor = p;
                     }
                 }

                 bGoingUp = nullptr != p;
                 if ( !bGoingUp )
                 {
                    // I cannot go up, because there is no upper frame.
                    return nullptr;
                 }
             }
         }

         // If I could not go down or forward, I'll have to go up
         bGoingUp = !bGoingFwdOrBwd && !bGoingDown;

         pFrame = p;
         p = lcl_GetLower( pFrame, true );

    } while( ( p && !p->IsFlowFrame() ) ||
             pFrame == this ||
             nullptr == ( pLayoutFrame = pFrame->IsLayoutFrame() ? static_cast<const SwLayoutFrame*>(pFrame) : nullptr ) ||
             pLayoutFrame->IsAnLower( pAnchor ) );

    return pLayoutFrame;
}

/**
 * Walk back inside the tree: grab the subordinate Frame if one exists and the
 * last step was not moving up a level (this would lead to an infinite up/down
 * loop!). With this we ensure that during walking back we search through all
 * sub trees. If we walked downwards we have to go to the end of the chain first
 * because we go backwards from the last Frame inside another Frame. Walking
 * forward works the same.
 *
 * @warning fixes here may also need to be applied to the @{lcl_NextFrame} method above
 */

const SwContentFrame* SwContentFrame::ImplGetNextContentFrame( bool bFwd ) const
{
    const SwFrame *pFrame = this;
    const SwContentFrame *pContentFrame = nullptr;
    bool bGoingUp = false;
    do {
        const SwFrame *p = nullptr;
        bool bGoingFwdOrBwd = false;

        bool bGoingDown = !bGoingUp;
        if (bGoingDown)
        {
            p = lcl_GetLower( pFrame, true ) ;
            bGoingDown = nullptr != p;
        }
        if ( !bGoingDown )
        {
            p = lcl_FindLayoutFrame( pFrame, bFwd );
            bGoingFwdOrBwd = nullptr != p;
            if ( !bGoingFwdOrBwd )
            {
                p = pFrame->GetUpper();
                bGoingUp = nullptr != p;
                if ( !bGoingUp )
                {
                    return nullptr;
                }
            }
        }

        bGoingUp = !(bGoingFwdOrBwd || bGoingDown);
        assert(p);
        if (!bFwd && bGoingDown)
        {
                while ( p->GetNext() )
                    p = p->GetNext();
        }

        pFrame = p;
    } while ( nullptr == (pContentFrame = (pFrame->IsContentFrame() ? static_cast<const SwContentFrame*>(pFrame) : nullptr) ));

    return pContentFrame;
}

SwPageFrame* SwFrame::ImplFindPageFrame()
{
    SwFrame *pRet = this;
    while ( pRet )
    {
        if (pRet->IsInDtor())
            return nullptr;

        if (pRet->IsPageFrame())
            break;

        if ( pRet->GetUpper() )
            pRet = pRet->GetUpper();
        else if ( pRet->IsFlyFrame() )
        {
            // #i28701# - use new method <GetPageFrame()>
            const auto pFly(static_cast<SwFlyFrame*>(pRet));
            pRet = pFly->GetPageFrame();
            if (pRet == nullptr)
                pRet = pFly->AnchorFrame();
        }
        else
            return nullptr;
    }
    return static_cast<SwPageFrame*>(pRet);
}

SwFootnoteBossFrame* SwFrame::FindFootnoteBossFrame( bool bFootnotes )
{
    SwFrame *pRet = this;
    // Footnote bosses can't exist inside a table; also sections with columns
    // don't contain footnote texts there
    if (SwFrame *pTabFrame = pRet->IsInTab() ? pRet->FindTabFrame() : nullptr)
        pRet = pTabFrame;

    // tdf139336: put the footnotes into the page frame (instead of a column frame)
    // to avoid maximizing the section to the full page.... if:
    // - it is in a section
    // - collect footnotes at section end (FootnoteAtEnd) is not set
    // - columns are evenly distributed (=balanced) is not set
    // Note 1: at page end, the footnotes have no multi-column-capability,
    //         so this fix is used only where there is better chance to help
    // Note 2: If balanced is not set, there is a higher chance that the 1. column will reach
    //         the end of the page... if that happens the section will be maximized anyway.
    // Note 3: The user will be able to easily choose the old layout (with multi-column footnotes)
    //         with this setting.
    //         similar case can be reached with a page break + FootnoteAtEnd setting
    SwSectionFrame* pSectframe = pRet->FindSctFrame();
    bool bMoveToPageFrame = false;
    // tdf146704: only if it is really a footnote, not an endnote.
    // tdf54465: compatibility flag to make old odt files keep these full page sections.
    if (bFootnotes && pSectframe
        && pSectframe->GetFormat()->getIDocumentSettingAccess().get(
            DocumentSettingId::FOOTNOTE_IN_COLUMN_TO_PAGEEND))
    {
        SwSection* pSect = pSectframe->GetSection();
        if (pSect) {
            bool bNoBalance = pSect->GetFormat()->GetBalancedColumns().GetValue();
            bool bFAtEnd = pSectframe->IsFootnoteAtEnd();
            bMoveToPageFrame = !bFAtEnd && !bNoBalance;
        }
    }
    while (pRet && !pRet->IsInDtor()
           && ((!bMoveToPageFrame && !pRet->IsFootnoteBossFrame())
               || (bMoveToPageFrame && !pRet->IsPageFrame())))
    {
        if ( pRet->GetUpper() )
            pRet = pRet->GetUpper();
        else if ( pRet->IsFlyFrame() )
        {
            // #i28701# - use new method <GetPageFrame()>
            if ( static_cast<SwFlyFrame*>(pRet)->GetPageFrame() )
                pRet = static_cast<SwFlyFrame*>(pRet)->GetPageFrame();
            else
                pRet = static_cast<SwFlyFrame*>(pRet)->AnchorFrame();
        }
        else
            return nullptr;
    }
    if( bFootnotes && pRet && pRet->IsColumnFrame() &&
        !pRet->GetNext() && !pRet->GetPrev() )
    {
        SwSectionFrame* pSct = pRet->FindSctFrame();
        assert(pSct && "FindFootnoteBossFrame: Single column outside section?");
        if( !pSct->IsFootnoteAtEnd() )
            return pSct->FindFootnoteBossFrame( true );
    }
    return static_cast<SwFootnoteBossFrame*>(pRet);
}

SwTabFrame* SwFrame::ImplFindTabFrame()
{
    SwFrame *pRet = this;
    if (pRet->IsInDtor())
        return nullptr;
    while ( !pRet->IsTabFrame() )
    {
        pRet = pRet->GetUpper();
        if ( !pRet )
            return nullptr;
        if (pRet->IsInDtor())
            return nullptr;
    }
    return static_cast<SwTabFrame*>(pRet);
}

SwSectionFrame* SwFrame::ImplFindSctFrame()
{
    SwFrame *pRet = this;
    if (pRet->IsInDtor())
        return nullptr;
    while ( !pRet->IsSctFrame() )
    {
        pRet = pRet->GetUpper();
        if ( !pRet )
            return nullptr;
        if (pRet->IsInDtor())
            return nullptr;
    }
    return static_cast<SwSectionFrame*>(pRet);
}

const SwBodyFrame* SwFrame::ImplFindBodyFrame() const
{
    const SwFrame *pRet = this;
    while ( !pRet->IsBodyFrame() )
    {
        pRet = pRet->GetUpper();
        if ( !pRet )
            return nullptr;
    }
    return static_cast<const SwBodyFrame*>(pRet);
}

SwFootnoteFrame *SwFrame::ImplFindFootnoteFrame()
{
    SwFrame *pRet = this;
    while ( !pRet->IsFootnoteFrame() )
    {
        pRet = pRet->GetUpper();
        if ( !pRet )
            return nullptr;
    }
    return static_cast<SwFootnoteFrame*>(pRet);
}

SwFlyFrame *SwFrame::ImplFindFlyFrame()
{
    SwFrame *pRet = this;
    do
    {
        if ( pRet->IsFlyFrame() )
            return static_cast<SwFlyFrame*>(pRet);
        else
            pRet = pRet->GetUpper();
    } while ( pRet );
    return nullptr;
}

SwFrame *SwFrame::FindColFrame()
{
    SwFrame *pFrame = this;
    do
    {   pFrame = pFrame->GetUpper();
    } while ( pFrame && !pFrame->IsColumnFrame() );
    return pFrame;
}

SwRowFrame *SwFrame::FindRowFrame()
{
    SwFrame *pFrame = this;
    do
    {   pFrame = pFrame->GetUpper();
    } while ( pFrame && !pFrame->IsRowFrame() );
    return dynamic_cast< SwRowFrame* >( pFrame );
}

SwFrame* SwFrame::FindFooterOrHeader()
{
    SwFrame* pRet = this;
    do
    {
        if (pRet->GetType() & FRM_HEADFOOT) //header and footer
            return pRet;
        else if ( pRet->GetUpper() )
            pRet = pRet->GetUpper();
        else if ( pRet->IsFlyFrame() )
            pRet = static_cast<SwFlyFrame*>(pRet)->AnchorFrame();
        else
            return nullptr;
    } while ( pRet );
    return pRet;
}

const SwFootnoteFrame* SwFootnoteContFrame::FindFootNote() const
{
    const SwFootnoteFrame* pRet = static_cast<const SwFootnoteFrame*>(Lower());
    if( pRet && !pRet->GetAttr()->GetFootnote().IsEndNote() )
        return pRet;
    return nullptr;
}

const SwFootnoteFrame* SwFootnoteContFrame::FindEndNote() const
{
    auto pRet = static_cast<const SwFootnoteFrame*>(Lower());
    if (pRet && pRet->GetAttr()->GetFootnote().IsEndNote())
    {
        return pRet;
    }

    return nullptr;
}

const SwPageFrame* SwRootFrame::GetPageAtPos( const Point& rPt, const Size* pSize, bool bExtend ) const
{
    const SwPageFrame* pRet = nullptr;

    SwRect aRect;
    if ( pSize )
    {
        aRect.Pos()  = rPt;
        aRect.SSize( *pSize );
    }

    const SwFrame* pPage = Lower();

    if ( !bExtend )
    {
        if( !getFrameArea().Contains( rPt ) )
            return nullptr;

        // skip pages above point:
        while( pPage && rPt.Y() > pPage->getFrameArea().Bottom() )
            pPage = pPage->GetNext();
    }

    OSL_ENSURE( GetPageNum() <= maPageRects.size(), "number of pages differs from page rect array size" );
    size_t nPageIdx = 0;

    while ( pPage && !pRet )
    {
        const SwRect& rBoundRect = bExtend ? maPageRects[ nPageIdx++ ] : pPage->getFrameArea();

        if ( (!pSize && rBoundRect.Contains(rPt)) ||
              (pSize && rBoundRect.Overlaps(aRect)) )
        {
            pRet = static_cast<const SwPageFrame*>(pPage);
        }

        pPage = pPage->GetNext();
    }

    return pRet;
}

bool SwRootFrame::IsBetweenPages(const Point& rPt) const
{
    if (!getFrameArea().Contains(rPt))
        return false;

    // top visible page
    const SwFrame* pPage = Lower();
    if (pPage == nullptr)
        return false;

    // skip pages above point:
    while (pPage && rPt.Y() > pPage->getFrameArea().Bottom())
        pPage = pPage->GetNext();

    if (pPage &&
        rPt.X() >= pPage->getFrameArea().Left() &&
        rPt.X() <= pPage->getFrameArea().Right())
    {
        // Trivial case when we're right in between.
        if (!pPage->getFrameArea().Contains(rPt))
            return true;

        // In normal mode the gap is large enough and
        // header/footer mouse interaction competes with
        // handling hide-whitespace within them.
        // In hide-whitespace, however, the gap is too small
        // for convenience and there are no headers/footers.
        const SwViewShell *pSh = GetCurrShell();
        if (pSh && pSh->GetViewOptions()->IsWhitespaceHidden())
        {
            constexpr SwTwips constMargin = o3tl::convert(tools::Long(2), o3tl::Length::mm, o3tl::Length::twip);

            // If we are really close to the bottom or top of a page.
            const auto toEdge = std::min(std::abs(pPage->getFrameArea().Top() - rPt.Y()),
                                         std::abs(pPage->getFrameArea().Bottom() - rPt.Y()));
            return toEdge <= constMargin;
        }
    }

    return false;
}

const SvxFormatBreakItem& SwFrame::GetBreakItem() const
{
    return GetAttrSet()->GetBreak();
}

const SwFormatPageDesc& SwFrame::GetPageDescItem() const
{
    return GetAttrSet()->GetPageDesc();
}

const SvxFormatBreakItem& SwTextFrame::GetBreakItem() const
{
    return GetTextNodeFirst()->GetSwAttrSet().GetBreak();
}

const SwFormatPageDesc& SwTextFrame::GetPageDescItem() const
{
    return GetTextNodeFirst()->GetSwAttrSet().GetPageDesc();
}

const SwAttrSet* SwFrame::GetAttrSet() const
{
    if (IsTextFrame())
    {
        return &static_cast<const SwTextFrame*>(this)->GetTextNodeForParaProps()->GetSwAttrSet();
    }
    else if (IsNoTextFrame())
    {
        return &static_cast<const SwNoTextFrame*>(this)->GetNode()->GetSwAttrSet();
    }
    else
    {
        assert(IsLayoutFrame());
        return &static_cast<const SwLayoutFrame*>(this)->GetFormat()->GetAttrSet();
    }
}

drawinglayer::attribute::SdrAllFillAttributesHelperPtr SwFrame::getSdrAllFillAttributesHelper() const
{
    if (IsTextFrame())
    {
        return static_cast<const SwTextFrame*>(this)->GetTextNodeForParaProps()->getSdrAllFillAttributesHelper();
    }
    else if (IsNoTextFrame())
    {
        return static_cast<const SwNoTextFrame*>(this)->GetNode()->getSdrAllFillAttributesHelper();
    }
    else
    {
        return static_castconst SwLayoutFrame* >(this)->GetFormat()->getSdrAllFillAttributesHelper();
    }
}

bool SwFrame::supportsFullDrawingLayerFillAttributeSet() const
{
    if (IsContentFrame())
    {
        return true;
    }
    else
    {
        return static_castconst SwLayoutFrame* >(this)->GetFormat()->supportsFullDrawingLayerFillAttributeSet();
    }
}

/*
 *  SwFrame::FindNext_(), FindPrev_(), InvalidateNextPos()
 *         FindNextCnt_() visits tables and sections and only returns SwContentFrames.
 *
 *  Description         Invalidates the position of the next frame.
 *      This is the direct successor or in case of ContentFrames the next
 *      ContentFrame which sits in the same flow as I do:
 *      - body,
 *      - footnote,
 *      - in headers/footers the notification only needs to be forwarded
 *        inside the section
 *      - same for Flys
 *      - Contents in tabs remain only inside their cell
 *      - in principle tables behave exactly like the Contents
 *      - sections also
 */

// This helper function is an equivalent to the ImplGetNextContentFrame() method,
// besides ContentFrames this function also returns TabFrames and SectionFrames.
static SwFrame* lcl_NextFrame( SwFrame* pFrame )
{
    SwFrame *pRet = nullptr;
    bool bGoingUp = false;
    do {
        SwFrame *p = nullptr;

        bool bGoingFwd = false;
        bool bGoingDown = !bGoingUp && pFrame->IsLayoutFrame();
        if (bGoingDown)
        {
            p = static_cast<SwLayoutFrame*>(pFrame)->Lower();
            bGoingDown = nullptr != p;
        }
        if( !bGoingDown )
        {
            p = pFrame->IsFlyFrame() ? static_cast<SwFlyFrame*>(pFrame)->GetNextLink() : pFrame->GetNext();
            bGoingFwd = nullptr != p;
            if ( !bGoingFwd )
            {
                p = pFrame->GetUpper();
                bGoingUp = nullptr != p;
                if ( !bGoingUp )
                {
                    return nullptr;
                }
            }
        }
        bGoingUp = !(bGoingFwd || bGoingDown);
        pFrame = p;
    } while ( nullptr == (pRet = ( ( pFrame->IsContentFrame() || ( !bGoingUp &&
            ( pFrame->IsTabFrame() || pFrame->IsSctFrame() ) ) )? pFrame : nullptr ) ) );
    return pRet;
}

SwFrame *SwFrame::FindNext_()
{
    bool bIgnoreTab = false;
    SwFrame *pThis = this;

    if ( IsTabFrame() )
    {
        //The last Content of the table gets picked up and his follower is
        //returned. To be able to deactivate the special case for tables
        //(see below) bIgnoreTab will be set.
        if ( static_cast<SwTabFrame*>(this)->GetFollow() )
            return static_cast<SwTabFrame*>(this)->GetFollow();

        pThis = static_cast<SwTabFrame*>(this)->FindLastContentOrTable();
        if ( !pThis )
            pThis = this;
        bIgnoreTab = true;
    }
    else if ( IsSctFrame() )
    {
        //The last Content of the section gets picked and his follower is returned.
        if ( static_cast<SwSectionFrame*>(this)->GetFollow() )
            return static_cast<SwSectionFrame*>(this)->GetFollow();

        pThis = static_cast<SwSectionFrame*>(this)->FindLastContent();
        if ( !pThis )
            pThis = this;
    }
    else if ( IsContentFrame() )
    {
        ifstatic_cast<SwContentFrame*>(this)->GetFollow() )
            return static_cast<SwContentFrame*>(this)->GetFollow();
    }
    else if ( IsRowFrame() )
    {
        SwFrame* pMyUpper = GetUpper();
        if ( pMyUpper->IsTabFrame() && static_cast<SwTabFrame*>(pMyUpper)->GetFollow() )
            return static_cast<SwTabFrame*>(pMyUpper)->GetFollow()->GetLower();
        else return nullptr;
    }
    else
        return nullptr;

    SwFrame* pRet = nullptr;
    const bool bFootnote  = pThis->IsInFootnote();
    if ( !bIgnoreTab && pThis->IsInTab() )
    {
        SwLayoutFrame *pUp = pThis->GetUpper();
        while (pUp && !pUp->IsCellFrame())
            pUp = pUp->GetUpper();
        assert(pUp && "Content flag says it's in table but it's not in cell.");
        SwFrame* pNxt = pUp ? static_cast<SwCellFrame*>(pUp)->GetFollowCell() : nullptr;
        if ( pNxt )
            pNxt = static_cast<SwCellFrame*>(pNxt)->ContainsContent();
        if ( !pNxt )
        {
            pNxt = lcl_NextFrame( pThis );
            if (pUp && pUp->IsAnLower(pNxt))
                pRet = pNxt;
        }
        else
            pRet = pNxt;
    }
    else
    {
        const bool bBody = pThis->IsInDocBody();
        SwFrame *pNxtCnt = lcl_NextFrame( pThis );
        if ( pNxtCnt )
        {
            if ( bBody || bFootnote )
            {
                while ( pNxtCnt )
                {
                    // OD 02.04.2003 #108446# - check for endnote, only if found
                    // next content isn't contained in a section, that collect its
                    // endnotes at its end.
                    bool bEndn = IsInSct() && !IsSctFrame() &&
                                 ( !pNxtCnt->IsInSct() ||
                                   !pNxtCnt->FindSctFrame()->IsEndnAtEnd()
                                 );
                    if ( ( bBody && pNxtCnt->IsInDocBody() ) ||
                         ( pNxtCnt->IsInFootnote() &&
                           ( bFootnote ||
                             ( bEndn && pNxtCnt->FindFootnoteFrame()->GetAttr()->GetFootnote().IsEndNote() )
                           )
                         )
                       )
                    {
                        if (pNxtCnt->IsInTab())
                        {
                            if (!IsTabFrame() || !static_cast<SwLayoutFrame*>(this)->IsAnLower(pNxtCnt))
                            {
                                pRet = pNxtCnt->FindTabFrame();
                                break;
                            }
                        }
                        else
                        {
                            pRet = pNxtCnt;
                            break;
                        }
                    }
                    pNxtCnt = lcl_NextFrame( pNxtCnt );
                }
            }
            else if ( pThis->IsInFly() )
            {
                pRet = pNxtCnt->IsInTab() ? pNxtCnt->FindTabFrame()
                                            : pNxtCnt;
            }
            else    //footer-/or header section
            {
                const SwFrame *pUp = pThis->GetUpper();
                const SwFrame *pCntUp = pNxtCnt->GetUpper();
                while ( pUp && pUp->GetUpper() &&
                        !pUp->IsHeaderFrame() && !pUp->IsFooterFrame() )
                    pUp = pUp->GetUpper();
                while ( pCntUp && pCntUp->GetUpper() &&
                        !pCntUp->IsHeaderFrame() && !pCntUp->IsFooterFrame() )
                    pCntUp = pCntUp->GetUpper();
                if ( pCntUp == pUp )
                {
                    pRet = pNxtCnt->IsInTab() ? pNxtCnt->FindTabFrame()
                                                : pNxtCnt;
                }
            }
        }
    }
    if( pRet && pRet->IsInSct() )
    {
        SwSectionFrame* pSct = pRet->FindSctFrame();
        //Footnotes in frames with columns must not return the section which
        //contains the footnote
        if( !pSct->IsAnLower( this ) &&
            (!bFootnote || pSct->IsInFootnote() ) )
            return pSct;
    }
    return pRet == this ? nullptr : pRet;
}

// #i27138# - add parameter <_bInSameFootnote>
SwContentFrame *SwFrame::FindNextCnt_( const bool _bInSameFootnote )
{
    SwFrame *pThis = this;

    if ( IsTabFrame() )
    {
        if ( static_cast<SwTabFrame*>(this)->GetFollow() )
        {
            pThis = static_cast<SwTabFrame*>(this)->GetFollow()->ContainsContent();
            if( pThis )
                return static_cast<SwContentFrame*>(pThis);
        }
        pThis = static_cast<SwTabFrame*>(this)->FindLastContentOrTable();
        if ( !pThis )
            return nullptr;
    }
    else if ( IsSctFrame() )
    {
        if ( static_cast<SwSectionFrame*>(this)->GetFollow() )
        {
            pThis = static_cast<SwSectionFrame*>(this)->GetFollow()->ContainsContent();
            if( pThis )
                return static_cast<SwContentFrame*>(pThis);
        }
        pThis = static_cast<SwSectionFrame*>(this)->FindLastContent();
        if ( !pThis )
            return nullptr;
    }
    else if ( IsContentFrame() && static_cast<SwContentFrame*>(this)->GetFollow() )
        return static_cast<SwContentFrame*>(this)->GetFollow();

    if ( pThis->IsContentFrame() )
    {
        const bool bBody = pThis->IsInDocBody();
        const bool bFootnote  = pThis->IsInFootnote();
        SwContentFrame *pNxtCnt = static_cast<SwContentFrame*>(pThis)->GetNextContentFrame();
        if ( pNxtCnt )
        {
            // #i27138#
            if ( bBody || ( bFootnote && !_bInSameFootnote ) )
            {
                // handling for environments 'footnotes' and 'document body frames':
                while ( pNxtCnt )
                {
                    if ( (bBody && pNxtCnt->IsInDocBody()) ||
                         (bFootnote  && pNxtCnt->IsInFootnote()) )
                        return pNxtCnt;
                    pNxtCnt = pNxtCnt->GetNextContentFrame();
                }
            }
            // #i27138#
            else if ( bFootnote && _bInSameFootnote )
            {
                // handling for environments 'each footnote':
                // Assure that found next content frame belongs to the same footnotes
                const SwFootnoteFrame* pFootnoteFrameOfNext( pNxtCnt->FindFootnoteFrame() );
                SwFootnoteFrame* pFootnoteFrameOfCurr(pThis->FindFootnoteFrame());
                OSL_ENSURE( pFootnoteFrameOfCurr,
                        " );
                if ( pFootnoteFrameOfNext == pFootnoteFrameOfCurr )
                {
                    return pNxtCnt;
                }
                else if ( pFootnoteFrameOfCurr->GetFollow() )
                {
                    // next content frame has to be the first content frame
                    // in the follow footnote, which contains a content frame.
                    SwFootnoteFrame* pFollowFootnoteFrameOfCurr(pFootnoteFrameOfCurr);
                    pNxtCnt = nullptr;
                    do {
                        pFollowFootnoteFrameOfCurr = pFollowFootnoteFrameOfCurr->GetFollow();
                        pNxtCnt = pFollowFootnoteFrameOfCurr->ContainsContent();
                    } while ( !pNxtCnt && pFollowFootnoteFrameOfCurr->GetFollow() );
                    return pNxtCnt;
                }
                else
                {
                    // current content frame is the last content frame in the
                    // footnote - no next content frame exists.
                    return nullptr;
                }
            }
            else if ( pThis->IsInFly() )
                // handling for environments 'unlinked fly frame' and
                // 'group of linked fly frames':
                return pNxtCnt;
            else
            {
                // handling for environments 'page header' and 'page footer':
                const SwFrame *pUp = pThis->GetUpper();
                const SwFrame *pCntUp = pNxtCnt->GetUpper();
                while ( pUp && pUp->GetUpper() &&
                        !pUp->IsHeaderFrame() && !pUp->IsFooterFrame() )
                    pUp = pUp->GetUpper();
                while ( pCntUp && pCntUp->GetUpper() &&
                        !pCntUp->IsHeaderFrame() && !pCntUp->IsFooterFrame() )
                    pCntUp = pCntUp->GetUpper();
                if ( pCntUp == pUp )
                    return pNxtCnt;
            }
        }
    }
    return nullptr;
}

/** method to determine previous content frame in the same environment
    for a flow frame (content frame, table frame, section frame)

    OD 2005-11-30 #i27138#
*/

SwContentFrame* SwFrame::FindPrevCnt_()
{
    if ( !IsFlowFrame() )
    {
        // nothing to do, if current frame isn't a flow frame.
        return nullptr;
    }

    SwContentFrame* pPrevContentFrame( nullptr );

    // Because method <SwContentFrame::GetPrevContentFrame()> is used to travel
    // through the layout, a content frame, at which the travel starts, is needed.
    SwContentFrame* pCurrContentFrame = dynamic_cast<SwContentFrame*>(this);

    // perform shortcut, if current frame is a follow, and
    // determine <pCurrContentFrame>, if current frame is a table or section frame
    if ( pCurrContentFrame && pCurrContentFrame->IsFollow() )
    {
        // previous content frame is its master content frame
        pPrevContentFrame = pCurrContentFrame->FindMaster();
    }
    else if ( IsTabFrame() )
    {
        SwTabFrame* pTabFrame( static_cast<SwTabFrame*>(this) );
        if ( pTabFrame->IsFollow() )
        {
            // previous content frame is the last content of its master table frame
            pPrevContentFrame = pTabFrame->FindMaster()->FindLastContent();
        }
        else
        {
            // start content frame for the search is the first content frame of
            // the table frame.
            pCurrContentFrame = pTabFrame->ContainsContent();
        }
    }
    else if ( IsSctFrame() )
    {
        SwSectionFrame* pSectFrame( static_cast<SwSectionFrame*>(this) );
        if ( pSectFrame->IsFollow() )
        {
            // previous content frame is the last content of its master section frame
            pPrevContentFrame = pSectFrame->FindMaster()->FindLastContent();
        }
        else
        {
            // start content frame for the search is the first content frame of
            // the section frame.
            pCurrContentFrame = pSectFrame->ContainsContent();
        }
    }

    // search for next content frame, depending on the environment, in which
    // the current frame is in.
    if ( !pPrevContentFrame && pCurrContentFrame )
    {
        pPrevContentFrame = pCurrContentFrame->GetPrevContentFrame();
        if ( pPrevContentFrame )
        {
            if ( pCurrContentFrame->IsInFly() )
            {
                // handling for environments 'unlinked fly frame' and
                // 'group of linked fly frames':
                // Nothing to do, <pPrevContentFrame> is the one
            }
            else
            {
                const bool bInDocBody = pCurrContentFrame->IsInDocBody();
                const bool bInFootnote  = pCurrContentFrame->IsInFootnote();
                if ( bInDocBody )
                {
                    // handling for environments 'footnotes' and 'document body frames':
                    // Assure that found previous frame is also in one of these
                    // environments. Otherwise, travel further
                    while ( pPrevContentFrame )
                    {
                        if ( ( bInDocBody && pPrevContentFrame->IsInDocBody() ) ||
                             ( bInFootnote && pPrevContentFrame->IsInFootnote() ) )
                        {
                            break;
                        }
                        pPrevContentFrame = pPrevContentFrame->GetPrevContentFrame();
                    }
                }
                else if ( bInFootnote )
                {
                    // handling for environments 'each footnote':
                    // Assure that found next content frame belongs to the same footnotes
                    const SwFootnoteFrame* pFootnoteFrameOfPrev( pPrevContentFrame->FindFootnoteFrame() );
                    SwFootnoteFrame* pFootnoteFrameOfCurr(pCurrContentFrame->FindFootnoteFrame());
                    if ( pFootnoteFrameOfPrev != pFootnoteFrameOfCurr )
                    {
                        if ( pFootnoteFrameOfCurr->GetMaster() )
                        {
                            SwFootnoteFrame* pMasterFootnoteFrameOfCurr(pFootnoteFrameOfCurr);
                            pPrevContentFrame = nullptr;
                            // correct wrong loop-condition
                            do {
                                pMasterFootnoteFrameOfCurr = pMasterFootnoteFrameOfCurr->GetMaster();
                                pPrevContentFrame = pMasterFootnoteFrameOfCurr->FindLastContent();
                            } while ( !pPrevContentFrame &&
                                      pMasterFootnoteFrameOfCurr->GetMaster() );
                        }
                        else
                        {
                            // current content frame is the first content in the
                            // footnote - no previous content exists.
                            pPrevContentFrame = nullptr;
                        }
                    }
                }
                else
                {
                    // handling for environments 'page header' and 'page footer':
                    // Assure that found previous frame is also in the same
                    // page header respectively page footer as <pCurrContentFrame>
                    // Note: At this point it's clear that <pCurrContentFrame> has
                    //       to be inside a page header or page footer and that
                    //       neither <pCurrContentFrame> nor <pPrevContentFrame> are
                    //       inside a fly frame.
                    //       Thus, method <FindFooterOrHeader()> can be used.
                    OSL_ENSURE( pCurrContentFrame->FindFooterOrHeader(),
                            " - unknown layout situation: current frame should be in page header or page footer" );
                    OSL_ENSURE( !pPrevContentFrame->IsInFly(),
                            " - unknown layout situation: found previous frame should *not* be inside a fly frame." );
                    if ( pPrevContentFrame->FindFooterOrHeader() !=
                                            pCurrContentFrame->FindFooterOrHeader() )
                    {
                        pPrevContentFrame = nullptr;
                    }
                }
            }
        }
    }

    return pPrevContentFrame;
}

SwFrame *SwFrame::FindPrev_()
{
    bool bIgnoreTab = false;
    SwFrame *pThis = this;

    if ( IsTabFrame() )
    {
        //The first Content of the table gets picked up and his predecessor is
        //returned. To be able to deactivate the special case for tables
        //(see below) bIgnoreTab will be set.
        if ( static_cast<SwTabFrame*>(this)->IsFollow() )
            return static_cast<SwTabFrame*>(this)->FindMaster();
        else
            pThis = static_cast<SwTabFrame*>(this)->ContainsContent();
        bIgnoreTab = true;
    }

    if ( pThis && pThis->IsContentFrame() )
    {
        SwContentFrame *pPrvCnt = static_cast<SwContentFrame*>(pThis)->GetPrevContentFrame();
        if( !pPrvCnt )
            return nullptr;
        if ( !bIgnoreTab && pThis->IsInTab() )
        {
            SwLayoutFrame *pUp = pThis->GetUpper();
            while (pUp && !pUp->IsCellFrame())
                pUp = pUp->GetUpper();
            assert(pUp && "Content flag says it's in table but it's not in cell.");
            if (pUp && pUp->IsAnLower(pPrvCnt))
                return pPrvCnt;
        }
        else
        {
            SwFrame* pRet;
            const bool bBody = pThis->IsInDocBody();
            const bool bFootnote  = !bBody && pThis->IsInFootnote();
            if ( bBody || bFootnote )
            {
                while ( pPrvCnt )
                {
                    if ( (bBody && pPrvCnt->IsInDocBody()) ||
                            (bFootnote   && pPrvCnt->IsInFootnote()) )
                    {
                        pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrame()
                                                  : static_cast<SwFrame*>(pPrvCnt);
                        return pRet;
                    }
                    pPrvCnt = pPrvCnt->GetPrevContentFrame();
                }
            }
            else if ( pThis->IsInFly() )
            {
                pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrame()
                                            : static_cast<SwFrame*>(pPrvCnt);
                return pRet;
            }
            else // footer or header or Fly
            {
                const SwFrame *pUp = pThis->GetUpper();
                const SwFrame *pCntUp = pPrvCnt->GetUpper();
                while ( pUp && pUp->GetUpper() &&
                        !pUp->IsHeaderFrame() && !pUp->IsFooterFrame() )
                    pUp = pUp->GetUpper();
                while ( pCntUp && pCntUp->GetUpper() )
                    pCntUp = pCntUp->GetUpper();
                if ( pCntUp == pUp )
                {
                    pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrame()
                                                : static_cast<SwFrame*>(pPrvCnt);
                    return pRet;
                }
            }
        }
    }
    return nullptr;
}

void SwFrame::ImplInvalidateNextPos( bool bNoFootnote )
{
    SwFrame *pFrame = FindNext_();
    if ( nullptr == pFrame )
        return;

    if( pFrame->IsSctFrame() )
    {
        while( pFrame && pFrame->IsSctFrame() )
        {
            ifstatic_cast<SwSectionFrame*>(pFrame)->GetSection() )
            {
                SwFrame* pTmp = static_cast<SwSectionFrame*>(pFrame)->ContainsAny();
                if( pTmp )
                    pTmp->InvalidatePos();
                else if( !bNoFootnote )
                    static_cast<SwSectionFrame*>(pFrame)->InvalidateFootnotePos();
                if( !IsInSct() || FindSctFrame()->GetFollow() != pFrame )
                    pFrame->InvalidatePos();
                return;
            }
            pFrame = pFrame->FindNext();
        }
        if( pFrame )
        {
            if ( pFrame->IsSctFrame())
            {
                // We need to invalidate the section's content so it gets
                // the chance to flow to a different page.
                SwFrame* pTmp = static_cast<SwSectionFrame*>(pFrame)->ContainsAny();
                if( pTmp )
                    pTmp->InvalidatePos();
                if( !IsInSct() || FindSctFrame()->GetFollow() != pFrame )
                    pFrame->InvalidatePos();
            }
            else
                pFrame->InvalidatePos();
        }
    }
    else
        pFrame->InvalidatePos();
}

/** method to invalidate printing area of next frame

    OD 09.01.2004 #i11859#

    FME 2004-04-19 #i27145# Moved function from SwTextFrame to SwFrame
*/

void SwFrame::InvalidateNextPrtArea()
{
    // determine next frame
    SwFrame* pNextFrame = FindNext();
    // skip empty section frames and hidden text frames
    {
        while (pNextFrame && pNextFrame->IsHiddenNow())
        {
            pNextFrame = pNextFrame->FindNext();
        }
    }

    // Invalidate printing area of found next frame
    if ( !pNextFrame )
        return;

    if ( pNextFrame->IsSctFrame() )
    {
        // Invalidate printing area of found section frame, if
        // (1) this text frame isn't in a section OR
        // (2) found section frame isn't a follow of the section frame this
        //     text frame is in.
        if ( !IsInSct() || FindSctFrame()->GetFollow() != pNextFrame )
        {
            pNextFrame->InvalidatePrt();
        }

        // Invalidate printing area of first content in found section.
        SwFrame* pFstContentOfSctFrame =
                static_cast<SwSectionFrame*>(pNextFrame)->ContainsAny();
        if ( pFstContentOfSctFrame )
        {
            pFstContentOfSctFrame->InvalidatePrt();
        }
    }
    else
    {
        pNextFrame->InvalidatePrt();
    }
}

/// @returns true if the frame _directly_ sits in a section
///     but not if it sits in a table which itself sits in a section.
static bool lcl_IsInSectionDirectly( const SwFrame *pUp )
{
    bool bSeenColumn = false;

    while( pUp )
    {
        if( pUp->IsColumnFrame() )
            bSeenColumn = true;
        else if( pUp->IsSctFrame() )
        {
            auto pSection = static_cast<const SwSectionFrame*>(pUp);
            const SwFrame* pHeaderFooter = pSection->FindFooterOrHeader();
            // When the section frame is not in header/footer:
            // Allow move of frame in case our only column is not growable.
            // Also allow if there is a previous section frame (to move back).
            bool bAllowOutsideHeaderFooter = !pSection->Growable() || pSection->GetPrecede();
            return bSeenColumn || (!pHeaderFooter && bAllowOutsideHeaderFooter);
        }
        else if( pUp->IsTabFrame() )
            return false;
        pUp = pUp->GetUpper();
    }
    return false;
}

/** determine, if frame is moveable in given environment

    OD 08.08.2003 #110978#
    method replaced 'old' method <sal_Bool IsMoveable() const>.
    Determines, if frame is moveable in given environment. if no environment
    is given (parameter _pLayoutFrame == 0), the movability in the actual
    environment (<GetUpper()) is checked.
*/

bool SwFrame::IsMoveable( const SwLayoutFrame* _pLayoutFrame ) const
{
    bool bRetVal = false;

    if ( !_pLayoutFrame )
    {
        _pLayoutFrame = GetUpper();
    }

    if ( _pLayoutFrame && IsFlowFrame() )
    {
        if ( _pLayoutFrame->IsInSct() && lcl_IsInSectionDirectly( _pLayoutFrame ) )
        {
            bRetVal = true;
        }
        else if ( _pLayoutFrame->IsInFly() ||
                  _pLayoutFrame->IsInDocBody() ||
                  _pLayoutFrame->IsInFootnote() )
        {
            // If IsMovable() is called before a MoveFwd() the method
            // may return false if there is no NextCellLeaf. If
            // IsMovable() is called before a MoveBwd() the method may
            // return false if there is no PrevCellLeaf.
            if ( _pLayoutFrame->IsInTab() && !IsTabFrame() &&
                 ( !IsContentFrame() || (!const_cast<SwFrame*>(this)->GetNextCellLeaf()
                                      && !const_cast<SwFrame*>(this)->GetPrevCellLeaf()) )
                )
            {
                bRetVal = false;
            }
            else
            {
                if ( _pLayoutFrame->IsInFly() )
                {
                    // if fly frame has a follow (next linked fly frame) or can split,
                    // frame is moveable.
                    const SwFlyFrame* pFlyFrame = _pLayoutFrame->FindFlyFrame();
                    if ( pFlyFrame->GetNextLink() || pFlyFrame->IsFlySplitAllowed() )
                    {
                        bRetVal = true;
                    }
                    else
                    {
                        // if environment is columned, frame is moveable, if
                        // it isn't in last column.
                        // search for column frame
                        const SwFrame* pCol = _pLayoutFrame;
                        while ( pCol && !pCol->IsColumnFrame() )
                        {
                            pCol = pCol->GetUpper();
                        }
                        // frame is moveable, if found column frame isn't last one.
                        if ( pCol && pCol->GetNext() )
                        {
                            bRetVal = true;
                        }
                    }
                }
                else if (!(_pLayoutFrame->IsInFootnote() && (IsTabFrame() || IsInTab())))
                {
                    bRetVal = true;
                }
            }
        }
    }

    return bRetVal;
}

void SwFrame::SetInfFlags()
{
    if ( !IsFlyFrame() && !GetUpper() ) //not yet pasted, no information available
        return;

    mbInfInvalid = mbInfBody = mbInfTab = mbInfFly = mbInfFootnote = mbInfSct = false;

    SwFrame *pFrame = this;
    if( IsFootnoteContFrame() )
        mbInfFootnote = true;
    do
    {
        // mbInfBody is only set in the page body, but not in the column body
        if ( pFrame->IsBodyFrame() && !mbInfFootnote && pFrame->GetUpper()
             && pFrame->GetUpper()->IsPageFrame() )
            mbInfBody = true;
        else if ( pFrame->IsTabFrame() || pFrame->IsCellFrame() )
        {
            mbInfTab = true;
        }
        else if ( pFrame->IsFlyFrame() )
            mbInfFly = true;
        else if ( pFrame->IsSctFrame() )
            mbInfSct = true;
        else if ( pFrame->IsFootnoteFrame() )
            mbInfFootnote = true;

        pFrame = pFrame->GetUpper();

    } while ( pFrame && !pFrame->IsPageFrame() ); //there is nothing above the page
}

/** Updates the vertical or the righttoleft-flags.
 *
 * If the property is derived, it's from the upper or (for fly frames) from
 * the anchor. Otherwise we've to call a virtual method to check the property.
 */

void SwFrame::SetDirFlags( bool bVert )
{
    if( bVert )
    {
        // OD 2004-01-21 #114969# - if derived, valid vertical flag only if
        // vertical flag of upper/anchor is valid.
        if( mbDerivedVert )
        {
            const SwFrame* pAsk = IsFlyFrame() ?
                          static_cast<SwFlyFrame*>(this)->GetAnchorFrame() : GetUpper();

            OSL_ENSURE( pAsk != this"Autsch! Stack overflow is about to happen" );

            if( pAsk )
            {
                mbVertical = pAsk->IsVertical();
                mbVertLR  = pAsk->IsVertLR();
                mbVertLRBT = pAsk->IsVertLRBT();

                if ( !pAsk->mbInvalidVert )
                    mbInvalidVert = false;

                if ( IsCellFrame() )
                {
                    SwCellFrame* pPrv = static_cast<SwCellFrame*>(this)->GetPreviousCell();
                    if ( pPrv && !mbVertical && pPrv->IsVertical() )
                    {
                        mbVertical = pPrv->IsVertical();
                        mbVertLR  = pPrv->IsVertLR();
                        mbVertLRBT = pPrv->IsVertLRBT();
                    }
                }
            }
        }
        else
            CheckDirection( bVert );
    }
    else
    {
        bool bInv = false;
        if( !mbDerivedR2L ) // CheckDirection is able to set bDerivedR2L!
            CheckDirection( bVert );
        if( mbDerivedR2L )
        {
            const SwFrame* pAsk = IsFlyFrame() ?
                          static_cast<SwFlyFrame*>(this)->GetAnchorFrame() : GetUpper();

            OSL_ENSURE( pAsk != this"Oops! Stack overflow is about to happen" );

            if( pAsk )
                mbRightToLeft = pAsk->IsRightToLeft();
            if( !pAsk || pAsk->mbInvalidR2L )
                bInv = mbInvalidR2L;
        }
        mbInvalidR2L = bInv;
    }
}

SwLayoutFrame* SwFrame::GetNextCellLeaf()
{
    SwFrame* pTmpFrame = this;
    while (pTmpFrame && !pTmpFrame->IsCellFrame())
        pTmpFrame = pTmpFrame->GetUpper();

    SAL_WARN_IF(!pTmpFrame, "sw.core""SwFrame::GetNextCellLeaf() without cell");
    return pTmpFrame ? static_cast<SwCellFrame*>(pTmpFrame)->GetFollowCell() : nullptr;
}

SwLayoutFrame* SwFrame::GetPrevCellLeaf()
{
    SwFrame* pTmpFrame = this;
    while (pTmpFrame && !pTmpFrame->IsCellFrame())
        pTmpFrame = pTmpFrame->GetUpper();

    SAL_WARN_IF(!pTmpFrame, "sw.core""SwFrame::GetNextPreviousLeaf() without cell");
    return pTmpFrame ? static_cast<SwCellFrame*>(pTmpFrame)->GetPreviousCell() : nullptr;
}

static SwCellFrame* lcl_FindCorrespondingCellFrame( const SwRowFrame& rOrigRow,
                                         const SwCellFrame& rOrigCell,
                                         const SwRowFrame& rCorrRow,
                                         bool bInFollow )
{
    SwCellFrame* pRet = nullptr;
    const SwCellFrame* pCell = static_cast<const SwCellFrame*>(rOrigRow.Lower());
    SwCellFrame* pCorrCell = const_cast<SwCellFrame*>(static_cast<const SwCellFrame*>(rCorrRow.Lower()));
    assert(pCell && pCorrCell && "lcl_FindCorrespondingCellFrame does not work");

    while ( pCell != &rOrigCell && !pCell->IsAnLower( &rOrigCell ) )
    {
        pCell = static_cast<const SwCellFrame*>(pCell->GetNext());
        pCorrCell = static_cast<SwCellFrame*>(pCorrCell->GetNext());
    }

    assert(pCell && pCorrCell && "lcl_FindCorrespondingCellFrame does not work");

    if ( pCell != &rOrigCell )
    {
        // rOrigCell must be a lower of pCell. We need to recurse into the rows:
        const SwFrame* pLower = pCell->Lower();
        assert(pLower && pLower->IsRowFrame() &&
               "lcl_FindCorrespondingCellFrame does not work");

        const SwRowFrame* pRow = static_cast<const SwRowFrame*>(pLower);
        while ( !pRow->IsAnLower( &rOrigCell ) )
            pRow = static_cast<const SwRowFrame*>(pRow->GetNext());

        SwRowFrame* pCorrRow = nullptr;
        if ( bInFollow )
            pCorrRow = pRow->GetFollowRow();
        else
        {
            SwRowFrame* pTmpRow = static_cast<SwRowFrame*>(pCorrCell->GetLastLower());

            if ( pTmpRow && pTmpRow->GetFollowRow() == pRow )
                pCorrRow = pTmpRow;
        }

        if ( pCorrRow )
            pRet = lcl_FindCorrespondingCellFrame( *pRow, rOrigCell, *pCorrRow, bInFollow );
    }
    else
        pRet = pCorrCell;

    return pRet;
}

// VERSION OF GetFollowCell() that assumes that we always have a follow flow line:
SwCellFrame* SwCellFrame::GetFollowCell() const
{
    SwCellFrame* pRet = nullptr;

    // NEW TABLES
    // Covered cells do not have follow cells!
    const tools::Long nRowSpan = GetLayoutRowSpan();
    if ( nRowSpan < 1 )
        return nullptr;

    // find most upper row frame
    const SwFrame* pRow = GetUpper();

    while (pRow && (!pRow->IsRowFrame() || !pRow->GetUpper()->IsTabFrame()))
        pRow = pRow->GetUpper();

    if (!pRow)
        return nullptr;

    const SwTabFrame* pTabFrame = static_cast<const SwTabFrame*>(pRow->GetUpper());
    if (!pTabFrame || !pTabFrame->GetFollow() || !pTabFrame->HasFollowFlowLine())
        return nullptr;

    const SwCellFrame* pThisCell = this;

    // Get last cell of the current table frame that belongs to the rowspan:
    if ( nRowSpan > 1 )
    {
        // optimization: Will end of row span be in last row or exceed row?
        tools::Long nMax = 0;
        while ( pRow->GetNext() && ++nMax < nRowSpan )
            pRow = pRow->GetNext();

        if ( !pRow->GetNext() )
        {
            pThisCell = &pThisCell->FindStartEndOfRowSpanCell( false );
            pRow = pThisCell->GetUpper();
        }
    }

    const SwRowFrame* pFollowRow = nullptr;
    if ( !pRow->GetNext() &&
         nullptr != ( pFollowRow = pRow->IsInSplitTableRow() ) &&
         ( !pFollowRow->IsRowSpanLine() || nRowSpan > 1 ) )
         pRet = lcl_FindCorrespondingCellFrame( *static_cast<const SwRowFrame*>(pRow), *pThisCell, *pFollowRow, true );

    return pRet;
}

// VERSION OF GetPreviousCell() THAT ASSUMES THAT WE ALWAYS HAVE A FFL
SwCellFrame* SwCellFrame::GetPreviousCell() const
{
    SwCellFrame* pRet = nullptr;

    // NEW TABLES
    // Covered cells do not have previous cells!
    if ( GetLayoutRowSpan() < 1 )
        return nullptr;

    // find most upper row frame
    const SwFrame* pRow = GetUpper();
    while( !pRow->IsRowFrame() || (pRow->GetUpper() && !pRow->GetUpper()->IsTabFrame()) )
        pRow = pRow->GetUpper();

    OSL_ENSURE( pRow->GetUpper() && pRow->GetUpper()->IsTabFrame(), "GetPreviousCell without Table" );

    const SwTabFrame* pTab = static_cast<const SwTabFrame*>(pRow->GetUpper());

    if ( pTab && pTab->IsFollow() )
    {
        const SwFrame* pTmp = pTab->GetFirstNonHeadlineRow();
        const bool bIsInFirstLine = ( pTmp == pRow );

        if ( bIsInFirstLine )
        {
            SwTabFrame *pMaster = pTab->FindMaster();
            if ( pMaster && pMaster->HasFollowFlowLine() )
            {
                SwRowFrame* pMasterRow = static_cast<SwRowFrame*>(pMaster->GetLastLower());
                if ( pMasterRow )
                    pRet = lcl_FindCorrespondingCellFrame( *static_cast<const SwRowFrame*>(pRow), *this, *pMasterRow, false );
                if ( pRet && pRet->GetTabBox()->getRowSpan() < 1 )
                    pRet = &const_cast<SwCellFrame&>(pRet->FindStartEndOfRowSpanCell( true ));
            }
        }
    }

    return pRet;
}

// --> NEW TABLES
const SwCellFrame& SwCellFrame::FindStartEndOfRowSpanCell( bool bStart ) const
{
    const SwTabFrame* pTableFrame = dynamic_cast<const SwTabFrame*>(GetUpper()->GetUpper());

    if ( !bStart && pTableFrame && pTableFrame->IsFollow() && pTableFrame->IsInHeadline( *this ) )
        return *this;

    OSL_ENSURE( pTableFrame &&
            (  (bStart && GetTabBox()->getRowSpan() < 1) ||
              (!bStart && GetLayoutRowSpan() > 1) ),
            "SwCellFrame::FindStartRowSpanCell: No rowspan, no table, no cookies" );

    if ( pTableFrame )
    {
        const SwTable* pTable = pTableFrame->GetTable();

        sal_uInt16 nMax = USHRT_MAX;
        const SwFrame* pCurrentRow = GetUpper();
        const bool bDoNotEnterHeadline = bStart && pTableFrame->IsFollow() &&
                                        !pTableFrame->IsInHeadline( *pCurrentRow );

        // check how many rows we are allowed to go up or down until we reach the end of
        // the current table frame:
        nMax = 0;
        while ( bStart ? pCurrentRow->GetPrev() : pCurrentRow->GetNext() )
        {
            if ( bStart )
            {
                // do not enter a repeated headline:
                if ( bDoNotEnterHeadline && pTableFrame->IsFollow() &&
                     pTableFrame->IsInHeadline( *pCurrentRow->GetPrev() ) )
                    break;

                pCurrentRow = pCurrentRow->GetPrev();
            }
            else
               pCurrentRow = pCurrentRow->GetNext();

            ++nMax;
        }

        // By passing the nMax value for Find*OfRowSpan (in case of bCurrentTableOnly
        // is set) we assure that we find a rMasterBox that has a SwCellFrame in
        // the current table frame:
        const SwTableBox& rMasterBox = bStart ?
                                       GetTabBox()->FindStartOfRowSpan( *pTable, nMax ) :
                                       GetTabBox()->FindEndOfRowSpan( *pTable, nMax );

        SwIterator<SwCellFrame,SwFormat> aIter( *rMasterBox.GetFrameFormat() );

        for ( SwCellFrame* pMasterCell = aIter.First(); pMasterCell; pMasterCell = aIter.Next() )
        {
            if ( pMasterCell->GetTabBox() == &rMasterBox )
            {
                const SwTabFrame* pMasterTable = static_cast<const SwTabFrame*>(pMasterCell->GetUpper()->GetUpper());

                if ( pMasterTable == pTableFrame )
                {
                    return *pMasterCell;
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=81 H=88 G=84

¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.33Angebot  Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können  ¤

*Eine klare Vorstellung vom Zielzustand






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.