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

Quelle  docdesc.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 <cmdid.h>
#include <init.hxx>
#include <editeng/lrspitem.hxx>
#include <editeng/ulspitem.hxx>
#include <editeng/paperinf.hxx>
#include <editeng/frmdiritem.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/dispatch.hxx>
#include <tools/globname.hxx>
#include <sal/log.hxx>
#include <osl/diagnose.h>
#include <unotools/localedatawrapper.hxx>
#include <fmtfsize.hxx>
#include <fmthdft.hxx>
#include <fmtcntnt.hxx>
#include <ftninfo.hxx>
#include <fesh.hxx>
#include <ndole.hxx>
#include <mdiexp.hxx>
#include <doc.hxx>
#include <IDocumentUndoRedo.hxx>
#include <IDocumentFieldsAccess.hxx>
#include <DocumentContentOperationsManager.hxx>
#include <IDocumentState.hxx>
#include <IDocumentLayoutAccess.hxx>
#include <rootfrm.hxx>
#include <poolfmt.hxx>
#include <docsh.hxx>
#include <ftnidx.hxx>
#include <fmtftn.hxx>
#include <txtftn.hxx>
#include <fldbas.hxx>
#include <strings.hrc>
#include <hints.hxx>
#include <SwUndoPageDesc.hxx>
#include <pagedeschint.hxx>
#include <tgrditem.hxx>
#include <comphelper/configuration.hxx>
#include <unotools/syslocale.hxx>
#include <svx/swframetypes.hxx>
#include <o3tl/unit_conversion.hxx>

#include <com/sun/star/embed/XEmbeddedObject.hpp>

using namespace com::sun::star;

static void lcl_DefaultPageFormat( sal_uInt16 nPoolFormatId,
                                SwFrameFormat &rFormat1,
                                SwFrameFormat &rFormat2,
                                SwFrameFormat &rFormat3,
                                SwFrameFormat &rFormat4)
{
    // --> #i41075# Printer on demand
    // This function does not require a printer anymore.
    // The default page size is obtained from the application
    //locale

    SwFormatFrameSize aFrameSize( SwFrameSize::Fixed );
    const Size aPhysSize = SvxPaperInfo::GetDefaultPaperSize();
    aFrameSize.SetSize( aPhysSize );

    // Prepare for default margins.
    // Margins have a default minimum size.
    // If the printer forces a larger margins, that's ok too.
    // The HTML page desc had A4 as page size always.
    // This has been changed to take the page size from the printer.
    // Unfortunately, the margins of the HTML page desc are smaller than
    // the margins used here in general, so one extra case is required.
    // In the long term, this needs to be changed to always keep the
    // margins from the page desc.
    sal_Int32 nMinTop, nMinBottom, nMinLeft, nMinRight;
    if( RES_POOLPAGE_HTML == nPoolFormatId )
    {
        nMinRight = nMinTop = nMinBottom = o3tl::toTwips(1, o3tl::Length::cm);
        nMinLeft = o3tl::toTwips(2, o3tl::Length::cm);
    }
    else if (!comphelper::IsFuzzing() && MeasurementSystem::Metric == SvtSysLocale().GetLocaleData().getMeasurementSystemEnum() )
    {
        nMinTop = nMinBottom = nMinLeft = nMinRight = o3tl::toTwips(2, o3tl::Length::cm);
    }
    else
    {
        nMinTop = nMinBottom = o3tl::toTwips(1, o3tl::Length::in);    // as in MS Word
        nMinLeft = nMinRight = o3tl::toTwips(1.25, o3tl::Length::in);
    }

    // set margins
    SvxLRSpaceItem aLR( RES_LR_SPACE );
    SvxULSpaceItem aUL( RES_UL_SPACE );

    aUL.SetUpper( o3tl::narrowing<sal_uInt16>(nMinTop) );
    aUL.SetLower( o3tl::narrowing<sal_uInt16>(nMinBottom) );
    aLR.SetRight(SvxIndentValue::twips(nMinRight));
    aLR.SetLeft(SvxIndentValue::twips(nMinLeft));

    rFormat1.SetFormatAttr( aFrameSize );
    rFormat1.SetFormatAttr( aLR );
    rFormat1.SetFormatAttr( aUL );

    rFormat2.SetFormatAttr( aFrameSize );
    rFormat2.SetFormatAttr( aLR );
    rFormat2.SetFormatAttr( aUL );

    rFormat3.SetFormatAttr( aFrameSize );
    rFormat3.SetFormatAttr( aLR );
    rFormat3.SetFormatAttr( aUL );

    rFormat4.SetFormatAttr( aFrameSize );
    rFormat4.SetFormatAttr( aLR );
    rFormat4.SetFormatAttr( aUL );
}

