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

Quelle  section.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 <libxml/xmlstring.h>
#include <libxml/xmlwriter.h>
#include <stdlib.h>
#include <hintids.hxx>
#include <osl/diagnose.h>
#include <sot/exchange.hxx>
#include <svl/stritem.hxx>
#include <sfx2/docfile.hxx>
#include <editeng/protitem.hxx>
#include <sfx2/linkmgr.hxx>
#include <sfx2/sfxsids.hrc>
#include <docary.hxx>
#include <fmtcntnt.hxx>
#include <fmtpdsc.hxx>
#include <doc.hxx>
#include <IDocumentUndoRedo.hxx>
#include <DocumentLinksAdministrationManager.hxx>
#include <DocumentContentOperationsManager.hxx>
#include <IDocumentRedlineAccess.hxx>
#include <IDocumentFieldsAccess.hxx>
#include <IDocumentStylePoolAccess.hxx>
#include <IDocumentState.hxx>
#include <IDocumentLayoutAccess.hxx>
#include <IDocumentStatistics.hxx>
#include <docstat.hxx>
#include <fmtanchr.hxx>
#include <node.hxx>
#include <pam.hxx>
#include <frmatr.hxx>
#include <frmtool.hxx>
#include <editsh.hxx>
#include <hints.hxx>
#include <docsh.hxx>
#include <ndtxt.hxx>
#include <section.hxx>
#include <swserv.hxx>
#include <shellio.hxx>
#include <poolfmt.hxx>
#include <swbaslnk.hxx>
#include <mvsave.hxx>
#include <ftnidx.hxx>
#include <doctxm.hxx>
#include <fmteiro.hxx>
#include <unosection.hxx>
#include <calbck.hxx>
#include <fmtclds.hxx>
#include <algorithm>
#include <utility>
#include "ndsect.hxx"

using namespace ::com::sun::star;

namespace {
    class SwIntrnlSectRefLink : public SwBaseLink
    {
        SwSectionFormat& m_rSectFormat;

    public:
        SwIntrnlSectRefLink(SwSectionFormat& rFormat, SfxLinkUpdateMode nUpdateType)
            : SwBaseLink(nUpdateType, SotClipboardFormatId::RTF)
            , m_rSectFormat(rFormat)
        {}

        virtual void Closed() override;
        virtual ::sfx2::SvBaseLink::UpdateResult DataChanged(
            const OUString& rMimeType, const css::uno::Any & rValue ) override;

        virtual const SwNode* GetAnchor() const override;
        virtual bool IsInRange( SwNodeOffset nSttNd, SwNodeOffset nEndNd ) const override;

        SwSectionNode* GetSectNode()
        {
            const SwNode* pSectNd( GetAnchor() );
            return const_cast<SwSectionNode*>( pSectNd->GetSectionNode() );
        }
    };
}