static void lcl_DescSetAttr( const SwFrameFormat &rSource, SwFrameFormat &rDest,
                         const bool bPage = true )
{
    // We should actually use ItemSet's Intersect here, but that doesn't work
    // correctly if we have different WhichRanges.

    // Take over the attributes which are of interest.
    sal_uInt16 const aIdArr[] = {
        RES_FRM_SIZE,                   RES_UL_SPACE,                   // [83..86
        RES_BACKGROUND,                 RES_SHADOW,                     // [99..101
        RES_COL,                        RES_COL,                        // [103
        RES_TEXTGRID,                   RES_TEXTGRID,                   // [109
        RES_FRAMEDIR,                   RES_FRAMEDIR,                   // [114
        RES_HEADER_FOOTER_EAT_SPACING,  RES_HEADER_FOOTER_EAT_SPACING,  // [115
        RES_BACKGROUND_FULL_SIZE,       RES_BACKGROUND_FULL_SIZE,       // [131
        RES_RTL_GUTTER,                 RES_RTL_GUTTER,                 // [132
        RES_UNKNOWNATR_CONTAINER,       RES_UNKNOWNATR_CONTAINER,       // [143

        // take over DrawingLayer FillStyles
        XATTR_FILL_FIRST,               XATTR_FILL_LAST,                // [1014

        0};

    const SfxPoolItem* pItem;
    for( sal_uInt16 n = 0; aIdArr[ n ]; n += 2 )
    {
        for( sal_uInt16 nId = aIdArr[ n ]; nId <= aIdArr[ n+1]; ++nId )
        {
            // #i45539#
            // bPage == true:
            // All in aIdArr except from RES_HEADER_FOOTER_EAT_SPACING
            // bPage == false:
            // All in aIdArr except from RES_COL and RES_PAPER_BIN:
            bool bExecuteId(true);

            if(bPage)
            {
                // When Page
                switch(nId)
                {
                    // All in aIdArr except from RES_HEADER_FOOTER_EAT_SPACING
                    case RES_HEADER_FOOTER_EAT_SPACING:
                    // take out SvxBrushItem; it's the result of the fallback
                    // at SwFormat::GetItemState and not really in state SfxItemState::SET
                    case RES_BACKGROUND:
                        bExecuteId = false;
                        break;
                    default:
                        break;
                }
            }
            else
            {
                // When not Page
                switch(nId)
                {
                    // When not Page: All in aIdArr except these:
                    case RES_COL:
                    case RES_PAPER_BIN:
                    case RES_BACKGROUND_FULL_SIZE:
                    case RES_RTL_GUTTER:
                        bExecuteId = false;
                        break;
                    default:
                        break;
                }
            }

            if(bExecuteId)
            {
                if (SfxItemState::SET == rSource.GetItemState(nId, false, &pItem))
                {
                    rDest.SetFormatAttr(*pItem);
                }
                else
                {
                    rDest.ResetFormatAttr(nId);
                }
            }
        }
    }

    // Transmit pool and help IDs too
    rDest.SetPoolFormatId( rSource.GetPoolFormatId() );
    rDest.SetPoolHelpId( rSource.GetPoolHelpId() );
    rDest.SetPoolHlpFileId( rSource.GetPoolHlpFileId() );
}

namespace
{
    SwFrameFormat& getFrameFormat(SwPageDesc &rDesc, bool bLeft, bool bFirst)
    {
        if (bFirst)
        {
            if (bLeft)
                return rDesc.GetFirstLeft();
            return rDesc.GetFirstMaster();
        }
        return rDesc.GetLeft();
    }

    const SwFrameFormat& getConstFrameFormat(const SwPageDesc &rDesc, bool bLeft, bool bFirst)
    {
        return getFrameFormat(const_cast<SwPageDesc&>(rDesc), bLeft, bFirst);
    }
}

void SwDoc::CopyMasterHeader(const SwPageDesc &rChged, const SwFormatHeader &rHead, SwPageDesc &rDesc, bool bLeft, bool bFirst)
{
    assert(bLeft || bFirst);
    SwFrameFormat& rDescFrameFormat = getFrameFormat(rDesc, bLeft, bFirst);
    if (bFirst && bLeft)
    {
        // special case: always shared with something
        rDescFrameFormat.SetFormatAttr( rChged.IsFirstShared()
                ? rDesc.GetLeft().GetHeader()
                : rDesc.GetFirstMaster().GetHeader());
    }
    else if ((bFirst ? rChged.IsFirstShared() : rChged.IsHeaderShared())
         || !rHead.IsActive())
    {
        // Left or first shares the header with the Master.
        rDescFrameFormat.SetFormatAttr( rDesc.GetMaster().GetHeader() );
    }
    else if ( rHead.IsActive() )
    {   // Left or first gets its own header if the Format doesn't already have one.
        // If it already has one and it points to the same Section as the
        // Right one, it needs to get an own Header.
        // The content is evidently copied.
        const SwFormatHeader &rFormatHead = rDescFrameFormat.GetHeader();
        if ( !rFormatHead.IsActive() )
        {
            SwFormatHeader aHead( getIDocumentLayoutAccess().MakeLayoutFormat( RndStdIds::HEADERL, nullptr ) );
            rDescFrameFormat.SetFormatAttr( aHead );
            // take over additional attributes (margins, borders ...)
            ::lcl_DescSetAttr( *rHead.GetHeaderFormat(), *aHead.GetHeaderFormat(), false);
        }
        else
        {
            const SwFormatContent &aCnt = rFormatHead.GetHeaderFormat()->GetContent();

            if (!aCnt.GetContentIdx())
            {
                const SwFrameFormat& rChgedFrameFormat = getConstFrameFormat(rChged, bLeft, bFirst);
                rDescFrameFormat.SetFormatAttr( rChgedFrameFormat.GetHeader() );
            }
            else
            {
                const SwFrameFormat *pRight = rHead.GetHeaderFormat();
                if (!pRight)
                    return;
                const SwFormatContent &aRCnt = pRight->GetContent();

                if ((*aRCnt.GetContentIdx() == *aCnt.GetContentIdx()) ||
                    // The ContentIdx is _always_ different when called from
                    // SwDocStyleSheet::SetItemSet, because it deep-copies the
                    // PageDesc.  So check if it was previously shared.
                     (bFirst ? rDesc.IsFirstShared() : rDesc.IsHeaderShared()))
                {
                    SwFrameFormat *pFormat = new SwFrameFormat( GetAttrPool(),
                            UIName(bFirst ? u"First header"_ustr : u"Left header"_ustr),
                                                    GetDfltFrameFormat() );
                    ::lcl_DescSetAttr( *pRight, *pFormat, false );
                    // The section which the right header attribute is pointing
                    // is copied, and the Index to the StartNode is set to
                    // the left or first header attribute.
                    SwStartNode* pSttNd = SwNodes::MakeEmptySection( GetNodes().GetEndOfAutotext(), SwHeaderStartNode );
                    SwNodeRange aRange( aRCnt.GetContentIdx()->GetNode(), SwNodeOffset(0),
                                *aRCnt.GetContentIdx()->GetNode().EndOfSectionNode() );
                    GetNodes().Copy_( aRange, *pSttNd->EndOfSectionNode(), false );
                    GetDocumentContentOperationsManager().CopyFlyInFlyImpl(aRange, nullptr, *pSttNd);
                    SwPaM const source(aRange.aStart, aRange.aEnd);
                    SwPosition dest(*pSttNd);
                    sw::CopyBookmarks(source, dest);
                    pFormat->SetFormatAttr( SwFormatContent( pSttNd ) );
                    rDescFrameFormat.SetFormatAttr( SwFormatHeader( pFormat ) );
                }
                else
                    ::lcl_DescSetAttr( *pRight,
                                   *const_cast<SwFrameFormat*>(rFormatHead.GetHeaderFormat()), false );
            }
        }
    }
}