SwSectionData::SwSectionData(SectionType const eType, UIName aName)
    : m_eType(eType)
    , m_sSectionName(std::move(aName))
    , m_nPage(0)
    , m_bHiddenFlag(false)
    , m_bProtectFlag(false)
    , m_bEditInReadonlyFlag(false// edit in readonly sections
    , m_bHidden(false)
    , m_bCondHiddenFlag(true)
    , m_bConnectFlag(true)
{
}

// this must have the same semantics as operator=()
SwSectionData::SwSectionData(SwSection const& rSection)
    : m_eType(rSection.GetType())
    , m_sSectionName(rSection.GetSectionName())
    , m_sCondition(rSection.GetCondition())
    , m_sLinkFileName(rSection.GetLinkFileName())
    , m_sLinkFilePassword(rSection.GetLinkFilePassword())
    , m_Password(rSection.GetPassword())
    , m_nPage(rSection.GetPageNum())
    , m_bHiddenFlag(rSection.IsHiddenFlag())
    , m_bProtectFlag(rSection.IsProtect())
    // edit in readonly sections
    , m_bEditInReadonlyFlag(rSection.IsEditInReadonly())
    , m_bHidden(rSection.IsHidden())
    , m_bCondHiddenFlag(true)
    , m_bConnectFlag(rSection.IsConnectFlag())
{
}

// this must have the same semantics as operator=()
SwSectionData::SwSectionData(SwSectionData const& rOther)
    : m_eType(rOther.m_eType)
    , m_sSectionName(rOther.m_sSectionName)
    , m_sCondition(rOther.m_sCondition)
    , m_sLinkFileName(rOther.m_sLinkFileName)
    , m_sLinkFilePassword(rOther.m_sLinkFilePassword)
    , m_Password(rOther.m_Password)
    , m_nPage(rOther.GetPageNum())
    , m_bHiddenFlag(rOther.m_bHiddenFlag)
    , m_bProtectFlag(rOther.m_bProtectFlag)
    // edit in readonly sections
    , m_bEditInReadonlyFlag(rOther.m_bEditInReadonlyFlag)
    , m_bHidden(rOther.m_bHidden)
    , m_bCondHiddenFlag(true)
    , m_bConnectFlag(rOther.m_bConnectFlag)
{
}

// the semantics here are weird for reasons of backward compatibility
SwSectionData & SwSectionData::operator= (SwSectionData const& rOther)
{
    m_eType = rOther.m_eType;
    m_sSectionName = rOther.m_sSectionName;
    m_sCondition = rOther.m_sCondition;
    m_sLinkFileName = rOther.m_sLinkFileName;
    m_sLinkFilePassword = rOther.m_sLinkFilePassword;
    m_bConnectFlag = rOther.m_bConnectFlag;
    m_Password = rOther.m_Password;
    m_nPage = rOther.m_nPage;

    m_bEditInReadonlyFlag = rOther.m_bEditInReadonlyFlag;
    m_bProtectFlag = rOther.m_bProtectFlag;

    m_bHidden = rOther.m_bHidden;
    // FIXME: old code did not assign m_bHiddenFlag ?
    // FIXME: why should m_bCondHiddenFlag always default to true?
    m_bCondHiddenFlag = true;

    return *this;
}

// the semantics here are weird for reasons of backward compatibility
bool SwSectionData::operator==(SwSectionData const& rOther) const
{
    return (m_eType == rOther.m_eType)
        && (m_sSectionName == rOther.m_sSectionName)
        && (m_sCondition == rOther.m_sCondition)
        && (m_bHidden == rOther.m_bHidden)
        && (m_bProtectFlag == rOther.m_bProtectFlag)
        && (m_bEditInReadonlyFlag == rOther.m_bEditInReadonlyFlag)
        && (m_sLinkFileName == rOther.m_sLinkFileName)
        && (m_sLinkFilePassword == rOther.m_sLinkFilePassword)
        && (m_Password == rOther.m_Password)
        && (m_nPage == rOther.m_nPage);
    // FIXME: old code ignored m_bCondHiddenFlag m_bHiddenFlag m_bConnectFlag
}

void SwSectionData::dumpAsXml(xmlTextWriterPtr pWriter) const
{
    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwSectionData"));
    (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p"this);
    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("section-name"), BAD_CAST(m_sSectionName.toString().toUtf8().getStr()));
    (void)xmlTextWriterEndElement(pWriter);
}

SwSection::SwSection(
        SectionType const eType, UIName const& rName, SwSectionFormat & rFormat)
    : SwClient(& rFormat)
    , m_Data(eType, rName)
{
    StartListening(rFormat.GetNotifier());

    SwSection *const pParentSect = GetParent();
    if( pParentSect )
    {
        // edit in readonly sections
        m_Data.SetEditInReadonlyFlag( pParentSect->IsEditInReadonlyFlag() );
    }

    m_Data.SetProtectFlag( rFormat.GetProtect().IsContentProtected() );

    if (!m_Data.IsEditInReadonlyFlag()) // edit in readonly sections
    {
        m_Data.SetEditInReadonlyFlag( rFormat.GetEditInReadonly().GetValue() );
    }
}

SwSection::~SwSection()
{
    SwSectionFormat* pFormat = GetFormat();
    if( !pFormat )
        return;

    SwDoc& rDoc = pFormat->GetDoc();
    if( rDoc.IsInDtor() )
    {
        // We reattach our Format to the default FrameFormat
        // to not get any dependencies
        if( pFormat->DerivedFrom() != rDoc.GetDfltFrameFormat() )
            pFormat->RegisterToFormat( *rDoc.GetDfltFrameFormat() );
    }
    else
    {
        pFormat->Remove(*this); // remove
        SvtListener::EndListeningAll();

        if (SectionType::Content != m_Data.GetType())
        {
            rDoc.getIDocumentLinksAdministration().GetLinkManager().Remove( m_RefLink.get() );
        }

        if (m_RefObj.is())
        {
            rDoc.getIDocumentLinksAdministration().GetLinkManager().RemoveServer( m_RefObj.get() );
        }

        // If the Section is the last Client in the Format we can delete it
        pFormat->RemoveAllUnos();
        if( !pFormat->HasWriterListeners() )
        {
            // Do not add to the Undo. This should've happened earlier.
            ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
            rDoc.DelSectionFormat( pFormat );
        }
    }
    if (m_RefObj.is())
    {
        m_RefObj->Closed();
    }
}

void SwSection::SetSectionData(SwSectionData const& rData)
{
    bool const bOldHidden( m_Data.IsHidden() );
    bool const bOldCondHidden{m_Data.IsCondHidden()};
    m_Data = rData;
    // The next two may actually overwrite the m_Data.m_bProtect or EditInReadonly Flag
    // in Modify, which should result in same flag value as the old code!
    SetProtect(m_Data.IsProtectFlag());
    SetEditInReadonly(m_Data.IsEditInReadonlyFlag());
    if (bOldHidden != m_Data.IsHidden()
        || bOldCondHidden != m_Data.IsCondHidden()) // check if changed...
    {
        ImplSetHiddenFlag(m_Data.IsHidden(), m_Data.IsCondHidden());
    }
}

bool SwSection::DataEquals(SwSectionData const& rCmp) const
{
    // note that the old code compared the flags of the parameter with the
    // format attributes of this; the following mess should do the same...
    (void) GetLinkFileName(); // updates m_sLinkFileName
    bool const bProtect(m_Data.IsProtectFlag());
    bool const bEditInReadonly(m_Data.IsEditInReadonlyFlag());
    m_Data.SetProtectFlag(IsProtect());
    m_Data.SetEditInReadonlyFlag(IsEditInReadonly());
    bool const bResult( m_Data == rCmp );
    m_Data.SetProtectFlag(bProtect);
    m_Data.SetEditInReadonlyFlag(bEditInReadonly);
    return bResult;
}

void SwSection::ImplSetHiddenFlag(bool const bTmpHidden, bool const bCondition)
{
    SwSectionFormat* pFormat = GetFormat();
    OSL_ENSURE(pFormat, "ImplSetHiddenFlag: no format?");
    if( !pFormat )
        return;

    const bool bHide = bTmpHidden && bCondition;

    if (bHide) // should be hidden
    {
        if (!m_Data.IsHiddenFlag()) // is not hidden
        {
            // Is the Parent hidden?
            // This should be shown by the bHiddenFlag.

            // Tell all Children that they are hidden
            const sw::SectionHidden aHint;
            pFormat->CallSwClientNotify(aHint);
        }
    }
    else if (m_Data.IsHiddenFlag()) // show Nodes again
    {
        // Show all Frames
        // Only if the Parent Section is not restricting us!
        SwSection* pParentSect = pFormat->GetParentSection();
        if( !pParentSect || !pParentSect->IsHiddenFlag() )
        {
            // Tell all Children that the Parent is not hidden anymore
            const sw::SectionHidden aHint(false);
            pFormat->CallSwClientNotify(aHint);
        }
    }
}

bool SwSection::CalcHiddenFlag() const
{
    const SwSection* pSect = this;
    do {
        if( pSect->IsHidden() && pSect->IsCondHidden() )
            return true;
    } while( nullptr != ( pSect = pSect->GetParent()) );

    return false;
}

bool SwSection::IsProtect() const
{
    SwSectionFormat const *const pFormat( GetFormat() );
    OSL_ENSURE(pFormat, "SwSection::IsProtect: no format?");
    return pFormat
        ?   pFormat->GetProtect().IsContentProtected()
        :   IsProtectFlag();
}

// edit in readonly sections
bool SwSection::IsEditInReadonly() const
{
    SwSectionFormat const *const pFormat( GetFormat() );
    OSL_ENSURE(pFormat, "SwSection::IsEditInReadonly: no format?");
    return pFormat
        ?   pFormat->GetEditInReadonly().GetValue()
        :   IsEditInReadonlyFlag();
}

void SwSection::SetHidden(bool const bFlag)
{
    if (!m_Data.IsHidden() == !bFlag)
        return;

    m_Data.SetHidden(bFlag);
    ImplSetHiddenFlag(bFlag, m_Data.IsCondHidden());
}

void SwSection::SetProtect(bool const bFlag)
{
    SwSectionFormat *const pFormat( GetFormat() );
    OSL_ENSURE(pFormat, "SwSection::SetProtect: no format?");
    if (pFormat)
    {
        SvxProtectItem aItem( RES_PROTECT );
        aItem.SetContentProtect( bFlag );
        pFormat->SetFormatAttr( aItem );
        // note: this will call m_Data.SetProtectFlag via Modify!
    }
    else
    {
        m_Data.SetProtectFlag(bFlag);
    }
}

// edit in readonly sections
void SwSection::SetEditInReadonly(bool const bFlag)
{
    SwSectionFormat *const pFormat( GetFormat() );
    OSL_ENSURE(pFormat, "SwSection::SetEditInReadonly: no format?");
    if (pFormat)
    {
        SwFormatEditInReadonly aItem;
        aItem.SetValue( bFlag );
        pFormat->SetFormatAttr( aItem );
        // note: this will call m_Data.SetEditInReadonlyFlag via Modify!
    }
    else
    {
        m_Data.SetEditInReadonlyFlag(bFlag);
    }
}

void SwSection::SwClientNotify(const SwModify&, const SfxHint& rHint)
{
    Notify(rHint);
}

void SwSection::Notify(SfxHint const& rHint)
{
    if (rHint.GetId() == SfxHintId::SwSectionHidden)
    {
        auto rSectionHidden = static_cast<const sw::SectionHidden&>(rHint);
        m_Data.SetHiddenFlag(rSectionHidden.m_isHidden || (m_Data.IsHidden() && m_Data.IsCondHidden()));
        return;
    }
    if (rHint.GetId() == SfxHintId::SwObjectDying)
    {
        auto pDyingHint = static_cast<const sw::ObjectDyingHint*>(&rHint);
        CheckRegistration( *pDyingHint );
        return;
    }
    if (rHint.GetId() != SfxHintId::SwLegacyModify && rHint.GetId() != SfxHintId::SwAttrSetChange)
        return;

    bool bUpdateFootnote = false;
    if (rHint.GetId() == SfxHintId::SwLegacyModify)
    {
        auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
        auto pOld = pLegacy->m_pOld;
        auto pNew = pLegacy->m_pNew;
        switch(pLegacy->GetWhich())
        {
        case RES_PROTECT:
            if( pNew )
            {
                bool bNewFlag =
                    static_cast<const SvxProtectItem*>(pNew)->IsContentProtected();
                // this used to inherit the flag from the parent, but then there is
                // no way to turn it off in an inner section
                m_Data.SetProtectFlag( bNewFlag );
            }
            return;
        // edit in readonly sections
        case RES_EDIT_IN_READONLY:
            if( pNew )
            {
                const bool bNewFlag =
                    static_cast<const SwFormatEditInReadonly*>(pNew)->GetValue();
                m_Data.SetEditInReadonlyFlag( bNewFlag );
            }
            return;

        case RES_COL:
            // Is handled by the Layout, if appropriate
            break;

        case RES_FTN_AT_TXTEND:
        case RES_END_AT_TXTEND:
            if( pNew && pOld )
            {
                bUpdateFootnote = true;
            }
            break;
        }
    }
    else // rHint.GetId() == SfxHintId::SwAttrSetChange
    {
        auto pChangeHint = static_cast<const sw::AttrSetChangeHint*>(&rHint);
        const SwAttrSetChg* pOld = pChangeHint->m_pOld;
        const SwAttrSetChg* pNew = pChangeHint->m_pNew;
        if (pNew && pOld)
        {
            SfxItemSet* pNewSet = const_cast<SwAttrSetChg*>(pNew)->GetChgSet();
            SfxItemSet* pOldSet = const_cast<SwAttrSetChg*>(pOld)->GetChgSet();

            ifconst SvxProtectItem* pItem = pNewSet->GetItemIfSet(
                        RES_PROTECT, false ) )
            {
                m_Data.SetProtectFlag( pItem->IsContentProtected() );
                pNewSet->ClearItem( RES_PROTECT );
                pOldSet->ClearItem( RES_PROTECT );
            }

            // --> edit in readonly sections
            ifconst SwFormatEditInReadonly* pItem = pNewSet->GetItemIfSet(
                        RES_EDIT_IN_READONLY, false ) )
            {
                m_Data.SetEditInReadonlyFlag(pItem->GetValue());
                pNewSet->ClearItem( RES_EDIT_IN_READONLY );
                pOldSet->ClearItem( RES_EDIT_IN_READONLY );
            }

            if( SfxItemState::SET == pNewSet->GetItemState(
                        RES_FTN_AT_TXTEND, false ) ||
                SfxItemState::SET == pNewSet->GetItemState(
                        RES_END_AT_TXTEND, false ))
            {
                    bUpdateFootnote = true;
            }

            if( !pNewSet->Count() )
                return;
        }
    }

    if( bUpdateFootnote )
    {
        SwSectionNode* pSectNd = GetFormat()->GetSectionNode();
        if( pSectNd )
            pSectNd->GetDoc().GetFootnoteIdxs().UpdateFootnote(*pSectNd);
    }
}

void SwSection::SetRefObject( SwServerObject* pObj )
{
    m_RefObj = pObj;
}

void SwSection::SetCondHidden(bool const bFlag)
{
    if (!m_Data.IsCondHidden() == !bFlag)
        return;

    m_Data.SetCondHidden(bFlag);
    ImplSetHiddenFlag(m_Data.IsHidden(), bFlag);
}

// Set/remove the linked FileName
OUString const & SwSection::GetLinkFileName() const
{
    if (m_RefLink.is())
    {
        OUString sTmp;
        switch (m_Data.GetType())
        {
        case SectionType::DdeLink:
            sTmp = m_RefLink->GetLinkSourceName();
            break;

        case SectionType::FileLink:
            {
                OUString sRange;
                OUString sFilter;
                if (m_RefLink->GetLinkManager() &&
                    sfx2::LinkManager::GetDisplayNames(
                        m_RefLink.get(), nullptr, &sTmp, &sRange, &sFilter ))
                {
                    sTmp += OUStringChar(sfx2::cTokenSeparator) + sFilter
                        + OUStringChar(sfx2::cTokenSeparator) + sRange;
                }
                else if( GetFormat() && !GetFormat()->GetSectionNode() )
                {
                    // If the Section is in the UndoNodesArray, the LinkManager
                    // does not contain the Link, thus it cannot be queried for it.
                    // Thus return the current Name.
                    return m_Data.GetLinkFileName();
                }
            }
            break;
        defaultbreak;
        }
        m_Data.SetLinkFileName(sTmp);
    }
    return m_Data.GetLinkFileName();
}

void SwSection::SetLinkFileName(const OUString& rNew)
{
    if (m_RefLink.is())
    {
        m_RefLink->SetLinkSourceName( rNew );
    }
    m_Data.SetLinkFileName(rNew);
}

// If it was a Linked Section, we need to make all Child Links visible
void SwSection::MakeChildLinksVisible( const SwSectionNode& rSectNd )
{
    const SwNode* pNd;
    const ::sfx2::SvBaseLinks& rLnks = rSectNd.GetDoc().getIDocumentLinksAdministration().GetLinkManager().GetLinks();
    forauto n = rLnks.size(); n; )
    {
        sfx2::SvBaseLink& rBLnk = *rLnks[--n];
        if (!rBLnk.IsVisible() && dynamic_cast<const SwBaseLink*>(&rBLnk) != nullptr
            && nullptr != (pNd = static_cast<SwBaseLink&>(rBLnk).GetAnchor()))
        {
            pNd = pNd->StartOfSectionNode(); // If it's a SectionNode
            const SwSectionNode* pParent;
            while( nullptr != ( pParent = pNd->FindSectionNode() ) &&
                    ( SectionType::Content == pParent->GetSection().GetType()
                        || pNd == &rSectNd ))
                    pNd = pParent->StartOfSectionNode();

            // It's within a normal Section, so show again
            if( !pParent )
                rBLnk.SetVisible(true);
        }
    }
}

const SwTOXBase* SwSection::GetTOXBase() const
{
    const SwTOXBase* pRet = nullptr;
    if( SectionType::ToxContent == GetType() )
        pRet = dynamic_cast<const SwTOXBaseSection*>(this);
    return pRet;
}

SwSectionFormat::SwSectionFormat( SwFrameFormat* pDrvdFrame, SwDoc& rDoc )
    : SwFrameFormat( rDoc.GetAttrPool(), UIName(), pDrvdFrame )
{
    LockModify();
    SetFormatAttr( *GetDfltAttr( RES_COL ) );
    UnlockModify();
}

SwSectionFormat::~SwSectionFormat()
{
    if( GetDoc().IsInDtor() )
        return;

    SwSectionNode* pSectNd;
    const SwNodeIndex* pIdx = GetContent( false ).GetContentIdx();
    if( pIdx && &GetDoc().GetNodes() == &pIdx->GetNodes() &&
        nullptr != (pSectNd = pIdx->GetNode().GetSectionNode() ))
    {
        SwSection& rSect = pSectNd->GetSection();
        // If it was a linked Section, we need to make all Child Links
        // visible again
        if( rSect.IsConnected() )
            SwSection::MakeChildLinksVisible( *pSectNd );

        // Check whether we need to be visible, before deleting the Nodes
        if( rSect.IsHiddenFlag() )
        {
            SwSection* pParentSect = rSect.GetParent();
            if( !pParentSect || !pParentSect->IsHiddenFlag() )
            {
                // Make Nodes visible again
                rSect.SetHidden(false);
            }
        }
        // mba: test iteration; objects are removed while iterating
        // use hint which allows to specify, if the content shall be saved or not
        CallSwClientNotify( SwSectionFrameMoveAndDeleteHint( true ) );

        // Raise the Section up
        SwNodeRange aRg( *pSectNd, SwNodeOffset(0), *pSectNd->EndOfSectionNode() );
        GetDoc().GetNodes().SectionUp( &aRg );
    }
    LockModify();
    ResetFormatAttr( RES_CNTNT );
    UnlockModify();
}