void SwDoc::CopyMasterFooter(const SwPageDesc &rChged, const SwFormatFooter &rFoot, SwPageDesc &rDesc, bool bLeft, bool bFirst)
{
    assert(bLeft || bFirst);
    SwFrameFormat& rDescFrameFormat = getFrameFormat(rDesc, bLeft, bFirst);
    if (bFirst && bLeft)
    {
        // special case: always shared with something
        rDescFrameFormat.SetFormatAttr( rChged.IsFirstShared()
                ? rDesc.GetLeft().GetFooter()
                : rDesc.GetFirstMaster().GetFooter());
    }
    else if ((bFirst ? rChged.IsFirstShared() : rChged.IsFooterShared())
        || !rFoot.IsActive())
    {
        // Left or first shares the Header with the Master.
        rDescFrameFormat.SetFormatAttr( rDesc.GetMaster().GetFooter() );
    }
    else if ( rFoot.IsActive() )
    {   // Left or first gets its own Footer if the Format does not already have one.
        // If the Format already has a Footer and it points to the same section as the Right one,
        // it needs to get an own one.
        // The content is evidently copied.
        const SwFormatFooter &rFormatFoot = rDescFrameFormat.GetFooter();
        if ( !rFormatFoot.IsActive() )
        {
            SwFormatFooter aFoot( getIDocumentLayoutAccess().MakeLayoutFormat( RndStdIds::FOOTER, nullptr ) );
            rDescFrameFormat.SetFormatAttr( aFoot );
            // Take over additional attributes (margins, borders ...).
            ::lcl_DescSetAttr( *rFoot.GetFooterFormat(), *aFoot.GetFooterFormat(), false);
        }
        else
        {
            const SwFormatContent &aLCnt = rFormatFoot.GetFooterFormat()->GetContent();
            if( !aLCnt.GetContentIdx() )
            {
                const SwFrameFormat& rChgedFrameFormat = getConstFrameFormat(rChged, bLeft, bFirst);
                rDescFrameFormat.SetFormatAttr( rChgedFrameFormat.GetFooter() );
            }
            else
            {
                const SwFrameFormat *pRight = rFoot.GetFooterFormat();
                if (!pRight)
                    return;
                const SwFormatContent &aRCnt = pRight->GetContent();

                if ((*aRCnt.GetContentIdx() == *aLCnt.GetContentIdx()) ||
                    // The ContentIdx is _always_ different when called from
                    // SwDocStyleSheet::SetItemSet, because it deep-copies the
                    // PageDesc.  So check if it was previously shared.
                     (bFirst ? rDesc.IsFirstShared() : rDesc.IsFooterShared()))
                {
                    SwFrameFormat *pFormat = new SwFrameFormat( GetAttrPool(),
                            UIName(bFirst ? u"First footer"_ustr : u"Left footer"_ustr),
                                                    GetDfltFrameFormat() );
                    ::lcl_DescSetAttr( *pRight, *pFormat, false );
                    // The section to which the right footer attribute is pointing
                    // is copied, and the Index to the StartNode is set to
                    // the left footer attribute.
                    SwStartNode* pSttNd = SwNodes::MakeEmptySection( GetNodes().GetEndOfAutotext(), SwFooterStartNode );
                    SwNodeRange aRange( aRCnt.GetContentIdx()->GetNode(), SwNodeOffset(0),
                                *aRCnt.GetContentIdx()->GetNode().EndOfSectionNode() );
                    GetNodes().Copy_( aRange, *pSttNd->EndOfSectionNode(), false );
                    GetDocumentContentOperationsManager().CopyFlyInFlyImpl(aRange, nullptr, *pSttNd);
                    SwPaM const source(aRange.aStart, aRange.aEnd);
                    SwPosition dest(*pSttNd);
                    sw::CopyBookmarks(source, dest);
                    pFormat->SetFormatAttr( SwFormatContent( pSttNd ) );
                    rDescFrameFormat.SetFormatAttr( SwFormatFooter( pFormat ) );
                }
                else
                    ::lcl_DescSetAttr( *pRight,
                                   *const_cast<SwFrameFormat*>(rFormatFoot.GetFooterFormat()), false );
            }
        }
    }
}