SwSection * SwSectionFormat::GetSection() const
{
    return SwIterator<SwSection,SwSectionFormat>( *this ).First();
}

// Do not destroy all Frames in aDepend (Frames are recognized with a dynamic_cast).
void SwSectionFormat::DelFrames()
{
    SwSectionNode* pSectNd;
    const SwNodeIndex* pIdx = GetContent(false).GetContentIdx();
    if( pIdx && &GetDoc().GetNodes() == &pIdx->GetNodes() &&
        nullptr != (pSectNd = pIdx->GetNode().GetSectionNode() ))
    {
        // First delete the <SwSectionFrame> of the <SwSectionFormat> instance
        // mba: test iteration as objects are removed in iteration
        // use hint which allows to specify, if the content shall be saved or not
        CallSwClientNotify( SwSectionFrameMoveAndDeleteHint( false ) );

        // Then delete frames of the nested <SwSectionFormat> instances
        SwIterator<SwSectionFormat,SwSectionFormat> aIter( *this );
        SwSectionFormat *pLast = aIter.First();
        while ( pLast )
        {
            pLast->DelFrames();
            pLast = aIter.Next();
        }

        SwNodeOffset nEnd = pSectNd->EndOfSectionIndex();
        SwNodeOffset nStart = pSectNd->GetIndex()+1;
        sw_DeleteFootnote( pSectNd, nStart, nEnd );
    }
    if( !pIdx )
        return;

    // Send Hint for PageDesc. Actually the Layout contained in the
    // Paste of the Frame itself would need to do this. But that leads
    // to subsequent errors, which we'd need to solve at run-time.
    SwNodeIndex aNextNd( *pIdx );
    SwContentNode* pCNd = SwNodes::GoNextSection(&aNextNd, truefalse);
    if( pCNd )
    {
        const SfxPoolItem& rItem = pCNd->GetSwAttrSet().Get(RES_PAGEDESC);
        pCNd->CallSwClientNotify(sw::LegacyModifyHint(&rItem, &rItem));
    }
}

// Create the Views
void SwSectionFormat::MakeFrames()
{
    SwSectionNode* pSectNd;
    const SwNodeIndex* pIdx = GetContent(false).GetContentIdx();

    if( pIdx && &GetDoc().GetNodes() == &pIdx->GetNodes() &&
        nullptr != (pSectNd = pIdx->GetNode().GetSectionNode() ))
    {
        SwNodeIndex aIdx( *pIdx );
        pSectNd->MakeOwnFrames( &aIdx );
    }
}

void SwSectionFormat::SwClientNotify(const SwModify& rMod, const SfxHint& rHint)
{
    if (rHint.GetId() == SfxHintId::SwSectionHidden)
    {
        auto rSectionHidden = static_cast<const sw::SectionHidden&>(rHint);
        auto pSect = GetSection();
        if(!pSect || rSectionHidden.m_isHidden == pSect->IsHiddenFlag()) // already at target state, skipping.
            return;
        GetNotifier().Broadcast(rSectionHidden);
        return;
    }
    else if(SfxHintId::SwRemoveUnoObject == rHint.GetId())
    {
        SwFrameFormat::SwClientNotify(rMod, rHint);
        // invalidate cached uno object
        SetXTextSection(nullptr);
        return;
    }
    else if (rHint.GetId() == SfxHintId::SwFormatChange)
    {
        auto pChangeHint = static_cast<const SwFormatChangeHint*>(&rHint);
        if( !GetDoc().IsInDtor() &&
            pChangeHint->m_pNewFormat == static_cast<void*>(GetRegisteredIn()) &&
            dynamic_cast<const SwSectionFormat*>(pChangeHint->m_pNewFormat) != nullptr )
        {
            // My Parent will be changed, thus I need to update
            SwFrameFormat::SwClientNotify(rMod, rHint);
            UpdateParent();
            return;
        }
        SwFrameFormat::SwClientNotify(rMod, rHint);
        return;
    }
    else if (rHint.GetId() == SfxHintId::SwAttrSetChange)
    {
        auto pChangeHint = static_cast<const sw::AttrSetChangeHint*>(&rHint);
        const SwAttrSetChg* pOld = pChangeHint->m_pOld;
        const SwAttrSetChg* pNew = pChangeHint->m_pNew;
        if (HasWriterListeners() && pOld && pNew)
        {
            SfxItemSet* pNewSet = const_cast<SwAttrSetChg*>(pNew)->GetChgSet();
            SfxItemSet* pOldSet = const_cast<SwAttrSetChg*>(pOld)->GetChgSet();
            const SfxPoolItem *pItem;
            if( SfxItemState::SET == pNewSet->GetItemState(
                                        RES_PROTECT, false, &pItem ))
            {
                GetNotifier().Broadcast(sw::LegacyModifyHint(pItem, pItem));
                pNewSet->ClearItem( RES_PROTECT );
                pOldSet->ClearItem( RES_PROTECT );
            }

            // --> edit in readonly sections
            if( SfxItemState::SET == pNewSet->GetItemState(
                        RES_EDIT_IN_READONLY, false, &pItem ) )
            {
                GetNotifier().Broadcast(sw::LegacyModifyHint(pItem, pItem));
                pNewSet->ClearItem( RES_EDIT_IN_READONLY );
                pOldSet->ClearItem( RES_EDIT_IN_READONLY );
            }

            if( SfxItemState::SET == pNewSet->GetItemState(
                                    RES_FTN_AT_TXTEND, false, &pItem ))
            {
                GetNotifier().Broadcast(sw::LegacyModifyHint(pItem, pItem));
                pNewSet->ClearItem( RES_FTN_AT_TXTEND );
                pOldSet->ClearItem( RES_FTN_AT_TXTEND );
            }
            if( SfxItemState::SET == pNewSet->GetItemState(
                                    RES_END_AT_TXTEND, false, &pItem ))
            {
                GetNotifier().Broadcast(sw::LegacyModifyHint(pItem, pItem));
                pNewSet->ClearItem( RES_END_AT_TXTEND );
                pOldSet->ClearItem( RES_END_AT_TXTEND );
            }
            if( !pOld->GetChgSet()->Count() )
                return;
        }
        SwFrameFormat::SwClientNotify(rMod, rHint);
        return;
    }
    else if (rHint.GetId() == SfxHintId::SwObjectDying)
    {
        auto pDyingHint = static_cast<const sw::ObjectDyingHint*>(&rHint);
        if( !GetDoc().IsInDtor() &&
            pDyingHint->m_pDying == GetRegisteredIn() )
        {
            // My Parents will be destroyed, so get the Parent's Parent
            // and update
            SwFrameFormat::SwClientNotify(rMod, rHint);
            UpdateParent();
        }
        else
            SwFrameFormat::SwClientNotify(rMod, rHint);
        return;
    }
    else if (rHint.GetId() == SfxHintId::SwUpdateAttr)
    {
        SwFrameFormat::SwClientNotify(rMod, rHint);
        return;
    }
    else if (rHint.GetId() != SfxHintId::SwLegacyModify)
        return;
    auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
    sal_uInt16 nWhich = pLegacy->GetWhich();
    auto pOld = pLegacy->m_pOld;
    auto pNew = pLegacy->m_pNew;
    switch( nWhich )
    {
    case RES_FTN_AT_TXTEND:
    case RES_END_AT_TXTEND:
    case RES_PROTECT:
    case RES_EDIT_IN_READONLY: // edit in readonly sections
        // Pass through these Messages until the End of the tree!
        GetNotifier().Broadcast(sw::LegacyModifyHint(pOld, pNew));
        return// That's it!
    }
    SwFrameFormat::SwClientNotify(rMod, rHint);
}

void SwSectionFormat::SetXTextSection(rtl::Reference<SwXTextSection> const& xTextSection)
{
    m_wXTextSection = xTextSection.get();
}

bool SwSectionFormat::IsVisible() const
{
    if(SwFrameFormat::IsVisible())
        return true;
    SwIterator<SwSectionFormat,SwSectionFormat> aFormatIter(*this);
    for(SwSectionFormat* pChild = aFormatIter.First(); pChild; pChild = aFormatIter.Next())
        if(pChild->IsVisible())
            return true;
    return false;
}

// Get info from the Format
bool SwSectionFormat::GetInfo(SwFindNearestNode& rInfo) const
{
    if(GetFormatAttr( RES_PAGEDESC ).GetPageDesc())
    {
        const SwSectionNode* pNd = GetSectionNode();
        if(pNd)
            rInfo.CheckNode(*pNd);
    }
    return true;
}

static bool lcl_SectionCmpPos( const SwSection *pFirst, const SwSection *pSecond)
{
    const SwSectionFormat* pFSectFormat = pFirst->GetFormat();
    const SwSectionFormat* pSSectFormat = pSecond->GetFormat();
    assert( pFSectFormat && pSSectFormat &&
            pFSectFormat->GetContent(false).GetContentIdx() &&
            pSSectFormat->GetContent(false).GetContentIdx() &&
                "Invalid sections" );
    return pFSectFormat->GetContent(false).GetContentIdx()->GetIndex() <
                  pSSectFormat->GetContent(false).GetContentIdx()->GetIndex();
}

// get all Sections that have been derived from this one
void SwSectionFormat::GetChildSections( SwSections& rArr,
                                        SectionSort eSort,
                                        bool bAllSections ) const
{
    rArr.clear();

    if( !HasWriterListeners() )
        return;

    SwIterator<SwSectionFormat,SwSectionFormat> aIter(*this);
    const SwNodeIndex* pIdx;
    for( SwSectionFormat* pLast = aIter.First(); pLast; pLast = aIter.Next() )
        if( bAllSections ||
            ( nullptr != ( pIdx = pLast->GetContent(false).
            GetContentIdx()) && &pIdx->GetNodes() == &GetDoc().GetNodes() ))
        {
            SwSection* pDummy = pLast->GetSection();
            rArr.push_back( pDummy );
        }

    // Do we need any sorting?
    if( 1 < rArr.size() )
        switch( eSort )
        {
        case SectionSort::Pos:
            std::sort( rArr.begin(), rArr.end(), lcl_SectionCmpPos );
            break;
        case SectionSort::Notbreak;
        }
}

// See whether the Section is within the Nodes or the UndoNodes array
bool SwSectionFormat::IsInNodesArr() const
{
    const SwNodeIndex* pIdx = GetContent(false).GetContentIdx();
    return pIdx && &pIdx->GetNodes() == &GetDoc().GetNodes();
}

// Parent was changed
void SwSectionFormat::UpdateParent()
{
    if(!HasWriterListeners())
        return;

    const SwSection* pSection = GetSection();
    const SvxProtectItem* pProtect = &GetProtect();
    // edit in readonly sections
    const SwFormatEditInReadonly* pEditInReadonly = &GetEditInReadonly();
    bool bIsHidden = pSection->IsHidden();
    if(GetRegisteredIn())
    {
        const SwSection* pPS = GetParentSection();
        pProtect = &pPS->GetFormat()->GetProtect();
        pEditInReadonly = &pPS->GetFormat()->GetEditInReadonly();
        bIsHidden = pPS->IsHiddenFlag();
    }
    if(!pProtect->IsContentProtected() != !pSection->IsProtectFlag())
        CallSwClientNotify(sw::LegacyModifyHint(pProtect, pProtect));

    // edit in readonly sections
    if(!pEditInReadonly->GetValue() != !pSection->IsEditInReadonlyFlag())
        CallSwClientNotify(sw::LegacyModifyHint(pEditInReadonly, pEditInReadonly));

    if(bIsHidden == pSection->IsHiddenFlag())
    {
        const sw::SectionHidden aHint(bIsHidden);
        CallSwClientNotify(aHint);
    }
}

SwSectionNode* SwSectionFormat::GetSectionNode()
{
    const SwNodeIndex* pIdx = GetContent(false).GetContentIdx();
    if( pIdx && ( &pIdx->GetNodes() == &GetDoc().GetNodes() ))
        return pIdx->GetNode().GetSectionNode();
    return nullptr;
}

// Is this Section valid for the GlobalDocument?
const SwSection* SwSectionFormat::GetGlobalDocSection() const
{
    const SwSectionNode* pNd = GetSectionNode();
    if( pNd &&
        ( SectionType::FileLink == pNd->GetSection().GetType() ||
          SectionType::ToxContent == pNd->GetSection().GetType() ) &&
        pNd->GetIndex() > pNd->GetNodes().GetEndOfExtras().GetIndex() &&
        !pNd->StartOfSectionNode()->IsSectionNode() &&
        !pNd->StartOfSectionNode()->FindSectionNode() )
        return &pNd->GetSection();
    return nullptr;
}

// sw::Metadatable
::sfx2::IXmlIdRegistry& SwSectionFormat::GetRegistry()
{
    return GetDoc().GetXmlIdRegistry();
}

bool SwSectionFormat::IsInClipboard() const
{
    return GetDoc().IsClipBoard();
}

bool SwSectionFormat::IsInUndo() const
{
    return !IsInNodesArr();
}

bool SwSectionFormat::IsInContent() const
{
    SwNodeIndex const*const pIdx = GetContent(false).GetContentIdx();
    OSL_ENSURE(pIdx, "SwSectionFormat::IsInContent: no index?");
    return pIdx == nullptr || !GetDoc().IsInHeaderFooter(pIdx->GetNode());
}

// n.b.: if the section format represents an index, then there is both a
// SwXDocumentIndex and a SwXTextSection instance for this single core object.
// these two can both implement XMetadatable and forward to the same core
// section format.  but here only one UNO object can be returned,
// so always return the text section.
uno::Reference< rdf::XMetadatable >
SwSectionFormat::MakeUnoObject()
{
    rtl::Reference<SwXTextSection> xMeta;
    SwSection *const pSection( GetSection() );
    if (pSection)
    {
        xMeta = SwXTextSection::CreateXTextSection(this,
                        SectionType::ToxHeader == pSection->GetType());
    }
    return xMeta;
}

bool SwSectionFormat::supportsFullDrawingLayerFillAttributeSet() const
{
    return false;
}

void SwSectionFormat::dumpAsXml(xmlTextWriterPtr pWriter) const
{
    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwSectionFormat"));
    SwFormat::dumpAsXml(pWriter);
    (void)xmlTextWriterEndElement(pWriter);
}

void SwSectionFormats::dumpAsXml(xmlTextWriterPtr pWriter) const
{
    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwSectionFormats"));
    for (size_t i = 0; i < size(); ++i)
        GetFormat(i)->dumpAsXml(pWriter);
    (void)xmlTextWriterEndElement(pWriter);
}