void SwDoc::ChgPageDesc( size_t i, const SwPageDesc &rChged )
{
    assert(i < m_PageDescs.size() && "PageDescs is out of range.");

    SwPageDesc& rDesc = *m_PageDescs[i];
    SwRootFrame* pTmpRoot = getIDocumentLayoutAccess().GetCurrentLayout();

    if (GetIDocumentUndoRedo().DoesUndo())
    {
        // Stash header formats as needed.
        const SwFormatHeader& rLeftHead = rChged.GetLeft().GetHeader();
        const SwFormatHeader& rFirstMasterHead = rChged.GetFirstMaster().GetHeader();
        const SwFormatHeader& rFirstLeftHead = rChged.GetFirstLeft().GetHeader();
        const bool bStashLeftHead = !rDesc.IsHeaderShared() && rChged.IsHeaderShared();
        const bool bStashFirstMasterHead = !rDesc.IsFirstShared() && rChged.IsFirstShared();
        const bool bStashFirstLeftHead = (!rDesc.IsHeaderShared() && rChged.IsHeaderShared()) || (!rDesc.IsFirstShared() && rChged.IsFirstShared());
        if (bStashLeftHead && rLeftHead.GetRegisteredIn() && !rDesc.HasStashedFormat(truetruefalse))
            rDesc.StashFrameFormat(rChged.GetLeft(), truetruefalse);
        if (bStashFirstMasterHead && rFirstMasterHead.GetRegisteredIn() && !rDesc.HasStashedFormat(truefalsetrue))
            rDesc.StashFrameFormat(rChged.GetFirstMaster(), truefalsetrue);
        if (bStashFirstLeftHead && rFirstLeftHead.GetRegisteredIn() && !rDesc.HasStashedFormat(truetruetrue))
            rDesc.StashFrameFormat(rChged.GetFirstLeft(), truetruetrue);

        // Stash footer formats as needed.
        const SwFormatFooter& rLeftFoot = rChged.GetLeft().GetFooter();
        const SwFormatFooter& rFirstMasterFoot = rChged.GetFirstMaster().GetFooter();
        const SwFormatFooter& rFirstLeftFoot = rChged.GetFirstLeft().GetFooter();
        const bool bStashLeftFoot = !rDesc.IsFooterShared() && rChged.IsFooterShared();
        const bool bStashFirstMasterFoot = !rDesc.IsFirstShared() && rChged.IsFirstShared();
        const bool bStashFirstLeftFoot = (!rDesc.IsFooterShared() && rChged.IsFooterShared()) || (!rDesc.IsFirstShared() && rChged.IsFirstShared());
        if (bStashLeftFoot && rLeftFoot.GetRegisteredIn() && !rDesc.HasStashedFormat(falsetruefalse))
            rDesc.StashFrameFormat(rChged.GetLeft(), falsetruefalse);
        if (bStashFirstMasterFoot && rFirstMasterFoot.GetRegisteredIn()  && !rDesc.HasStashedFormat(falsefalsetrue))
            rDesc.StashFrameFormat(rChged.GetFirstMaster(), falsefalsetrue);
        if (bStashFirstLeftFoot && rFirstLeftFoot.GetRegisteredIn()  && !rDesc.HasStashedFormat(falsetruetrue))
            rDesc.StashFrameFormat(rChged.GetFirstLeft(), falsetruetrue);

        GetIDocumentUndoRedo().AppendUndo(std::make_unique<SwUndoPageDesc>(rDesc, rChged, *this));
    }
    else
    {
        SwUndoId nBeingUndone(SwUndoId::EMPTY);
        GetIDocumentUndoRedo().GetFirstRedoInfo(nullptr, &nBeingUndone);
        if (SwUndoId::HEADER_FOOTER == nBeingUndone || SwUndoId::INSERT_PAGE_NUMBER == nBeingUndone)
        {
            // The last format change is currently being undone. Remove header/footer and corresponding nodes.
            SwFormatHeader aDescMasterHeaderFormat = rDesc.GetMaster().GetFormatAttr(RES_HEADER);
            SwFormatHeader aDescLeftHeaderFormat = rDesc.GetLeft().GetFormatAttr(RES_HEADER);
            SwFormatHeader aDescFirstLeftHeaderFormat = rDesc.GetFirstLeft().GetFormatAttr(RES_HEADER);
            SwFormatFooter aDescMasterFooterFormat = rDesc.GetMaster().GetFormatAttr(RES_FOOTER);
            SwFormatFooter aDescLeftFooterFormat = rDesc.GetLeft().GetFormatAttr(RES_FOOTER);
            SwFormatFooter aDescFirstLeftFooterFormat = rDesc.GetFirstLeft().GetFormatAttr(RES_FOOTER);

            SwFormatHeader aChgedMasterHeaderFormat = rChged.GetMaster().GetFormatAttr(RES_HEADER);
            SwFormatHeader aChgedLeftHeaderFormat = rChged.GetLeft().GetFormatAttr(RES_HEADER);
            SwFormatHeader aChgedFirstLeftHeaderFormat = rChged.GetFirstLeft().GetFormatAttr(RES_HEADER);
            SwFormatFooter aChgedMasterFooterFormat = rChged.GetMaster().GetFormatAttr(RES_FOOTER);
            SwFormatFooter aChgedLeftFooterFormat = rChged.GetLeft().GetFormatAttr(RES_FOOTER);
            SwFormatFooter aChgedFirstLeftFooterFormat = rChged.GetFirstLeft().GetFormatAttr(RES_FOOTER);

            rDesc.GetMaster().ResetFormatAttr(RES_HEADER);
            rDesc.GetLeft().ResetFormatAttr(RES_HEADER);
            rDesc.GetFirstLeft().ResetFormatAttr(RES_HEADER);
            rDesc.GetMaster().ResetFormatAttr(RES_FOOTER);
            rDesc.GetLeft().ResetFormatAttr(RES_FOOTER);
            rDesc.GetFirstLeft().ResetFormatAttr(RES_FOOTER);

            auto lDelHFFormat = [this](sw::ClientBase<SwFrameFormat>* pToRemove, SwFrameFormat* pFormat)
            {
                // Code taken from lcl_DelHFFormat
                pFormat->Remove(*pToRemove);
                SwFormatContent& rCnt = const_cast<SwFormatContent&>(pFormat->GetContent());
                if (rCnt.GetContentIdx())
                {
                    SwNode* pNode = nullptr;
                    {
                        SwNodeIndex aIdx(*rCnt.GetContentIdx(), 0);
                        pNode = &aIdx.GetNode();
                        SwNodeOffset nEnd = pNode->EndOfSectionIndex();
                        while (aIdx < nEnd)
                        {
                            if (pNode->IsContentNode() &&
                                static_cast<SwContentNode*>(pNode)->HasWriterListeners())
                            {
                                SwCursorShell* pShell = SwIterator<SwCursorShell, SwContentNode>(*static_cast<SwContentNode*>(pNode)).First();
                                if (pShell)
                                {
                                    pShell->ParkCursor(aIdx.GetNode());
                                    aIdx = nEnd - 1;
                                }
                            }
                            ++aIdx;
                            pNode = &aIdx.GetNode();
                        }
                    }
                    rCnt.SetNewContentIdx(nullptr);

                    ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo());

                    assert(pNode);
                    getIDocumentContentOperations().DeleteSection(pNode);
                }
                delete pFormat;
            };

            if (aDescMasterHeaderFormat.GetHeaderFormat() && aDescMasterHeaderFormat != aChgedMasterHeaderFormat)
                lDelHFFormat(&aDescMasterHeaderFormat, aDescMasterHeaderFormat.GetHeaderFormat());
            else if (aDescLeftHeaderFormat.GetHeaderFormat() && aDescLeftHeaderFormat != aChgedLeftHeaderFormat)
                lDelHFFormat(&aDescLeftHeaderFormat, aDescLeftHeaderFormat.GetHeaderFormat());
            else if (aDescFirstLeftHeaderFormat.GetHeaderFormat() && aDescFirstLeftHeaderFormat != aChgedFirstLeftHeaderFormat)
                lDelHFFormat(&aDescFirstLeftHeaderFormat, aDescFirstLeftHeaderFormat.GetHeaderFormat());

            else if (aDescMasterFooterFormat.GetFooterFormat() && aDescMasterFooterFormat != aChgedMasterFooterFormat)
                lDelHFFormat(&aDescMasterFooterFormat, aDescMasterFooterFormat.GetFooterFormat());
            else if (aDescLeftFooterFormat.GetFooterFormat() && aDescLeftFooterFormat != aChgedLeftFooterFormat)
                lDelHFFormat(&aDescLeftFooterFormat, aDescLeftFooterFormat.GetFooterFormat());
            else if (aDescFirstLeftFooterFormat.GetFooterFormat() && aDescFirstLeftFooterFormat != aChgedFirstLeftFooterFormat)
                lDelHFFormat(&aDescFirstLeftFooterFormat, aDescFirstLeftFooterFormat.GetFooterFormat());

            // tdf#141613 FIXME: Disable redoing header/footer changes for now.
            // The proper solution would be to write a SwUndoHeaderFooter class
            // to represent the addition of a header or footer to the current page.
            GetIDocumentUndoRedo().ClearRedo();
        }
    }
    ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo());

    // Mirror at first if needed.
    if ( rChged.GetUseOn() == UseOnPage::Mirror )
        const_cast<SwPageDesc&>(rChged).Mirror();
    else
    {
        // Or else transfer values from Master to Left
        ::lcl_DescSetAttr(rChged.GetMaster(),
                   const_cast<SwPageDesc&>(rChged).GetLeft());
    }
    ::lcl_DescSetAttr(rChged.GetMaster(),
                   const_cast<SwPageDesc&>(rChged).GetFirstMaster());
    ::lcl_DescSetAttr(rChged.GetLeft(),
                   const_cast<SwPageDesc&>(rChged).GetFirstLeft());

    // Take over NumType.
    if( rChged.GetNumType().GetNumberingType() != rDesc.GetNumType().GetNumberingType() )
    {
        rDesc.SetNumType( rChged.GetNumType() );
        // Notify page number fields that NumFormat has changed
        getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::PageNumber )->UpdateFields();
        getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::RefPageGet )->UpdateFields();

        // If the numbering scheme has changed we could have QuoVadis/ErgoSum texts
        // that refer to a changed page, so we invalidate foot notes.
        SwFootnoteIdxs& rFootnoteIdxs = GetFootnoteIdxs();
        for( SwFootnoteIdxs::size_type nPos = 0; nPos < rFootnoteIdxs.size(); ++nPos )
        {
            SwTextFootnote *pTextFootnote = rFootnoteIdxs[ nPos ];
            const SwFormatFootnote &rFootnote = pTextFootnote->GetFootnote();
            pTextFootnote->SetNumber(rFootnote.GetNumber(), rFootnote.GetNumberRLHidden(), rFootnote.GetNumStr());
        }
    }

    // Take over orientation
    rDesc.SetLandscape( rChged.GetLandscape() );

    // Synch header.
    const SwFormatHeader& rMasterHead = rChged.GetMaster().GetHeader();
    rDesc.GetMaster().SetFormatAttr( rMasterHead );
    const bool bRestoreStashedLeftHead = rDesc.IsHeaderShared() && !rChged.IsHeaderShared();
    const bool bRestoreStashedFirstMasterHead = rDesc.IsFirstShared() && !rChged.IsFirstShared();
    const bool bRestoreStashedFirstLeftHead = (rDesc.IsHeaderShared() && !rChged.IsHeaderShared()) || (rDesc.IsFirstShared() && !rChged.IsFirstShared());
    const SwFrameFormat* pStashedLeftFormat = bRestoreStashedLeftHead ? rChged.GetStashedFrameFormat(truetruefalse) : nullptr;
    const SwFrameFormat* pStashedFirstMasterFormat = bRestoreStashedFirstMasterHead ? rChged.GetStashedFrameFormat(truefalsetrue) : nullptr;
    const SwFrameFormat* pStashedFirstLeftFormat = bRestoreStashedFirstLeftHead ? rChged.GetStashedFrameFormat(truetruetrue) : nullptr;
    CopyMasterHeader(rChged, pStashedLeftFormat ? pStashedLeftFormat->GetHeader() : rMasterHead, rDesc, truefalse); // Copy left header
    CopyMasterHeader(rChged, pStashedFirstMasterFormat ? pStashedFirstMasterFormat->GetHeader() : rMasterHead, rDesc, falsetrue); // Copy first master
    CopyMasterHeader(rChged, pStashedFirstLeftFormat ? pStashedFirstLeftFormat->GetHeader() : rMasterHead, rDesc, truetrue); // Copy first left

    if (pStashedLeftFormat)
        rDesc.RemoveStashedFormat(truetruefalse);

    if (pStashedFirstMasterFormat)
        rDesc.RemoveStashedFormat(truefalsetrue);

    if (pStashedFirstLeftFormat)
        rDesc.RemoveStashedFormat(truetruetrue);

    rDesc.ChgHeaderShare( rChged.IsHeaderShared() );

    // Synch Footer.
    const SwFormatFooter& rMasterFoot = rChged.GetMaster().GetFooter();
    rDesc.GetMaster().SetFormatAttr( rMasterFoot );
    const bool bRestoreStashedLeftFoot = rDesc.IsFooterShared() && !rChged.IsFooterShared();
    const bool bRestoreStashedFirstMasterFoot = rDesc.IsFirstShared() && !rChged.IsFirstShared();
    const bool bRestoreStashedFirstLeftFoot = (rDesc.IsFooterShared() && !rChged.IsFooterShared()) || (rDesc.IsFirstShared() && !rChged.IsFirstShared());
    const SwFrameFormat* pStashedLeftFoot = bRestoreStashedLeftFoot ? rChged.GetStashedFrameFormat(falsetruefalse) : nullptr;
    const SwFrameFormat* pStashedFirstMasterFoot = bRestoreStashedFirstMasterFoot ? rChged.GetStashedFrameFormat(falsefalsetrue) : nullptr;
    const SwFrameFormat* pStashedFirstLeftFoot = bRestoreStashedFirstLeftFoot ? rChged.GetStashedFrameFormat(falsetruetrue) : nullptr;
    CopyMasterFooter(rChged, pStashedLeftFoot ? pStashedLeftFoot->GetFooter() : rMasterFoot, rDesc, truefalse); // Copy left footer
    CopyMasterFooter(rChged, pStashedFirstMasterFoot ? pStashedFirstMasterFoot->GetFooter() : rMasterFoot, rDesc, falsetrue); // Copy first master
    CopyMasterFooter(rChged, pStashedFirstLeftFoot ? pStashedFirstLeftFoot->GetFooter() : rMasterFoot, rDesc, truetrue); // Copy first left

    if (pStashedLeftFoot)
        rDesc.RemoveStashedFormat(falsetruefalse);

    if (pStashedFirstMasterFoot)
        rDesc.RemoveStashedFormat(falsefalsetrue);

    if (pStashedFirstLeftFoot)
        rDesc.RemoveStashedFormat(falsetruetrue);

    rDesc.ChgFooterShare( rChged.IsFooterShared() );
    // there is just one first shared flag for both header and footer?
    rDesc.ChgFirstShare( rChged.IsFirstShared() );

    if ( rDesc.GetName() != rChged.GetName() )
        rDesc.SetName( rChged.GetName() );

    // A RegisterChange is triggered, if necessary
    rDesc.SetRegisterFormatColl( rChged.GetRegisterFormatColl() );

    // If UseOn or the Follow change, the paragraphs need to know about it.
    bool bUseOn  = false;
    bool bFollow = false;
    if (rDesc.GetUseOn() != rChged.GetUseOn())
    {
        rDesc.SetUseOn( rChged.GetUseOn() );
        bUseOn = true;
    }
    if (rDesc.GetFollow() != rChged.GetFollow())
    {
        if (rChged.GetFollow() == &rChged)
        {
            if (rDesc.GetFollow() != &rDesc)
            {
                rDesc.SetFollow( &rDesc );
                bFollow = true;
            }
        }
        else
        {
            rDesc.SetFollow( rChged.m_pFollow );
            bFollow = true;
        }
    }

    if ( (bUseOn || bFollow) && pTmpRoot)
        // Inform layout!
    {
        forauto aLayout : GetAllLayouts() )
            aLayout->AllCheckPageDescs();
    }

    // Take over the page attributes.
    ::lcl_DescSetAttr( rChged.GetMaster(), rDesc.GetMaster() );
    ::lcl_DescSetAttr( rChged.GetLeft(), rDesc.GetLeft() );
    ::lcl_DescSetAttr( rChged.GetFirstMaster(), rDesc.GetFirstMaster() );
    ::lcl_DescSetAttr( rChged.GetFirstLeft(), rDesc.GetFirstLeft() );

    // If the FootnoteInfo changes, the pages are triggered.
    if( !(rDesc.GetFootnoteInfo() == rChged.GetFootnoteInfo()) )
    {
        rDesc.SetFootnoteInfo( rChged.GetFootnoteInfo() );
        sw::PageFootnoteHint aHint;
        rDesc.GetMaster().CallSwClientNotify(aHint);
        rDesc.GetLeft().CallSwClientNotify(aHint);
        rDesc.GetFirstMaster().CallSwClientNotify(aHint);
        rDesc.GetFirstLeft().CallSwClientNotify(aHint);
    }
    getIDocumentState().SetModified();

    if (SwDocShell* pShell = GetDocShell())
    {
        if (SfxDispatcher* pDispatcher = pShell->GetDispatcher())
        {
            if (SfxBindings* pBindings = pDispatcher->GetBindings())
            {
                pBindings->Invalidate( SID_ATTR_PAGE_COLUMN );
                pBindings->Invalidate( SID_ATTR_PAGE );
                pBindings->Invalidate( SID_ATTR_PAGE_SIZE );
                pBindings->Invalidate( SID_ATTR_PAGE_ULSPACE );
                pBindings->Invalidate( SID_ATTR_PAGE_LRSPACE );
                pBindings->Invalidate(SID_ATTR_PAGE_FILLSTYLE);
                pBindings->Invalidate(SID_ATTR_PAGE_COLOR);
                pBindings->Invalidate(SID_ATTR_PAGE_GRADIENT);
                pBindings->Invalidate(SID_ATTR_PAGE_HATCH);
                pBindings->Invalidate(SID_ATTR_PAGE_BITMAP);
            }
        }
    }

    //h/f of first-left page must not be unique but same as first master or left
    assert((rDesc.IsFirstShared())
        ? rDesc.GetFirstLeft().GetHeader().GetHeaderFormat() == rDesc.GetLeft().GetHeader().GetHeaderFormat()
        : rDesc.GetFirstLeft().GetHeader().GetHeaderFormat() == rDesc.GetFirstMaster().GetHeader().GetHeaderFormat());
    assert((rDesc.IsFirstShared())
        ? rDesc.GetFirstLeft().GetFooter().GetFooterFormat() == rDesc.GetLeft().GetFooter().GetFooterFormat()
        : rDesc.GetFirstLeft().GetFooter().GetFooterFormat() == rDesc.GetFirstMaster().GetFooter().GetFooterFormat());
}