// Method to break section links inside a linked section
static void lcl_BreakSectionLinksInSect( const SwSectionNode& rSectNd )
{
    if ( !rSectNd.GetSection().IsConnected() )
    {
        OSL_FAIL( "method - no Link at Section of SectionNode" );
        return;
    }
    const ::sfx2::SvBaseLink* pOwnLink( &(rSectNd.GetSection().GetBaseLink() ) );
    const ::sfx2::SvBaseLinks& rLnks = rSectNd.GetDoc().getIDocumentLinksAdministration().GetLinkManager().GetLinks();
    for ( auto n = rLnks.size(); n > 0; )
    {
        SwIntrnlSectRefLink* pSectLnk = dynamic_cast<SwIntrnlSectRefLink*>(&(*rLnks[ --n ]));
        if ( pSectLnk && pSectLnk != pOwnLink &&
             pSectLnk->IsInRange( rSectNd.GetIndex(), rSectNd.EndOfSectionIndex() ) )
        {
            // break the link of the corresponding section.
            // the link is also removed from the link manager
            SwSectionNode* pSectNode = pSectLnk->GetSectNode();
            assert(pSectNode);
            pSectNode->GetSection().BreakLink();

            // for robustness, because link is removed from the link manager
            if ( n > rLnks.size() )
            {
                n = rLnks.size();
            }
        }
    }
}

static void lcl_UpdateLinksInSect( const SwBaseLink& rUpdLnk, SwSectionNode& rSectNd )
{
    SwDoc& rDoc = rSectNd.GetDoc();
    SwDocShell* pDShell = rDoc.GetDocShell();
    if( !pDShell || !pDShell->GetMedium() )
        return ;

    const OUString sName( pDShell->GetMedium()->GetName() );
    const OUString sMimeType( SotExchange::GetFormatMimeType( SotClipboardFormatId::SIMPLE_FILE ));
    uno::Any aValue;
    aValue <<= sName; // Arbitrary name

    const ::sfx2::SvBaseLinks& rLnks = rDoc.getIDocumentLinksAdministration().GetLinkManager().GetLinks();
    forauto n = rLnks.size(); n; )
    {
        ::sfx2::SvBaseLink* pLnk = &(*rLnks[ --n ]);
        if( pLnk == &rUpdLnk )
            continue;
        if( sfx2::SvBaseLinkObjectType::ClientFile != pLnk->GetObjType() )
            continue;
        SwBaseLink* pBLink = dynamic_cast<SwBaseLink*>( pLnk );
        if( pBLink && pBLink->IsInRange( rSectNd.GetIndex(),
                                        rSectNd.EndOfSectionIndex() ) )
        {
            // It's in the Section, so update. But only if it's not in the same File!
            OUString sFName;
            sfx2::LinkManager::GetDisplayNames( pBLink, nullptr, &sFName );
            if( sFName != sName )
            {
                pBLink->DataChanged( sMimeType, aValue );

                // If needed find the Link pointer to avoid skipping one or calling one twice
                if( n >= rLnks.size() && 0 != ( n = rLnks.size() ))
                    --n;

                if( n && pLnk != &(*rLnks[ n ]) )
                {
                    // Find - it can only precede it!
                    while( n )
                        if( pLnk == &(*rLnks[ --n ] ) )
                            break;
                }
            }
        }
    }
}