/// All descriptors whose Follow point to the to-be-deleted have to be adapted.
// #i7983#
void SwDoc::PreDelPageDesc(SwPageDesc const * pDel)
{
    if (nullptr == pDel)
        return;

    // mba: test iteration as clients are removed while iteration
    SwPageDescHint aHint( m_PageDescs[0] );
    pDel->CallSwClientNotify( aHint );

    bool bHasLayout = getIDocumentLayoutAccess().HasLayout();
    if ( mpFootnoteInfo->DependsOn( pDel ) )
    {
        mpFootnoteInfo->ChgPageDesc( m_PageDescs[0] );
        if ( bHasLayout )
        {
            forauto aLayout : GetAllLayouts() )
                aLayout->CheckFootnotePageDescs(false);
        }
    }
    else if ( mpEndNoteInfo->DependsOn( pDel ) )
    {
        mpEndNoteInfo->ChgPageDesc( m_PageDescs[0] );
        if ( bHasLayout )
        {
            forauto aLayout : GetAllLayouts() )
                aLayout->CheckFootnotePageDescs(true);
        }
    }

    for (SwPageDesc* pPageDesc : m_PageDescs)
    {
        if (pPageDesc->GetFollow() == pDel)
        {
            pPageDesc->SetFollow(nullptr);
            if( bHasLayout )
            {
                forauto aLayout : GetAllLayouts() )
                    aLayout->AllCheckPageDescs();
            }
        }
    }
}