::sfx2::SvBaseLink::UpdateResult SwIntrnlSectRefLink::DataChanged(
    const OUString& rMimeType, const uno::Any & rValue )
{
    SwSectionNode* pSectNd = m_rSectFormat.GetSectionNode();
    SwDoc& rDoc = m_rSectFormat.GetDoc();

    SotClipboardFormatId nDataFormat = SotExchange::GetFormatIdFromMimeType( rMimeType );

    if( !pSectNd || rDoc.IsInDtor() || ChkNoDataFlag() ||
        sfx2::LinkManager::RegisterStatusInfoId() == nDataFormat )
    {
        // Should we be in the Undo already?
        return SUCCESS;
    }

    //  #i38810# - Due to possible existing signatures, the
    // document has to be modified after updating a link.
    rDoc.getIDocumentState().SetModified();
    // set additional flag that links have been updated, in order to check this
    // during load.
    rDoc.getIDocumentLinksAdministration().SetLinksUpdated( true );

    // Always switch off Undo
    bool const bWasUndo = rDoc.GetIDocumentUndoRedo().DoesUndo();
    rDoc.GetIDocumentUndoRedo().DoUndo(false);
    bool bWasVisibleLinks = rDoc.getIDocumentLinksAdministration().IsVisibleLinks();
    rDoc.getIDocumentLinksAdministration().SetVisibleLinks( false );

    SwPaM* pPam;
    SwViewShell* pVSh = rDoc.getIDocumentLayoutAccess().GetCurrentViewShell();
    SwEditShell* pESh = rDoc.GetEditShell();
    rDoc.getIDocumentFieldsAccess().LockExpFields();
    {
        // Insert an empty TextNode at the Section's start
        SwNodeIndex aIdx( *pSectNd, +1 );
        SwNodeIndex aEndIdx( *pSectNd->EndOfSectionNode() );
        rDoc.GetNodes().MakeTextNode( aIdx.GetNode(),
                        rDoc.getIDocumentStylePoolAccess().GetTextCollFromPool( RES_POOLCOLL_TEXT ) );

        if( pESh )
            pESh->StartAllAction();
        else if( pVSh )
            pVSh->StartAction();

        SwPosition aPos( aIdx, SwNodeOffset(-1) );
        SwDoc::CorrAbs( aIdx, aEndIdx, aPos, true );

        pPam = new SwPaM( aPos );

        // Delete everything succeeding it
        --aIdx;
        DelFlyInRange( aIdx.GetNode(), aEndIdx.GetNode() );
        DelBookmarks(aIdx.GetNode(), aEndIdx.GetNode());
        ++aIdx;

        rDoc.GetNodes().Delete( aIdx, aEndIdx.GetIndex() - aIdx.GetIndex() );
    }

    SwSection& rSection = pSectNd->GetSection();
    rSection.SetConnectFlag(false);

    Reader* pRead = nullptr;
    switch( nDataFormat )
    {
    case SotClipboardFormatId::STRING:
        pRead = ReadAscii;
        break;

    case SotClipboardFormatId::RICHTEXT:
    case SotClipboardFormatId::RTF:
        pRead = SwReaderWriter::GetRtfReader();
        break;

    case SotClipboardFormatId::SIMPLE_FILE:
        if ( rValue.hasValue() )
        {
            OUString sFileName;
            if ( !(rValue >>= sFileName) )
                break;
            OUString sFilter;
            OUString sRange;
            sfx2::LinkManager::GetDisplayNames( this, nullptr, &sFileName,
                                                    &sRange, &sFilter );

            RedlineFlags eOldRedlineFlags = RedlineFlags::NONE;
            SfxObjectShellRef xDocSh;
            SfxObjectShellLock xLockRef;
            int nRet;
            if( sFileName.isEmpty() )
            {
                xDocSh = rDoc.GetDocShell();
                nRet = 1;
            }
            else
            {
                nRet = SwFindDocShell( xDocSh, xLockRef, sFileName,
                                    rSection.GetLinkFilePassword(),
                                    sFilter, 0, rDoc.GetDocShell(), {} );
                if( nRet )
                {
                    SwDoc* pSrcDoc = static_cast<SwDocShell*>( xDocSh.get() )->GetDoc();
                    eOldRedlineFlags = pSrcDoc->getIDocumentRedlineAccess().GetRedlineFlags();
                    pSrcDoc->getIDocumentRedlineAccess().SetRedlineFlags( RedlineFlags::ShowInsert );
                }
            }

            if( nRet )
            {
                rSection.SetConnectFlag();

                SwNodeIndex aSave( pPam->GetPoint()->GetNode(), -1 );
                std::optional<SwNodeRange> oCpyRg;

                if( xDocSh->GetMedium() &&
                    rSection.GetLinkFilePassword().isEmpty() )
                {
                    ifconst SfxStringItem* pItem = xDocSh->GetMedium()->GetItemSet().
                        GetItemIfSet( SID_PASSWORD, false ) )
                        rSection.SetLinkFilePassword( pItem->GetValue() );
                }

                SwDoc* pSrcDoc = static_cast<SwDocShell*>( xDocSh.get() )->GetDoc();

                if( !sRange.isEmpty() )
                {
                    // Catch recursion
                    bool bRecursion = false;
                    if( pSrcDoc == &rDoc )
                    {
                        tools::SvRef<SwServerObject> refObj( static_cast<SwServerObject*>(
                                        rDoc.getIDocumentLinksAdministration().CreateLinkSource( sRange )));
                        if( refObj.is() )
                        {
                            bRecursion = refObj->IsLinkInServer( this ) ||
                                        ChkNoDataFlag();
                        }
                    }

                    SwNode& rInsPos = pPam->GetPoint()->GetNode();

                    SwPaM* pCpyPam = nullptr;
                    if( !bRecursion &&
                        pSrcDoc->GetDocumentLinksAdministrationManager().SelectServerObj( sRange, pCpyPam, oCpyRg )
                        && pCpyPam )
                    {
                        if( pSrcDoc != &rDoc ||
                            pCpyPam->Start()->GetNode() > rInsPos ||
                            rInsPos >= pCpyPam->End()->GetNode() )
                        {
                            pSrcDoc->getIDocumentContentOperations().CopyRange(*pCpyPam, *pPam->GetPoint(), SwCopyFlags::CheckPosInFly);
                        }
                        delete pCpyPam;
                    }
                    if( oCpyRg && pSrcDoc == &rDoc &&
                        oCpyRg->aStart < rInsPos && rInsPos < oCpyRg->aEnd.GetNode() )
                    {
                        oCpyRg.reset();
                    }
                }
                else if( pSrcDoc != &rDoc )
                {
                    // before update, remove obsolete page-anchored flys from the target master document
                    auto pFormats = rDoc.GetSpzFrameFormats();
                    for( sal_uInt16 nCnt = pFormats->size(); nCnt; )
                    {
                        SwFrameFormat* pFormat = (*pFormats)[ --nCnt ];
                        SwFormatAnchor aAnchor( pFormat->GetAnchor() );
                        if ( RndStdIds::FLY_AT_PAGE == aAnchor.GetAnchorId() &&
                                pFormat->GetName().toString().indexOf(sFileName) > -1 )
                        {
                            rDoc.getIDocumentLayoutAccess().DelLayoutFormat( pFormat );
                        }
                    }

                    // store page count of the source document to calculate
                    // the physical page number of the objects anchored at page
                    const SwDocStat& rDStat = pSrcDoc->getIDocumentStatistics().GetDocStat();
                    m_rSectFormat.GetSection()->SetPageNum(rDStat.nPage);

                    // tdf#121119 keep objects anchored at page
                    auto pSrcFormats = pSrcDoc->GetSpzFrameFormats();
                    sal_uInt32 nPrevPages = 0;
                    for( sw::SpzFrameFormat* pCpyFormat: *pSrcFormats)
                    {
                        SwFormatAnchor aAnchor( pCpyFormat->GetAnchor() );
                        if ( RndStdIds::FLY_AT_PAGE == aAnchor.GetAnchorId() )
                        {
                            // add file name of the source document to the name of the copied object
                            // Note: used for the recognition of the copied objects anchored at page
                            pCpyFormat->SetFormatName( UIName(pCpyFormat->GetName().toString() + " (" + sFileName + ")") );

                            // sum page counts of the previous sections
                            if ( nPrevPages == 0 )
                            {
                                const SwSectionFormats& rFormats = rDoc.GetSections();
                                for( size_t n = 0; n < rFormats.size() && rFormats[n] != &m_rSectFormat; ++n )
                                {
                                    if ( const SwSection * pGlobalDocSection = rFormats[n]->GetGlobalDocSection() )
                                        nPrevPages += pGlobalDocSection->GetPageNum();
                                }
                            }

                            // set corrected physical page number of the object
                            aAnchor.SetPageNum( nPrevPages + aAnchor.GetPageNum() );

                            // copy object anchored at page to the target document
                            rDoc.getIDocumentLayoutAccess().CopyLayoutFormat( *pCpyFormat, aAnchor, truetrue );
                        }
                    }

                    oCpyRg.emplace( pSrcDoc->GetNodes().GetEndOfExtras(), SwNodeOffset(2),
                                          pSrcDoc->GetNodes().GetEndOfContent() );
                }

                // #i81653#
                // Update links of extern linked document or extern linked
                // document section, if section is protected.
                if ( pSrcDoc != &rDoc &&
                     rSection.IsProtectFlag() )
                {
                    pSrcDoc->getIDocumentLinksAdministration().GetLinkManager().UpdateAllLinks( falsefalse, nullptr, u""_ustr );
                }

                if( oCpyRg )
                {
                    SwNode& rInsPos = pPam->GetPoint()->GetNode();
                    bool bCreateFrame = rInsPos <= rDoc.GetNodes().GetEndOfExtras() ||
                                rInsPos.FindTableNode();

                    SwTableNumFormatMerge aTNFM( *pSrcDoc, rDoc );

                    pSrcDoc->GetDocumentContentOperationsManager().CopyWithFlyInFly(*oCpyRg, rInsPos, nullptr, bCreateFrame);
                    ++aSave;

                    if( !bCreateFrame )
                        ::MakeFrames( rDoc, aSave.GetNode(), rInsPos );

                    // Delete last Node, only if it was copied successfully
                    // (the Section contains more than one Node)
                    if( SwNodeOffset(2) < pSectNd->EndOfSectionIndex() - pSectNd->GetIndex() )
                    {
                        aSave = rInsPos;
                        pPam->Move( fnMoveBackward, GoInNode );
                        pPam->SetMark(); // Rewire both SwPositions

                        rDoc.CorrAbs( aSave.GetNode(), *pPam->GetPoint(), 0, true );
                        rDoc.GetNodes().Delete( aSave );
                    }
                    oCpyRg.reset();
                }

                lcl_BreakSectionLinksInSect( *pSectNd );

                // Update all Links in this Section
                lcl_UpdateLinksInSect( *this, *pSectNd );
            }
            if( xDocSh.is() )
            {
                if( 2 == nRet )
                    xDocSh->DoClose();
                else ifstatic_cast<SwDocShell*>( xDocSh.get() )->GetDoc() )
                    static_cast<SwDocShell*>( xDocSh.get() )->GetDoc()->getIDocumentRedlineAccess().SetRedlineFlags(
                                eOldRedlineFlags );
            }
        }
        break;
    defaultbreak;
    }

    // Only create DDE if Shell is available!
    uno::Sequence< sal_Int8 > aSeq;
    if( pRead && rValue.hasValue() && ( rValue >>= aSeq ) )
    {
        if( pESh )
        {
            pESh->Push();
            SwPaM* pCursor = pESh->GetCursor();
            *pCursor->GetPoint() = *pPam->GetPoint();
            delete pPam;
            pPam = pCursor;
        }

        if (SwDocShell* pShell = rDoc.GetDocShell())
        {
            SvMemoryStream aStrm( const_cast<sal_Int8 *>(aSeq.getConstArray()), aSeq.getLength(),
                                    StreamMode::READ );
            aStrm.Seek( 0 );

            // TODO/MBA: it's impossible to set a BaseURL here!
            SwReader aTmpReader( aStrm, OUString(), pShell->GetMedium()->GetBaseURL(), *pPam );

            if( ! aTmpReader.Read( *pRead ).IsError() )
            {
                rSection.SetConnectFlag();
            }
        }

        if( pESh )
        {
            pESh->Pop(SwCursorShell::PopMode::DeleteCurrent);
            pPam = nullptr; // pam was deleted earlier
        }
    }

    // remove all undo actions and turn undo on again
    rDoc.GetIDocumentUndoRedo().DelAllUndoObj();
    rDoc.GetIDocumentUndoRedo().DoUndo(bWasUndo);
    rDoc.getIDocumentLinksAdministration().SetVisibleLinks( bWasVisibleLinks );

    rDoc.getIDocumentFieldsAccess().UnlockExpFields();
    if( !rDoc.getIDocumentFieldsAccess().IsExpFieldsLocked() )
        rDoc.getIDocumentFieldsAccess().UpdateExpFields(nullptr, true);

    if( pESh )
        pESh->EndAllAction();
    else if( pVSh )
        pVSh->EndAction();
    delete pPam; // Was created at the start

    return SUCCESS;
}