void SwDoc::BroadcastStyleOperation(const UIName& rName, SfxStyleFamily eFamily,
                                    SfxHintId nOp)
{
    if (mpDocShell)
    {
        SfxStyleSheetBasePool * pPool = mpDocShell->GetStyleSheetPool();

        if (pPool)
        {
            SfxStyleSheetBase* pBase = pPool->Find(rName.toString(), eFamily);

            if (pBase != nullptr)
                pPool->Broadcast(SfxStyleSheetHint( nOp, *pBase ));
        }
    }
}

void SwDoc::DelPageDesc( size_t i, bool bBroadcast )
{
    OSL_ENSURE(i < m_PageDescs.size(), "PageDescs is out of range.");
    OSL_ENSURE( i != 0, "You cannot delete the default Pagedesc.");
    if ( i == 0 )
        return;

    SwPageDesc &rDel = *m_PageDescs[i];

    if (bBroadcast)
        BroadcastStyleOperation(rDel.GetName(), SfxStyleFamily::Page,
                                SfxHintId::StyleSheetErased);

    if (GetIDocumentUndoRedo().DoesUndo())
    {
        GetIDocumentUndoRedo().AppendUndo(
            std::make_unique<SwUndoPageDescDelete>(rDel, *this));
    }

    PreDelPageDesc(&rDel); // #i7983#

    m_PageDescs.erase(m_PageDescs.begin() + i);
    getIDocumentState().SetModified();
}