void SwIntrnlSectRefLink::Closed()
{
    SwDoc& rDoc = m_rSectFormat.GetDoc();
    if( !rDoc.IsInDtor() )
    {
        // Advise says goodbye: mark the Section as not protected
        // and change the Flag
        const SwSectionFormats& rFormats = rDoc.GetSections();
        forauto n = rFormats.size(); n; )
            if (rFormats[--n] == &m_rSectFormat)
            {
                SwViewShell* pSh = rDoc.getIDocumentLayoutAccess().GetCurrentViewShell();
                SwEditShell* pESh = rDoc.GetEditShell();

                if( pESh )
                    pESh->StartAllAction();
                else
                    pSh->StartAction();

                SwSectionData aSectionData(*m_rSectFormat.GetSection());
                aSectionData.SetType( SectionType::Content );
                aSectionData.SetLinkFileName( OUString() );
                aSectionData.SetProtectFlag( false );
                // edit in readonly sections
                aSectionData.SetEditInReadonlyFlag( false );

                aSectionData.SetConnectFlag( false );

                rDoc.UpdateSection( n, aSectionData );

                // Make all Links within the Section visible again
                SwSectionNode* pSectNd = m_rSectFormat.GetSectionNode();
                if( pSectNd )
                    SwSection::MakeChildLinksVisible( *pSectNd );

                if( pESh )
                    pESh->EndAllAction();
                else
                    pSh->EndAction();
                break;
            }
    }
    SvBaseLink::Closed();
}

void SwSection::CreateLink( LinkCreateType eCreateType )
{
    SwSectionFormat* pFormat = GetFormat();
    OSL_ENSURE(pFormat, "SwSection::CreateLink: no format?");
    if (!pFormat || (SectionType::Content == m_Data.GetType()))
        return ;

    SfxLinkUpdateMode nUpdateType = SfxLinkUpdateMode::ALWAYS;

    if (!m_RefLink.is())
    {
        // create BaseLink
        m_RefLink = new SwIntrnlSectRefLink( *pFormat, nUpdateType );
    }
    else
    {
        pFormat->GetDoc().getIDocumentLinksAdministration().GetLinkManager().Remove( m_RefLink.get() );
    }

    SwIntrnlSectRefLink *const pLnk =
        static_cast<SwIntrnlSectRefLink*>( m_RefLink.get() );

    const OUString sCmd(m_Data.GetLinkFileName());
    pLnk->SetUpdateMode( nUpdateType );
    pLnk->SetVisible( pFormat->GetDoc().getIDocumentLinksAdministration().IsVisibleLinks() );

    switch (m_Data.GetType())
    {
    case SectionType::DdeLink:
        pLnk->SetLinkSourceName( sCmd );
        pFormat->GetDoc().getIDocumentLinksAdministration().GetLinkManager().InsertDDELink( pLnk );
        break;
    case SectionType::FileLink:
        {
            pLnk->SetContentType( SotClipboardFormatId::SIMPLE_FILE );
            sal_Int32 nIndex = 0;
            const OUString sFile(sCmd.getToken( 0, sfx2::cTokenSeparator, nIndex ));
            const OUString sFltr(sCmd.getToken( 0, sfx2::cTokenSeparator, nIndex ));
            const OUString sRange(sCmd.getToken( 0, sfx2::cTokenSeparator, nIndex ));
            pFormat->GetDoc().getIDocumentLinksAdministration().GetLinkManager().InsertFileLink( *pLnk,
                                static_cast<sfx2::SvBaseLinkObjectType>(m_Data.GetType()),
                                sFile,
                                ( !sFltr.isEmpty() ? &sFltr : nullptr ),
                                ( !sRange.isEmpty() ? &sRange : nullptr ) );
        }
        break;
    default:
        OSL_ENSURE( false"What kind of Link is this?" );
    }

    switch( eCreateType )
    {
    case LinkCreateType::Connect: // Connect Link right away
        pLnk->Connect();
        break;

    case LinkCreateType::Update: // Connect Link and update
        pLnk->Update();
        break;
    case LinkCreateType::NONE: break;
    }
}

void SwSection::BreakLink()
{
    const SectionType eCurrentType( GetType() );
    if ( eCurrentType == SectionType::Content ||
         eCurrentType == SectionType::ToxHeader ||
         eCurrentType == SectionType::ToxContent )
    {
        // nothing to do
        return;
    }

    // Release link, if it exists
    if (m_RefLink.is())
    {
        SwSectionFormat *const pFormat( GetFormat() );
        OSL_ENSURE(pFormat, "SwSection::BreakLink: no format?");
        if (pFormat)
        {
            pFormat->GetDoc().getIDocumentLinksAdministration().GetLinkManager().Remove( m_RefLink.get() );
        }
        m_RefLink.clear();
    }
    // change type
    SetType( SectionType::Content );
    // reset linked file data
    SetLinkFileName( OUString() );
    SetLinkFilePassword( OUString() );
}

void SwSection::dumpAsXml(xmlTextWriterPtr pWriter) const
{
    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwSection"));
    (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p"this);
    (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("registered-in"), "%p",
                                            GetRegisteredIn());
    m_Data.dumpAsXml(pWriter);
    (void)xmlTextWriterEndElement(pWriter);
}

const SwNode* SwIntrnlSectRefLink::GetAnchor() const { return m_rSectFormat.GetSectionNode(); }

bool SwIntrnlSectRefLink::IsInRange( SwNodeOffset nSttNd, SwNodeOffset nEndNd ) const
{
    SwStartNode* pSttNd = m_rSectFormat.GetSectionNode();
    return pSttNd &&
            nSttNd < pSttNd->GetIndex() &&
            pSttNd->EndOfSectionIndex() < nEndNd;
}

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

Messung V0.5
C=94 H=97 G=95

¤ Dauer der Verarbeitung: 0.20 Sekunden  ¤

*© 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.