SwPageDesc* SwDoc::MakePageDesc(const UIName &rName, const SwPageDesc *pCpy,
                            bool bRegardLanguage)
{
    SwPageDesc *pNew;
    if( pCpy )
    {
        pNew = new SwPageDesc( *pCpy );
        pNew->SetName( rName );
        if( rName != pCpy->GetName() )
        {
            pNew->SetPoolFormatId( USHRT_MAX );
            pNew->SetPoolHelpId( USHRT_MAX );
            pNew->SetPoolHlpFileId( UCHAR_MAX );
        }
    }
    else
    {
        pNew = new SwPageDesc( rName, GetDfltFrameFormat(), *this );
        // Set the default page format.
        lcl_DefaultPageFormat( USHRT_MAX, pNew->GetMaster(), pNew->GetLeft(), pNew->GetFirstMaster(), pNew->GetFirstLeft() );

        SvxFrameDirection aFrameDirection = bRegardLanguage ?
            GetDefaultFrameDirection(GetAppLanguage())
            : SvxFrameDirection::Horizontal_LR_TB;

        pNew->GetMaster().SetFormatAttr( SvxFrameDirectionItem(aFrameDirection, RES_FRAMEDIR) );
        pNew->GetLeft().SetFormatAttr( SvxFrameDirectionItem(aFrameDirection, RES_FRAMEDIR) );
        pNew->GetFirstMaster().SetFormatAttr( SvxFrameDirectionItem(aFrameDirection, RES_FRAMEDIR) );
        pNew->GetFirstLeft().SetFormatAttr( SvxFrameDirectionItem(aFrameDirection, RES_FRAMEDIR) );
    }

    std::pair<SwPageDescs::const_iterator, bool> res = m_PageDescs.push_back( pNew );
    SAL_WARN_IF(!res.second, "sw""MakePageDesc called with existing name" );

    if (GetIDocumentUndoRedo().DoesUndo())
    {
        GetIDocumentUndoRedo().AppendUndo(std::make_unique<SwUndoPageDescCreate>(pNew, *this));
    }

    getIDocumentState().SetModified();
    return pNew;
}

void SwDoc::PrtOLENotify( bool bAll )
{
    SwFEShell *pShell = nullptr;
    {
        SwViewShell *pSh = getIDocumentLayoutAccess().GetCurrentViewShell();
        if ( pSh )
        {
            for(SwViewShell& rShell : pSh->GetRingContainer())
            {
                if(auto pFEShell = dynamic_cast<SwFEShell*>( &rShell))
                {
                    pShell = pFEShell;
                    break;
                }
            }
        }
    }
    if ( !pShell )
    {
        // This doesn't make sense without a Shell and thus without a client, because
        // the communication about size changes is implemented by these components.
        // Because we don't have a Shell we remember this unfortunate situation
        // in the document,
        // which is made up for later on when creating the first Shell.
        mbOLEPrtNotifyPending = true;
        if ( bAll )
            mbAllOLENotify = true;
    }
    else
    {
        if ( mbAllOLENotify )
            bAll = true;

        mbOLEPrtNotifyPending = mbAllOLENotify = false;

        std::unique_ptr<SwOLENodes> pNodes = SwContentNode::CreateOLENodesArray( *GetDfltGrfFormatColl(), !bAll );
        if ( pNodes )
        {
            ::StartProgress( STR_STATSTR_SWGPRTOLENOTIFY,
                             0, pNodes->size(), GetDocShell());
            getIDocumentLayoutAccess().GetCurrentLayout()->StartAllAction();

            for( SwOLENodes::size_type i = 0; i < pNodes->size(); ++i )
            {
                ::SetProgressState( i, GetDocShell() );

                SwOLENode* pOLENd = (*pNodes)[i];
                pOLENd->SetOLESizeInvalid( false );

                // At first load the Infos and see if it's not already in the exclude list.
                SvGlobalName aName;

                svt::EmbeddedObjectRef& xObj = pOLENd->GetOLEObj().GetObject();
                if ( xObj.is() )
                    aName = SvGlobalName( xObj->getClassID() );
                else  // Not yet loaded
                {
                        // TODO/LATER: retrieve ClassID of an unloaded object
                        // aName = ????
                }

                bool bFound = false;
                for ( std::vector<SvGlobalName>::size_type j = 0;
                      j < pGlobalOLEExcludeList->size() && !bFound;
                      ++j )
                {
                    bFound = (*pGlobalOLEExcludeList)[j] == aName;
                }
                if ( bFound )
                    continue;

                // We don't know it, so the object has to be loaded.
                // If it doesn't want to be informed
                if ( xObj.is() )
                {
                    pGlobalOLEExcludeList->push_back( aName );
                }
            }
            pNodes.reset();
            getIDocumentLayoutAccess().GetCurrentLayout()->EndAllAction();
            ::EndProgress( GetDocShell() );
        }
    }
}

IMPL_LINK_NOARG( SwDoc, DoUpdateModifiedOLE, Timer *, void )
{
    SwFEShell* pSh = static_cast<SwFEShell*>(GetEditShell());
    if (!pSh)
        return;

    mbOLEPrtNotifyPending = mbAllOLENotify = false;

    std::unique_ptr<SwOLENodes> pNodes = SwContentNode::CreateOLENodesArray( *GetDfltGrfFormatColl(), true );
    if( !pNodes )
        return;

    ::StartProgress( STR_STATSTR_SWGPRTOLENOTIFY,
                     0, pNodes->size(), GetDocShell());
    getIDocumentLayoutAccess().GetCurrentLayout()->StartAllAction();
    SwUpdateAttr aHint(0,0,0);
    for( SwOLENodes::size_type i = 0; i < pNodes->size(); ++i )
    {
        ::SetProgressState( i, GetDocShell() );

        SwOLENode* pOLENd = (*pNodes)[i];
        pOLENd->SetOLESizeInvalid( false );

        // We don't know it, so the object has to be loaded.
        // If it doesn't want to be informed
        if( pOLENd->GetOLEObj().GetOleRef().is() ) // Broken?
        {
            pOLENd->UpdateAttr(aHint);
        }
    }
    getIDocumentLayoutAccess().GetCurrentLayout()->EndAllAction();
    ::EndProgress( GetDocShell() );
}

static SwPageDesc* lcl_FindPageDesc( const SwPageDescs *pPageDescs,
                                     size_t *pPos, const UIName &rName )
{
    SwPageDesc* res = nullptr;
    SwPageDescs::const_iterator it = pPageDescs->find( rName );
    if( it != pPageDescs->end() )
    {
        res = *it;
        if( pPos )
            *pPos = std::distance( pPageDescs->begin(), it );
    }
    else if( pPos )
        *pPos = SIZE_MAX;
    return res;
}

SwPageDesc* SwDoc::FindPageDesc( const UIName & rName, size_t* pPos ) const
{
    return lcl_FindPageDesc( &m_PageDescs, pPos, rName );
}

bool SwDoc::ContainsPageDesc( const SwPageDesc *pDesc, size_t* pPos ) const
{
    if( pDesc == nullptr )
        return false;
    if( !m_PageDescs.contains( const_cast <SwPageDesc*>( pDesc ) ) ) {
        if( pPos )
            *pPos = SIZE_MAX;
        return false;
    }
    if( ! pPos )
        return true;

    SwPageDesc* desc = lcl_FindPageDesc(
        &m_PageDescs, pPos, pDesc->GetName() );
    SAL_WARN_IF( desc != pDesc, "sw""SwPageDescs container is broken!" );
    return true;
}

void SwDoc::DelPageDesc( const UIName & rName, bool bBroadcast )
{
    size_t nI;

    if (FindPageDesc(rName, &nI))
        DelPageDesc(nI, bBroadcast);
}

void SwDoc::ChgPageDesc( const UIName & rName, const SwPageDesc & rDesc)
{
    size_t nI;

    if (FindPageDesc(rName, &nI))
        ChgPageDesc(nI, rDesc);
}

/*
 * The HTML import cannot resist changing the page descriptions, I don't
 * know why. This function is meant to check the page descriptors for invalid
 * values.
 */

void SwDoc::CheckDefaultPageFormat()
{
    for ( size_t i = 0; i < GetPageDescCnt(); ++i )
    {
        SwPageDesc& rDesc = GetPageDesc( i );

        SwFrameFormat& rMaster = rDesc.GetMaster();
        SwFrameFormat& rLeft   = rDesc.GetLeft();

        const SwFormatFrameSize& rMasterSize  = rMaster.GetFrameSize();
        const SwFormatFrameSize& rLeftSize    = rLeft.GetFrameSize();

        const bool bSetSize = INVALID_TWIPS == rMasterSize.GetWidth() ||
                              INVALID_TWIPS == rMasterSize.GetHeight() ||
                              INVALID_TWIPS == rLeftSize.GetWidth() ||
                              INVALID_TWIPS == rLeftSize.GetHeight();

        if ( bSetSize )
            lcl_DefaultPageFormat( rDesc.GetPoolFormatId(), rDesc.GetMaster(), rDesc.GetLeft(), rDesc.GetFirstMaster(), rDesc.GetFirstLeft() );
    }
}

void SwDoc::SetDefaultPageMode(bool bSquaredPageMode)
{
    if( !bSquaredPageMode == !IsSquaredPageMode() )
        return;

    const SwTextGridItem& rGrid = GetDefault( RES_TEXTGRID );
    SwTextGridItem aNewGrid = rGrid;
    aNewGrid.SetSquaredMode(bSquaredPageMode);
    aNewGrid.Init();
    SetDefault(aNewGrid);

    for ( size_t i = 0; i < GetPageDescCnt(); ++i )
    {
        SwPageDesc& rDesc = GetPageDesc( i );

        SwFrameFormat& rMaster = rDesc.GetMaster();
        SwFrameFormat& rLeft = rDesc.GetLeft();

        SwTextGridItem aGrid(rMaster.GetFormatAttr(RES_TEXTGRID));
        aGrid.SwitchPaperMode( bSquaredPageMode );
        rMaster.SetFormatAttr(aGrid);
        rLeft.SetFormatAttr(aGrid);
    }
}

bool SwDoc::IsSquaredPageMode() const
{
    const SwTextGridItem& rGrid = GetDefault( RES_TEXTGRID );
    return rGrid.IsSquaredMode();
}

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

Messung V0.5
C=89 H=94 G=91

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

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

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.