From 940b4d1848e8c70ab7642901a68594e8016caffc Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 27 Apr 2024 18:51:28 +0200 Subject: Adding upstream version 1:7.0.4. Signed-off-by: Daniel Baumann --- sw/source/core/layout/atrfrm.cxx | 3656 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 3656 insertions(+) create mode 100644 sw/source/core/layout/atrfrm.cxx (limited to 'sw/source/core/layout/atrfrm.cxx') diff --git a/sw/source/core/layout/atrfrm.cxx b/sw/source/core/layout/atrfrm.cxx new file mode 100644 index 000000000..d9f37a669 --- /dev/null +++ b/sw/source/core/layout/atrfrm.cxx @@ -0,0 +1,3656 @@ +/* -*- 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +using namespace ::com::sun::star; + + +namespace sw { + +bool GetAtPageRelOrientation(sal_Int16 & rOrientation, bool const isIgnorePrintArea) +{ + switch (rOrientation) + { + case text::RelOrientation::CHAR: + case text::RelOrientation::FRAME: + rOrientation = text::RelOrientation::PAGE_FRAME; + return true; + case text::RelOrientation::PRINT_AREA: + if (isIgnorePrintArea) + { + return false; + } + else + { + rOrientation = text::RelOrientation::PAGE_PRINT_AREA; + return true; + } + case text::RelOrientation::FRAME_LEFT: + rOrientation = text::RelOrientation::PAGE_LEFT; + return true; + case text::RelOrientation::FRAME_RIGHT: + rOrientation = text::RelOrientation::PAGE_RIGHT; + return true; + default: + return false; + } +} + +} // namespace sw + +SfxPoolItem* SwFormatLineNumber::CreateDefault() { return new SwFormatLineNumber; } + +static sal_Int16 lcl_IntToRelation(const uno::Any& rVal) +{ + sal_Int16 nVal = text::RelOrientation::FRAME; + if (!(rVal >>= nVal)) + SAL_WARN("sw.core", "lcl_IntToRelation: read from Any failed!"); + return nVal; +} + +static void lcl_DelHFFormat( SwClient *pToRemove, SwFrameFormat *pFormat ) +{ + //If the client is the last one who uses this format, then we have to delete + //it - before this is done, we may need to delete the content-section. + SwDoc* pDoc = pFormat->GetDoc(); + pFormat->Remove( pToRemove ); + if( pDoc->IsInDtor() ) + { + delete pFormat; + return; + } + + // Anything other than frames registered? + bool bDel = true; + { + // nested scope because DTOR of SwClientIter resets the flag bTreeChg. + // It's suboptimal if the format is deleted beforehand. + SwIterator aIter(*pFormat); + for(SwClient* pLast = aIter.First(); bDel && pLast; pLast = aIter.Next()) + if (dynamic_cast(pLast) == nullptr) + bDel = false; + } + + if ( bDel ) + { + // If there is a Cursor registered in one of the nodes, we need to call the + // ParkCursor in an (arbitrary) shell. + SwFormatContent& rCnt = const_cast(pFormat->GetContent()); + if ( rCnt.GetContentIdx() ) + { + SwNode *pNode = nullptr; + { + // #i92993# + // Begin with start node of page header/footer to assure that + // complete content is checked for cursors and the complete content + // is deleted on below made method call getIDocumentContentOperations().DeleteSection(pNode)> + SwNodeIndex aIdx( *rCnt.GetContentIdx(), 0 ); + // If there is a Cursor registered in one of the nodes, we need to call the + // ParkCursor in an (arbitrary) shell. + pNode = & aIdx.GetNode(); + sal_uInt32 nEnd = pNode->EndOfSectionIndex(); + while ( aIdx < nEnd ) + { + if ( pNode->IsContentNode() && + static_cast(pNode)->HasWriterListeners() ) + { + SwCursorShell *pShell = SwIterator( *static_cast(pNode) ).First(); + if( pShell ) + { + pShell->ParkCursor( aIdx ); + aIdx = nEnd-1; + } + } + ++aIdx; + pNode = & aIdx.GetNode(); + } + } + rCnt.SetNewContentIdx( nullptr ); + + // When deleting a header/footer-format, we ALWAYS need to disable + // the undo function (Bug 31069) + ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo()); + + OSL_ENSURE( pNode, "A big problem." ); + pDoc->getIDocumentContentOperations().DeleteSection( pNode ); + } + delete pFormat; + } +} + +void SwFormatFrameSize::ScaleMetrics(long lMult, long lDiv) { + // Don't inherit the SvxSizeItem override (might or might not be relevant; added "just in case" + // when changing SwFormatFrameSize to derive from SvxSizeItem instead of directly from + // SfxPoolItem): + return SfxPoolItem::ScaleMetrics(lMult, lDiv); +} + +bool SwFormatFrameSize::HasMetrics() const { + // Don't inherit the SvxSizeItem override (might or might not be relevant; added "just in case" + // when changing SwFormatFrameSize to derive from SvxSizeItem instead of directly from + // SfxPoolItem): + return SfxPoolItem::HasMetrics(); +} + +// Partially implemented inline in hxx +SwFormatFrameSize::SwFormatFrameSize( SwFrameSize eSize, SwTwips nWidth, SwTwips nHeight ) + : SvxSizeItem( RES_FRM_SIZE, {nWidth, nHeight} ), + m_eFrameHeightType( eSize ), + m_eFrameWidthType( SwFrameSize::Fixed ) +{ + m_nWidthPercent = m_eWidthPercentRelation = m_nHeightPercent = m_eHeightPercentRelation = 0; +} + +bool SwFormatFrameSize::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + return( m_eFrameHeightType == static_cast(rAttr).m_eFrameHeightType && + m_eFrameWidthType == static_cast(rAttr).m_eFrameWidthType && + SvxSizeItem::operator==(rAttr)&& + m_nWidthPercent == static_cast(rAttr).GetWidthPercent() && + m_eWidthPercentRelation == static_cast(rAttr).GetWidthPercentRelation() && + m_nHeightPercent == static_cast(rAttr).GetHeightPercent() && + m_eHeightPercentRelation == static_cast(rAttr).GetHeightPercentRelation() ); +} + +SwFormatFrameSize* SwFormatFrameSize::Clone( SfxItemPool* ) const +{ + return new SwFormatFrameSize( *this ); +} + +bool SwFormatFrameSize::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + // here we convert always! + nMemberId &= ~CONVERT_TWIPS; + switch ( nMemberId ) + { + case MID_FRMSIZE_SIZE: + { + awt::Size aTmp; + aTmp.Height = convertTwipToMm100(GetHeight()); + aTmp.Width = convertTwipToMm100(GetWidth()); + rVal <<= aTmp; + } + break; + case MID_FRMSIZE_REL_HEIGHT: + rVal <<= static_cast(GetHeightPercent() != SwFormatFrameSize::SYNCED ? GetHeightPercent() : 0); + break; + case MID_FRMSIZE_REL_HEIGHT_RELATION: + rVal <<= GetHeightPercentRelation(); + break; + case MID_FRMSIZE_REL_WIDTH: + rVal <<= static_cast(GetWidthPercent() != SwFormatFrameSize::SYNCED ? GetWidthPercent() : 0); + break; + case MID_FRMSIZE_REL_WIDTH_RELATION: + rVal <<= GetWidthPercentRelation(); + break; + case MID_FRMSIZE_IS_SYNC_HEIGHT_TO_WIDTH: + rVal <<= SwFormatFrameSize::SYNCED == GetHeightPercent(); + break; + case MID_FRMSIZE_IS_SYNC_WIDTH_TO_HEIGHT: + rVal <<= SwFormatFrameSize::SYNCED == GetWidthPercent(); + break; + case MID_FRMSIZE_WIDTH : + rVal <<= static_cast(convertTwipToMm100(GetWidth())); + break; + case MID_FRMSIZE_HEIGHT: + // #95848# returned size should never be zero. + // (there was a bug that allowed for setting height to 0. + // Thus there some documents existing with that not allowed + // attribute value which may cause problems on import.) + rVal <<= static_cast(convertTwipToMm100(GetHeight() < MINLAY ? MINLAY : GetHeight() )); + break; + case MID_FRMSIZE_SIZE_TYPE: + rVal <<= static_cast(GetHeightSizeType()); + break; + case MID_FRMSIZE_IS_AUTO_HEIGHT: + rVal <<= SwFrameSize::Fixed != GetHeightSizeType(); + break; + case MID_FRMSIZE_WIDTH_TYPE: + rVal <<= static_cast(GetWidthSizeType()); + break; + } + return true; +} + +bool SwFormatFrameSize::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + bool bConvert = 0 != (nMemberId&CONVERT_TWIPS); + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_FRMSIZE_SIZE: + { + awt::Size aVal; + if(!(rVal >>= aVal)) + bRet = false; + else + { + Size aTmp(aVal.Width, aVal.Height); + if(bConvert) + { + aTmp.setHeight( convertMm100ToTwip(aTmp.Height()) ); + aTmp.setWidth( convertMm100ToTwip(aTmp.Width()) ); + } + SetSize(aTmp); + } + } + break; + case MID_FRMSIZE_REL_HEIGHT: + { + sal_Int16 nSet = 0; + rVal >>= nSet; + if(nSet >= 0 && nSet < SwFormatFrameSize::SYNCED) + SetHeightPercent(static_cast(nSet)); + else + bRet = false; + } + break; + case MID_FRMSIZE_REL_HEIGHT_RELATION: + { + sal_Int16 eSet = 0; + rVal >>= eSet; + SetHeightPercentRelation(eSet); + } + break; + case MID_FRMSIZE_REL_WIDTH: + { + sal_Int16 nSet = 0; + rVal >>= nSet; + if(nSet >= 0 && nSet < SwFormatFrameSize::SYNCED) + SetWidthPercent(static_cast(nSet)); + else + bRet = false; + } + break; + case MID_FRMSIZE_REL_WIDTH_RELATION: + { + sal_Int16 eSet = 0; + rVal >>= eSet; + SetWidthPercentRelation(eSet); + } + break; + case MID_FRMSIZE_IS_SYNC_HEIGHT_TO_WIDTH: + { + bool bSet = *o3tl::doAccess(rVal); + if(bSet) + SetHeightPercent(SwFormatFrameSize::SYNCED); + else if( SwFormatFrameSize::SYNCED == GetHeightPercent() ) + SetHeightPercent( 0 ); + } + break; + case MID_FRMSIZE_IS_SYNC_WIDTH_TO_HEIGHT: + { + bool bSet = *o3tl::doAccess(rVal); + if(bSet) + SetWidthPercent(SwFormatFrameSize::SYNCED); + else if( SwFormatFrameSize::SYNCED == GetWidthPercent() ) + SetWidthPercent(0); + } + break; + case MID_FRMSIZE_WIDTH : + { + sal_Int32 nWd = 0; + if(rVal >>= nWd) + { + if(bConvert) + nWd = convertMm100ToTwip(nWd); + if(nWd < MINLAY) + nWd = MINLAY; + SetWidth(nWd); + } + else + bRet = false; + } + break; + case MID_FRMSIZE_HEIGHT: + { + sal_Int32 nHg = 0; + if(rVal >>= nHg) + { + if(bConvert) + nHg = convertMm100ToTwip(nHg); + if(nHg < MINLAY) + nHg = MINLAY; + SetHeight(nHg); + } + else + bRet = false; + } + break; + case MID_FRMSIZE_SIZE_TYPE: + { + sal_Int16 nType = 0; + if((rVal >>= nType) && nType >= 0 && nType <= static_cast(SwFrameSize::Minimum) ) + { + SetHeightSizeType(static_cast(nType)); + } + else + bRet = false; + } + break; + case MID_FRMSIZE_IS_AUTO_HEIGHT: + { + bool bSet = *o3tl::doAccess(rVal); + SetHeightSizeType(bSet ? SwFrameSize::Variable : SwFrameSize::Fixed); + } + break; + case MID_FRMSIZE_WIDTH_TYPE: + { + sal_Int16 nType = 0; + if((rVal >>= nType) && nType >= 0 && nType <= static_cast(SwFrameSize::Minimum) ) + { + SetWidthSizeType(static_cast(nType)); + } + else + bRet = false; + } + break; + default: + bRet = false; + } + return bRet; +} + +void SwFormatFrameSize::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatFrameSize")); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr())); + + std::stringstream aSize; + aSize << GetSize(); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("size"), BAD_CAST(aSize.str().c_str())); + + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eFrameHeightType"), BAD_CAST(OString::number(static_cast(m_eFrameHeightType)).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eFrameWidthType"), BAD_CAST(OString::number(static_cast(m_eFrameWidthType)).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nWidthPercent"), BAD_CAST(OString::number(m_nWidthPercent).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eWidthPercentRelation"), BAD_CAST(OString::number(m_eWidthPercentRelation).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nHeightPercent"), BAD_CAST(OString::number(m_nHeightPercent).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eHeightPercentRelation"), BAD_CAST(OString::number(m_eHeightPercentRelation).getStr())); + + xmlTextWriterEndElement(pWriter); +} + +// Partially implemented inline in hxx +SwFormatFillOrder::SwFormatFillOrder( SwFillOrder nFO ) + : SfxEnumItem( RES_FILL_ORDER, nFO ) +{} + +SwFormatFillOrder* SwFormatFillOrder::Clone( SfxItemPool* ) const +{ + return new SwFormatFillOrder( GetValue() ); +} + +sal_uInt16 SwFormatFillOrder::GetValueCount() const +{ + return SW_FILL_ORDER_END - SW_FILL_ORDER_BEGIN; +} + +// Partially implemented inline in hxx +SwFormatHeader::SwFormatHeader( SwFrameFormat *pHeaderFormat ) + : SfxPoolItem( RES_HEADER ), + SwClient( pHeaderFormat ), + m_bActive( pHeaderFormat ) +{ +} + +SwFormatHeader::SwFormatHeader( const SwFormatHeader &rCpy ) + : SfxPoolItem( RES_HEADER ), + SwClient( const_cast(rCpy.GetRegisteredIn()) ), + m_bActive( rCpy.IsActive() ) +{ +} + +SwFormatHeader::SwFormatHeader( bool bOn ) + : SfxPoolItem( RES_HEADER ), + SwClient( nullptr ), + m_bActive( bOn ) +{ +} + + SwFormatHeader::~SwFormatHeader() +{ + if ( GetHeaderFormat() ) + lcl_DelHFFormat( this, GetHeaderFormat() ); +} + +bool SwFormatHeader::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + return ( GetRegisteredIn() == static_cast(rAttr).GetRegisteredIn() && + m_bActive == static_cast(rAttr).IsActive() ); +} + +SwFormatHeader* SwFormatHeader::Clone( SfxItemPool* ) const +{ + return new SwFormatHeader( *this ); +} + +void SwFormatHeader::RegisterToFormat( SwFormat& rFormat ) +{ + rFormat.Add(this); +} + +// Partially implemented inline in hxx +SwFormatFooter::SwFormatFooter( SwFrameFormat *pFooterFormat ) + : SfxPoolItem( RES_FOOTER ), + SwClient( pFooterFormat ), + m_bActive( pFooterFormat ) +{ +} + +SwFormatFooter::SwFormatFooter( const SwFormatFooter &rCpy ) + : SfxPoolItem( RES_FOOTER ), + SwClient( const_cast(rCpy.GetRegisteredIn()) ), + m_bActive( rCpy.IsActive() ) +{ +} + +SwFormatFooter::SwFormatFooter( bool bOn ) + : SfxPoolItem( RES_FOOTER ), + SwClient( nullptr ), + m_bActive( bOn ) +{ +} + + SwFormatFooter::~SwFormatFooter() +{ + if ( GetFooterFormat() ) + lcl_DelHFFormat( this, GetFooterFormat() ); +} + +void SwFormatFooter::RegisterToFormat( SwFormat& rFormat ) +{ + rFormat.Add(this); +} + +bool SwFormatFooter::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + return ( GetRegisteredIn() == static_cast(rAttr).GetRegisteredIn() && + m_bActive == static_cast(rAttr).IsActive() ); +} + +SwFormatFooter* SwFormatFooter::Clone( SfxItemPool* ) const +{ + return new SwFormatFooter( *this ); +} + +// Partially implemented inline in hxx +SwFormatContent::SwFormatContent( const SwFormatContent &rCpy ) + : SfxPoolItem( RES_CNTNT ) +{ + m_pStartNode.reset( rCpy.GetContentIdx() ? + new SwNodeIndex( *rCpy.GetContentIdx() ) : nullptr); +} + +SwFormatContent::SwFormatContent( const SwStartNode *pStartNd ) + : SfxPoolItem( RES_CNTNT ) +{ + m_pStartNode.reset( pStartNd ? new SwNodeIndex( *pStartNd ) : nullptr); +} + +SwFormatContent::~SwFormatContent() +{ +} + +void SwFormatContent::SetNewContentIdx( const SwNodeIndex *pIdx ) +{ + m_pStartNode.reset( pIdx ? new SwNodeIndex( *pIdx ) : nullptr ); +} + +bool SwFormatContent::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + if( static_cast(m_pStartNode) != static_cast(static_cast(rAttr).m_pStartNode) ) + return false; + if( m_pStartNode ) + return ( *m_pStartNode == *static_cast(rAttr).GetContentIdx() ); + return true; +} + +SwFormatContent* SwFormatContent::Clone( SfxItemPool* ) const +{ + return new SwFormatContent( *this ); +} + +void SwFormatContent::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatContent")); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("startNode"), BAD_CAST(OString::number(m_pStartNode->GetNode().GetIndex()).getStr())); + xmlTextWriterEndElement(pWriter); +} + +// Partially implemented inline in hxx +SwFormatPageDesc::SwFormatPageDesc( const SwFormatPageDesc &rCpy ) + : SfxPoolItem( RES_PAGEDESC ), + SwClient( const_cast(rCpy.GetPageDesc()) ), + m_oNumOffset( rCpy.m_oNumOffset ), + m_pDefinedIn( nullptr ) +{ +} + +SwFormatPageDesc::SwFormatPageDesc( const SwPageDesc *pDesc ) + : SfxPoolItem( RES_PAGEDESC ), + SwClient( const_cast(pDesc) ), + m_pDefinedIn( nullptr ) +{ +} + +SwFormatPageDesc &SwFormatPageDesc::operator=(const SwFormatPageDesc &rCpy) +{ + if(this == &rCpy) + return *this; + + if (rCpy.GetPageDesc()) + RegisterToPageDesc(*const_cast(rCpy.GetPageDesc())); + m_oNumOffset = rCpy.m_oNumOffset; + m_pDefinedIn = nullptr; + + return *this; +} + + SwFormatPageDesc::~SwFormatPageDesc() {} + +bool SwFormatPageDesc::KnowsPageDesc() const +{ + return (GetRegisteredIn() != nullptr); +} + +bool SwFormatPageDesc::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + return ( m_pDefinedIn == static_cast(rAttr).m_pDefinedIn ) && + ( m_oNumOffset == static_cast(rAttr).m_oNumOffset ) && + ( GetPageDesc() == static_cast(rAttr).GetPageDesc() ); +} + +SwFormatPageDesc* SwFormatPageDesc::Clone( SfxItemPool* ) const +{ + return new SwFormatPageDesc( *this ); +} + +void SwFormatPageDesc::SwClientNotify( const SwModify& rModify, const SfxHint& rHint ) +{ + SwClient::SwClientNotify(rModify, rHint); + const SwPageDescHint* pHint = dynamic_cast(&rHint); + if ( pHint ) + { + // mba: shouldn't that be broadcasted also? + SwFormatPageDesc aDfltDesc( pHint->GetPageDesc() ); + SwPageDesc* pDesc = pHint->GetPageDesc(); + const SwModify* pMod = GetDefinedIn(); + if ( pMod ) + { + if( auto pContentNode = dynamic_cast( pMod) ) + const_cast(pContentNode)->SetAttr( aDfltDesc ); + else if( auto pFormat = dynamic_cast( pMod) ) + const_cast(pFormat)->SetFormatAttr( aDfltDesc ); + else + { + OSL_FAIL( "What kind of SwModify is this?" ); + RegisterToPageDesc( *pDesc ); + } + } + else + // there could be an Undo-copy + RegisterToPageDesc( *pDesc ); + } +} + +void SwFormatPageDesc::RegisterToPageDesc( SwPageDesc& rDesc ) +{ + rDesc.Add( this ); +} + +void SwFormatPageDesc::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew ) +{ + if( !m_pDefinedIn ) + return; + + const sal_uInt16 nWhichId = pOld ? pOld->Which() : pNew ? pNew->Which() : 0; + switch( nWhichId ) + { + case RES_OBJECTDYING: + //The Pagedesc where I'm registered dies, therefore I unregister + //from that format. During this I get deleted! + if( typeid(SwFormat) == typeid( m_pDefinedIn )) + { + bool const bResult = + static_cast(m_pDefinedIn)->ResetFormatAttr(RES_PAGEDESC); + OSL_ENSURE( bResult, "FormatPageDesc not deleted" ); + } + else if( typeid(SwContentNode) == typeid( m_pDefinedIn )) + { + bool const bResult = static_cast(m_pDefinedIn) + ->ResetAttr(RES_PAGEDESC); + OSL_ENSURE( bResult, "FormatPageDesc not deleted" ); + } + break; + + default: + /* do nothing */; + } +} + +bool SwFormatPageDesc::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + // here we convert always! + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_PAGEDESC_PAGENUMOFFSET: + { + ::std::optional oOffset = GetNumOffset(); + if (oOffset) + { + rVal <<= static_cast(*oOffset); + } + else + { + rVal.clear(); + } + } + break; + + case MID_PAGEDESC_PAGEDESCNAME: + { + const SwPageDesc* pDesc = GetPageDesc(); + if( pDesc ) + { + OUString aString; + SwStyleNameMapper::FillProgName(pDesc->GetName(), aString, SwGetPoolIdFromName::PageDesc); + rVal <<= aString; + } + else + rVal.clear(); + } + break; + default: + OSL_ENSURE( false, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + +bool SwFormatPageDesc::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + // here we convert always! + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_PAGEDESC_PAGENUMOFFSET: + { + sal_Int16 nOffset = 0; + if (!rVal.hasValue()) + { + SetNumOffset(std::nullopt); + } + else if (rVal >>= nOffset) + SetNumOffset( nOffset ); + else + bRet = false; + } + break; + + case MID_PAGEDESC_PAGEDESCNAME: + /* Doesn't work, because the attribute doesn't need the name but a + * pointer to the PageDesc (it's a client of it). The pointer can + * only be requested from the document using the name. + */ + default: + OSL_ENSURE( false, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + +void SwFormatPageDesc::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatPageDesc")); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr())); + if (m_oNumOffset) + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("oNumOffset"), BAD_CAST(OString::number(*m_oNumOffset).getStr())); + else + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("oNumOffset"), BAD_CAST("none")); + xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("pPageDesc"), "%p", GetPageDesc()); + if (const SwPageDesc* pPageDesc = GetPageDesc()) + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("presentation"), BAD_CAST(pPageDesc->GetName().toUtf8().getStr())); + xmlTextWriterEndElement(pWriter); +} + +// class SwFormatCol +// Partially implemented inline in hxx + +SwColumn::SwColumn() : + m_nWish ( 0 ), + m_nLeft ( 0 ), + m_nRight( 0 ) +{ +} + +bool SwColumn::operator==( const SwColumn &rCmp ) const +{ + return m_nWish == rCmp.GetWishWidth() && + GetLeft() == rCmp.GetLeft() && + GetRight() == rCmp.GetRight(); +} + +void SwColumn::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + xmlTextWriterStartElement(pWriter, BAD_CAST("SwColumn")); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nWish"), BAD_CAST(OString::number(m_nWish).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nUpper"), BAD_CAST(OString::number(0).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nLower"), BAD_CAST(OString::number(0).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nLeft"), BAD_CAST(OString::number(m_nLeft).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nRight"), BAD_CAST(OString::number(m_nRight).getStr())); + xmlTextWriterEndElement(pWriter); +} + +SwFormatCol::SwFormatCol( const SwFormatCol& rCpy ) + : SfxPoolItem( RES_COL ), + m_eLineStyle( rCpy.m_eLineStyle ), + m_nLineWidth( rCpy.m_nLineWidth), + m_aLineColor( rCpy.m_aLineColor), + m_nLineHeight( rCpy.GetLineHeight() ), + m_eAdj( rCpy.GetLineAdj() ), + m_nWidth( rCpy.GetWishWidth() ), + m_aWidthAdjustValue( rCpy.m_aWidthAdjustValue ), + m_bOrtho( rCpy.IsOrtho() ) +{ + m_aColumns.reserve(rCpy.GetNumCols()); + for ( sal_uInt16 i = 0; i < rCpy.GetNumCols(); ++i ) + { + m_aColumns.emplace_back(rCpy.GetColumns()[i] ); + } +} + +SwFormatCol::~SwFormatCol() {} + +SwFormatCol& SwFormatCol::operator=( const SwFormatCol& rCpy ) +{ + if (this != &rCpy) + { + m_eLineStyle = rCpy.m_eLineStyle; + m_nLineWidth = rCpy.m_nLineWidth; + m_aLineColor = rCpy.m_aLineColor; + m_nLineHeight = rCpy.GetLineHeight(); + m_eAdj = rCpy.GetLineAdj(); + m_nWidth = rCpy.GetWishWidth(); + m_aWidthAdjustValue = rCpy.m_aWidthAdjustValue; + m_bOrtho = rCpy.IsOrtho(); + + m_aColumns.clear(); + for ( sal_uInt16 i = 0; i < rCpy.GetNumCols(); ++i ) + { + m_aColumns.emplace_back(rCpy.GetColumns()[i] ); + } + } + return *this; +} + +SwFormatCol::SwFormatCol() + : SfxPoolItem( RES_COL ) + , m_eLineStyle( SvxBorderLineStyle::NONE) + , + m_nLineWidth(0), + m_nLineHeight( 100 ), + m_eAdj( COLADJ_NONE ), + m_nWidth( USHRT_MAX ), + m_aWidthAdjustValue( 0 ), + m_bOrtho( true ) +{ +} + +bool SwFormatCol::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + const SwFormatCol &rCmp = static_cast(rAttr); + if( !(m_eLineStyle == rCmp.m_eLineStyle && + m_nLineWidth == rCmp.m_nLineWidth && + m_aLineColor == rCmp.m_aLineColor && + m_nLineHeight == rCmp.GetLineHeight() && + m_eAdj == rCmp.GetLineAdj() && + m_nWidth == rCmp.GetWishWidth() && + m_bOrtho == rCmp.IsOrtho() && + m_aColumns.size() == rCmp.GetNumCols() && + m_aWidthAdjustValue == rCmp.GetAdjustValue() + ) ) + return false; + + for ( size_t i = 0; i < m_aColumns.size(); ++i ) + if ( !(m_aColumns[i] == rCmp.GetColumns()[i]) ) + return false; + + return true; +} + +SwFormatCol* SwFormatCol::Clone( SfxItemPool* ) const +{ + return new SwFormatCol( *this ); +} + +sal_uInt16 SwFormatCol::GetGutterWidth( bool bMin ) const +{ + sal_uInt16 nRet = 0; + if ( m_aColumns.size() == 2 ) + nRet = m_aColumns[0].GetRight() + m_aColumns[1].GetLeft(); + else if ( m_aColumns.size() > 2 ) + { + bool bSet = false; + for ( size_t i = 1; i+1 < m_aColumns.size(); ++i ) + { + const sal_uInt16 nTmp = m_aColumns[i].GetRight() + m_aColumns[i+1].GetLeft(); + if ( bSet ) + { + if ( nTmp != nRet ) + { + if ( !bMin ) + return USHRT_MAX; + if ( nRet > nTmp ) + nRet = nTmp; + } + } + else + { + bSet = true; + nRet = nTmp; + } + } + } + return nRet; +} + +void SwFormatCol::SetGutterWidth( sal_uInt16 nNew, sal_uInt16 nAct ) +{ + if ( m_bOrtho ) + Calc( nNew, nAct ); + else + { + sal_uInt16 nHalf = nNew / 2; + for (size_t i = 0; i < m_aColumns.size(); ++i) + { + SwColumn &rCol = m_aColumns[i]; + rCol.SetLeft(nHalf); + rCol.SetRight(nHalf); + if ( i == 0 ) + rCol.SetLeft(0); + else if ( i+1 == m_aColumns.size() ) + rCol.SetRight(0); + } + } +} + +void SwFormatCol::Init( sal_uInt16 nNumCols, sal_uInt16 nGutterWidth, sal_uInt16 nAct ) +{ + // Deleting seems to be a bit radical on the first sight; but otherwise we + // have to initialize all values of the remaining SwColumns. + m_aColumns.clear(); + for ( sal_uInt16 i = 0; i < nNumCols; ++i ) + { + m_aColumns.emplace_back( ); + } + m_bOrtho = true; + m_nWidth = USHRT_MAX; + if( nNumCols ) + Calc( nGutterWidth, nAct ); +} + +void SwFormatCol::SetOrtho( bool bNew, sal_uInt16 nGutterWidth, sal_uInt16 nAct ) +{ + m_bOrtho = bNew; + if ( bNew && !m_aColumns.empty() ) + Calc( nGutterWidth, nAct ); +} + +sal_uInt16 SwFormatCol::CalcColWidth( sal_uInt16 nCol, sal_uInt16 nAct ) const +{ + assert(nCol < m_aColumns.size()); + if ( m_nWidth != nAct ) + { + long nW = m_aColumns[nCol].GetWishWidth(); + nW *= nAct; + nW /= m_nWidth; + return sal_uInt16(nW); + } + else + return m_aColumns[nCol].GetWishWidth(); +} + +sal_uInt16 SwFormatCol::CalcPrtColWidth( sal_uInt16 nCol, sal_uInt16 nAct ) const +{ + assert(nCol < m_aColumns.size()); + sal_uInt16 nRet = CalcColWidth( nCol, nAct ); + const SwColumn *pCol = &m_aColumns[nCol]; + nRet = nRet - pCol->GetLeft(); + nRet = nRet - pCol->GetRight(); + return nRet; +} + +void SwFormatCol::Calc( sal_uInt16 nGutterWidth, sal_uInt16 nAct ) +{ + if (!GetNumCols()) + return; + + //First set the column widths with the current width, then calculate the + //column's requested width using the requested total width. + const sal_uInt16 nGutterHalf = nGutterWidth ? nGutterWidth / 2 : 0; + + //Width of PrtAreas is totalwidth - spacings / count + sal_uInt16 nSpacings; + bool bFail = o3tl::checked_multiply(GetNumCols() - 1, nGutterWidth, nSpacings); + if (bFail) + { + SAL_WARN("sw.core", "SwFormatVertOrient::Calc: overflow"); + return; + } + + const sal_uInt16 nPrtWidth = (nAct - nSpacings) / GetNumCols(); + sal_uInt16 nAvail = nAct; + + //The first column is PrtWidth + (gap width / 2) + const sal_uInt16 nLeftWidth = nPrtWidth + nGutterHalf; + SwColumn &rFirstCol = m_aColumns.front(); + rFirstCol.SetWishWidth(nLeftWidth); + rFirstCol.SetRight(nGutterHalf); + rFirstCol.SetLeft(0); + nAvail = nAvail - nLeftWidth; + + //Column 2 to n-1 is PrtWidth + gap width + const sal_uInt16 nMidWidth = nPrtWidth + nGutterWidth; + + for (sal_uInt16 i = 1; i < GetNumCols()-1; ++i) + { + SwColumn &rCol = m_aColumns[i]; + rCol.SetWishWidth(nMidWidth); + rCol.SetLeft(nGutterHalf); + rCol.SetRight(nGutterHalf); + nAvail = nAvail - nMidWidth; + } + + //The last column is equivalent to the first one - to compensate rounding + //errors we add the remaining space of the other columns to the last one. + SwColumn &rLastCol = m_aColumns.back(); + rLastCol.SetWishWidth(nAvail); + rLastCol.SetLeft(nGutterHalf); + rLastCol.SetRight(0); + + //Convert the current width to the requested width. + for (SwColumn &rCol: m_aColumns) + { + long nTmp = rCol.GetWishWidth(); + nTmp *= GetWishWidth(); + nTmp /= nAct; + rCol.SetWishWidth(sal_uInt16(nTmp)); + } +} + +bool SwFormatCol::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + // here we convert always! + nMemberId &= ~CONVERT_TWIPS; + if(MID_COLUMN_SEPARATOR_LINE == nMemberId) + { + OSL_FAIL("not implemented"); + } + else + { + uno::Reference< text::XTextColumns > xCols = new SwXTextColumns(*this); + rVal <<= xCols; + } + return true; +} + +bool SwFormatCol::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + // here we convert always! + nMemberId &= ~CONVERT_TWIPS; + bool bRet = false; + if(MID_COLUMN_SEPARATOR_LINE == nMemberId) + { + OSL_FAIL("not implemented"); + } + else + { + uno::Reference< text::XTextColumns > xCols; + rVal >>= xCols; + if(xCols.is()) + { + uno::Sequence aSetColumns = xCols->getColumns(); + const text::TextColumn* pArray = aSetColumns.getConstArray(); + m_aColumns.clear(); + //max count is 64k here - this is something the array can't do + sal_uInt16 nCount = std::min( static_cast(aSetColumns.getLength()), + sal_uInt16(0x3fff) ); + sal_uInt16 nWidthSum = 0; + // #101224# one column is no column + + if(nCount > 1) + for(sal_uInt16 i = 0; i < nCount; i++) + { + SwColumn aCol; + aCol.SetWishWidth(pArray[i].Width ); + nWidthSum = nWidthSum + pArray[i].Width; + aCol.SetLeft (convertMm100ToTwip(pArray[i].LeftMargin)); + aCol.SetRight(convertMm100ToTwip(pArray[i].RightMargin)); + m_aColumns.insert(m_aColumns.begin() + i, aCol); + } + bRet = true; + m_nWidth = nWidthSum; + m_bOrtho = false; + + auto pSwColums = comphelper::getUnoTunnelImplementation(xCols); + if(pSwColums) + { + m_bOrtho = pSwColums->IsAutomaticWidth(); + m_nLineWidth = pSwColums->GetSepLineWidth(); + m_aLineColor = pSwColums->GetSepLineColor(); + m_nLineHeight = pSwColums->GetSepLineHeightRelative(); + switch ( pSwColums->GetSepLineStyle() ) + { + default: + case 0: m_eLineStyle = SvxBorderLineStyle::NONE; break; + case 1: m_eLineStyle = SvxBorderLineStyle::SOLID; break; + case 2: m_eLineStyle = SvxBorderLineStyle::DOTTED; break; + case 3: m_eLineStyle = SvxBorderLineStyle::DASHED; break; + } + if(!pSwColums->GetSepLineIsOn()) + m_eAdj = COLADJ_NONE; + else switch(pSwColums->GetSepLineVertAlign()) + { + case style::VerticalAlignment_TOP: m_eAdj = COLADJ_TOP; break; + case style::VerticalAlignment_MIDDLE: m_eAdj = COLADJ_CENTER; break; + case style::VerticalAlignment_BOTTOM: m_eAdj = COLADJ_BOTTOM; break; + default: OSL_ENSURE( false, "unknown alignment" ); break; + } + } + } + } + return bRet; +} + +void SwFormatCol::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatCol")); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eLineStyle"), BAD_CAST(OString::number(static_cast(m_eLineStyle)).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nLineWidth"), BAD_CAST(OString::number(m_nLineWidth).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("aLineColor"), BAD_CAST(m_aLineColor.AsRGBHexString().toUtf8().getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nLineHeight"), BAD_CAST(OString::number(m_nLineHeight).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eAdj"), BAD_CAST(OString::number(m_eAdj).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nWidth"), BAD_CAST(OString::number(m_nWidth).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nWidthAdjustValue"), BAD_CAST(OString::number(m_aWidthAdjustValue).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bOrtho"), BAD_CAST(OString::boolean(m_bOrtho).getStr())); + + xmlTextWriterStartElement(pWriter, BAD_CAST("aColumns")); + for (const SwColumn& rColumn : m_aColumns) + rColumn.dumpAsXml(pWriter); + xmlTextWriterEndElement(pWriter); + + xmlTextWriterEndElement(pWriter); +} + +// Partially implemented inline in hxx +SwFormatSurround::SwFormatSurround( css::text::WrapTextMode eFly ) : + SfxEnumItem( RES_SURROUND, eFly ) +{ + m_bAnchorOnly = m_bContour = m_bOutside = false; +} + +bool SwFormatSurround::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + return ( GetValue() == static_cast(rAttr).GetValue() && + m_bAnchorOnly== static_cast(rAttr).m_bAnchorOnly && + m_bContour== static_cast(rAttr).m_bContour && + m_bOutside== static_cast(rAttr).m_bOutside ); +} + +SwFormatSurround* SwFormatSurround::Clone( SfxItemPool* ) const +{ + return new SwFormatSurround( *this ); +} + +sal_uInt16 SwFormatSurround::GetValueCount() const +{ + return 6; +} + +bool SwFormatSurround::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + // here we convert always! + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_SURROUND_SURROUNDTYPE: + rVal <<= GetSurround(); + break; + case MID_SURROUND_ANCHORONLY: + rVal <<= IsAnchorOnly(); + break; + case MID_SURROUND_CONTOUR: + rVal <<= IsContour(); + break; + case MID_SURROUND_CONTOUROUTSIDE: + rVal <<= IsOutside(); + break; + default: + OSL_ENSURE( false, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + +bool SwFormatSurround::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + // here we convert always! + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_SURROUND_SURROUNDTYPE: + { + css::text::WrapTextMode eVal = static_cast(SWUnoHelper::GetEnumAsInt32( rVal )); + if( eVal >= css::text::WrapTextMode_NONE && eVal <= css::text::WrapTextMode_RIGHT ) + SetValue( eVal ); + else { + //exception + ; + } + } + break; + + case MID_SURROUND_ANCHORONLY: + SetAnchorOnly( *o3tl::doAccess(rVal) ); + break; + case MID_SURROUND_CONTOUR: + SetContour( *o3tl::doAccess(rVal) ); + break; + case MID_SURROUND_CONTOUROUTSIDE: + SetOutside( *o3tl::doAccess(rVal) ); + break; + default: + OSL_ENSURE( false, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + +void SwFormatSurround::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatSurround")); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(OString::number(static_cast(GetValue())).getStr())); + + OUString aPresentation; + IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag()); + GetPresentation(SfxItemPresentation::Nameless, MapUnit::Map100thMM, MapUnit::Map100thMM, aPresentation, aIntlWrapper); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("presentation"), BAD_CAST(aPresentation.toUtf8().getStr())); + + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bAnchorOnly"), BAD_CAST(OString::boolean(m_bAnchorOnly).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bContour"), BAD_CAST(OString::boolean(m_bContour).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bOutside"), BAD_CAST(OString::boolean(m_bOutside).getStr())); + + xmlTextWriterEndElement(pWriter); +} + +// Partially implemented inline in hxx +SwFormatVertOrient::SwFormatVertOrient( SwTwips nY, sal_Int16 eVert, + sal_Int16 eRel ) + : SfxPoolItem( RES_VERT_ORIENT ), + m_nYPos( nY ), + m_eOrient( eVert ), + m_eRelation( eRel ) +{} + +bool SwFormatVertOrient::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + return ( m_nYPos == static_cast(rAttr).m_nYPos && + m_eOrient == static_cast(rAttr).m_eOrient && + m_eRelation == static_cast(rAttr).m_eRelation ); +} + +SwFormatVertOrient* SwFormatVertOrient::Clone( SfxItemPool* ) const +{ + return new SwFormatVertOrient( *this ); +} + +bool SwFormatVertOrient::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + // here we convert always! + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_VERTORIENT_ORIENT: + { + rVal <<= m_eOrient; + } + break; + case MID_VERTORIENT_RELATION: + rVal <<= m_eRelation; + break; + case MID_VERTORIENT_POSITION: + rVal <<= static_cast(convertTwipToMm100(GetPos())); + break; + default: + OSL_ENSURE( false, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + +bool SwFormatVertOrient::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + bool bConvert = 0 != (nMemberId&CONVERT_TWIPS); + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_VERTORIENT_ORIENT: + { + sal_uInt16 nVal = text::VertOrientation::NONE; + rVal >>= nVal; + m_eOrient = nVal; + } + break; + case MID_VERTORIENT_RELATION: + { + m_eRelation = lcl_IntToRelation(rVal); + } + break; + case MID_VERTORIENT_POSITION: + { + sal_Int32 nVal = 0; + rVal >>= nVal; + if(bConvert) + nVal = convertMm100ToTwip(nVal); + SetPos( nVal ); + } + break; + default: + OSL_ENSURE( false, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + +void SwFormatVertOrient::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatVertOrient")); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nYPos"), BAD_CAST(OString::number(m_nYPos).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eOrient"), BAD_CAST(OString::number(m_eOrient).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eRelation"), BAD_CAST(OString::number(m_eRelation).getStr())); + xmlTextWriterEndElement(pWriter); +} + +// Partially implemented inline in hxx +SwFormatHoriOrient::SwFormatHoriOrient( SwTwips nX, sal_Int16 eHori, + sal_Int16 eRel, bool bPos ) + : SfxPoolItem( RES_HORI_ORIENT ), + m_nXPos( nX ), + m_eOrient( eHori ), + m_eRelation( eRel ), + m_bPosToggle( bPos ) +{} + +bool SwFormatHoriOrient::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + return ( m_nXPos == static_cast(rAttr).m_nXPos && + m_eOrient == static_cast(rAttr).m_eOrient && + m_eRelation == static_cast(rAttr).m_eRelation && + m_bPosToggle == static_cast(rAttr).m_bPosToggle ); +} + +SwFormatHoriOrient* SwFormatHoriOrient::Clone( SfxItemPool* ) const +{ + return new SwFormatHoriOrient( *this ); +} + +bool SwFormatHoriOrient::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + // here we convert always! + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_HORIORIENT_ORIENT: + { + rVal <<= m_eOrient; + } + break; + case MID_HORIORIENT_RELATION: + rVal <<= m_eRelation; + break; + case MID_HORIORIENT_POSITION: + rVal <<= static_cast(convertTwipToMm100(GetPos())); + break; + case MID_HORIORIENT_PAGETOGGLE: + rVal <<= IsPosToggle(); + break; + default: + OSL_ENSURE( false, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + +bool SwFormatHoriOrient::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + bool bConvert = 0 != (nMemberId&CONVERT_TWIPS); + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_HORIORIENT_ORIENT: + { + sal_Int16 nVal = text::HoriOrientation::NONE; + rVal >>= nVal; + m_eOrient = nVal; + } + break; + case MID_HORIORIENT_RELATION: + { + m_eRelation = lcl_IntToRelation(rVal); + } + break; + case MID_HORIORIENT_POSITION: + { + sal_Int32 nVal = 0; + if(!(rVal >>= nVal)) + bRet = false; + if(bConvert) + nVal = convertMm100ToTwip(nVal); + SetPos( nVal ); + } + break; + case MID_HORIORIENT_PAGETOGGLE: + SetPosToggle( *o3tl::doAccess(rVal)); + break; + default: + OSL_ENSURE( false, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + +void SwFormatHoriOrient::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatHoriOrient")); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nXPos"), BAD_CAST(OString::number(m_nXPos).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eOrient"), BAD_CAST(OString::number(m_eOrient).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eRelation"), BAD_CAST(OString::number(m_eRelation).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bPosToggle"), BAD_CAST(OString::boolean(m_bPosToggle).getStr())); + xmlTextWriterEndElement(pWriter); +} + +// Partially implemented inline in hxx +SwFormatAnchor::SwFormatAnchor( RndStdIds nRnd, sal_uInt16 nPage ) + : SfxPoolItem( RES_ANCHOR ), + m_eAnchorId( nRnd ), + m_nPageNumber( nPage ), + // OD 2004-05-05 #i28701# - get always new increased order number + m_nOrder( ++m_nOrderCounter ) +{} + +SwFormatAnchor::SwFormatAnchor( const SwFormatAnchor &rCpy ) + : SfxPoolItem( RES_ANCHOR ) + , m_pContentAnchor( (rCpy.GetContentAnchor()) + ? new SwPosition( *rCpy.GetContentAnchor() ) : nullptr ) + , m_eAnchorId( rCpy.GetAnchorId() ) + , m_nPageNumber( rCpy.GetPageNum() ) + // OD 2004-05-05 #i28701# - get always new increased order number + , m_nOrder( ++m_nOrderCounter ) +{ +} + +SwFormatAnchor::~SwFormatAnchor() +{ +} + +void SwFormatAnchor::SetAnchor( const SwPosition *pPos ) +{ + // anchor only to paragraphs, or start nodes in case of RndStdIds::FLY_AT_FLY + // also allow table node, this is used when a table is selected and is converted to a frame by the UI + assert(!pPos + || ((RndStdIds::FLY_AT_FLY == m_eAnchorId) && + dynamic_cast(&pPos->nNode.GetNode())) + || (RndStdIds::FLY_AT_PARA == m_eAnchorId && dynamic_cast(&pPos->nNode.GetNode())) + || dynamic_cast(&pPos->nNode.GetNode())); + m_pContentAnchor .reset( pPos ? new SwPosition( *pPos ) : nullptr ); + // Flys anchored AT paragraph should not point into the paragraph content + if (m_pContentAnchor && + ((RndStdIds::FLY_AT_PARA == m_eAnchorId) || (RndStdIds::FLY_AT_FLY == m_eAnchorId))) + { + m_pContentAnchor->nContent.Assign( nullptr, 0 ); + } +} + +SwFormatAnchor& SwFormatAnchor::operator=(const SwFormatAnchor& rAnchor) +{ + if (this != &rAnchor) + { + m_eAnchorId = rAnchor.GetAnchorId(); + m_nPageNumber = rAnchor.GetPageNum(); + // OD 2004-05-05 #i28701# - get always new increased order number + m_nOrder = ++m_nOrderCounter; + + m_pContentAnchor.reset( (rAnchor.GetContentAnchor()) + ? new SwPosition(*(rAnchor.GetContentAnchor())) + : nullptr ); + } + return *this; +} + +bool SwFormatAnchor::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + SwFormatAnchor const& rFormatAnchor(static_cast(rAttr)); + // OD 2004-05-05 #i28701# - Note: hasn't to be considered. + return ( m_eAnchorId == rFormatAnchor.GetAnchorId() && + m_nPageNumber == rFormatAnchor.GetPageNum() && + // compare anchor: either both do not point into a textnode or + // both do (valid m_pContentAnchor) and the positions are equal + ((m_pContentAnchor.get() == rFormatAnchor.m_pContentAnchor.get()) || + (m_pContentAnchor && rFormatAnchor.GetContentAnchor() && + (*m_pContentAnchor == *rFormatAnchor.GetContentAnchor())))); +} + +SwFormatAnchor* SwFormatAnchor::Clone( SfxItemPool* ) const +{ + return new SwFormatAnchor( *this ); +} + +// OD 2004-05-05 #i28701# +sal_uInt32 SwFormatAnchor::m_nOrderCounter = 0; + +// OD 2004-05-05 #i28701# + +bool SwFormatAnchor::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + // here we convert always! + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_ANCHOR_ANCHORTYPE: + + text::TextContentAnchorType eRet; + switch (GetAnchorId()) + { + case RndStdIds::FLY_AT_CHAR: + eRet = text::TextContentAnchorType_AT_CHARACTER; + break; + case RndStdIds::FLY_AT_PAGE: + eRet = text::TextContentAnchorType_AT_PAGE; + break; + case RndStdIds::FLY_AT_FLY: + eRet = text::TextContentAnchorType_AT_FRAME; + break; + case RndStdIds::FLY_AS_CHAR: + eRet = text::TextContentAnchorType_AS_CHARACTER; + break; + //case RndStdIds::FLY_AT_PARA: + default: + eRet = text::TextContentAnchorType_AT_PARAGRAPH; + } + rVal <<= eRet; + break; + case MID_ANCHOR_PAGENUM: + rVal <<= static_cast(GetPageNum()); + break; + case MID_ANCHOR_ANCHORFRAME: + { + if (m_pContentAnchor && RndStdIds::FLY_AT_FLY == m_eAnchorId) + { + SwFrameFormat* pFormat = m_pContentAnchor->nNode.GetNode().GetFlyFormat(); + if(pFormat) + { + uno::Reference const xRet( + SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat)); + rVal <<= xRet; + } + } + } + break; + default: + OSL_ENSURE( false, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + +bool SwFormatAnchor::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + // here we convert always! + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_ANCHOR_ANCHORTYPE: + { + RndStdIds eAnchor; + switch( static_cast(SWUnoHelper::GetEnumAsInt32( rVal )) ) + { + case text::TextContentAnchorType_AS_CHARACTER: + eAnchor = RndStdIds::FLY_AS_CHAR; + break; + case text::TextContentAnchorType_AT_PAGE: + eAnchor = RndStdIds::FLY_AT_PAGE; + if( GetPageNum() > 0 ) + { + // If the anchor type is page and a valid page number + // has been set, the content position isn't required + // any longer. + m_pContentAnchor.reset(); + } + break; + case text::TextContentAnchorType_AT_FRAME: + eAnchor = RndStdIds::FLY_AT_FLY; + break; + case text::TextContentAnchorType_AT_CHARACTER: + eAnchor = RndStdIds::FLY_AT_CHAR; + break; + //case text::TextContentAnchorType_AT_PARAGRAPH: + default: + eAnchor = RndStdIds::FLY_AT_PARA; + break; + } + SetType( eAnchor ); + } + break; + case MID_ANCHOR_PAGENUM: + { + sal_Int16 nVal = 0; + if((rVal >>= nVal) && nVal > 0) + { + SetPageNum( nVal ); + if (RndStdIds::FLY_AT_PAGE == GetAnchorId()) + { + // If the anchor type is page and a valid page number + // is set, the content position has to be deleted to not + // confuse the layout (frmtool.cxx). However, if the + // anchor type is not page, any content position will + // be kept. + m_pContentAnchor.reset(); + } + } + else + bRet = false; + } + break; + case MID_ANCHOR_ANCHORFRAME: + //no break here!; + default: + OSL_ENSURE( false, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + +void SwFormatAnchor::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatAnchor")); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr())); + + if (m_pContentAnchor) + { + std::stringstream aContentAnchor; + aContentAnchor << *m_pContentAnchor; + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_pContentAnchor"), BAD_CAST(aContentAnchor.str().c_str())); + } + else + xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("m_pContentAnchor"), "%p", m_pContentAnchor.get()); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_eAnchorType"), BAD_CAST(OString::number(static_cast(m_eAnchorId)).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nPageNumber"), BAD_CAST(OString::number(m_nPageNumber).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nOrder"), BAD_CAST(OString::number(m_nOrder).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nOrderCounter"), BAD_CAST(OString::number(m_nOrderCounter).getStr())); + OUString aPresentation; + IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag()); + GetPresentation(SfxItemPresentation::Nameless, MapUnit::Map100thMM, MapUnit::Map100thMM, aPresentation, aIntlWrapper); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("presentation"), BAD_CAST(aPresentation.toUtf8().getStr())); + + xmlTextWriterEndElement(pWriter); +} + +// Partially implemented inline in hxx +SwFormatURL::SwFormatURL() : + SfxPoolItem( RES_URL ), + m_bIsServerMap( false ) +{ +} + +SwFormatURL::SwFormatURL( const SwFormatURL &rURL) : + SfxPoolItem( RES_URL ), + m_sTargetFrameName( rURL.GetTargetFrameName() ), + m_sURL( rURL.GetURL() ), + m_sName( rURL.GetName() ), + m_bIsServerMap( rURL.IsServerMap() ) +{ + if (rURL.GetMap()) + m_pMap.reset( new ImageMap( *rURL.GetMap() ) ); +} + +SwFormatURL::~SwFormatURL() +{ +} + +bool SwFormatURL::operator==( const SfxPoolItem &rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + const SwFormatURL &rCmp = static_cast(rAttr); + bool bRet = m_bIsServerMap == rCmp.IsServerMap() && + m_sURL == rCmp.GetURL() && + m_sTargetFrameName == rCmp.GetTargetFrameName() && + m_sName == rCmp.GetName(); + if ( bRet ) + { + if ( m_pMap && rCmp.GetMap() ) + bRet = *m_pMap == *rCmp.GetMap(); + else + bRet = m_pMap.get() == rCmp.GetMap(); + } + return bRet; +} + +SwFormatURL* SwFormatURL::Clone( SfxItemPool* ) const +{ + return new SwFormatURL( *this ); +} + +void SwFormatURL::SetURL(const OUString &rURL, bool bServerMap) +{ + m_sURL = rURL; + m_bIsServerMap = bServerMap; +} + +void SwFormatURL::SetMap( const ImageMap *pM ) +{ + m_pMap.reset( pM ? new ImageMap( *pM ) : nullptr); +} + +bool SwFormatURL::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + // here we convert always! + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_URL_URL: + rVal <<= GetURL(); + break; + case MID_URL_TARGET: + rVal <<= GetTargetFrameName(); + break; + case MID_URL_HYPERLINKNAME: + rVal <<= GetName(); + break; + case MID_URL_CLIENTMAP: + { + uno::Reference< uno::XInterface > xInt; + if(m_pMap) + { + xInt = SvUnoImageMap_createInstance( *m_pMap, sw_GetSupportedMacroItems() ); + } + else + { + ImageMap aEmptyMap; + xInt = SvUnoImageMap_createInstance( aEmptyMap, sw_GetSupportedMacroItems() ); + } + uno::Reference< container::XIndexContainer > xCont(xInt, uno::UNO_QUERY); + rVal <<= xCont; + } + break; + case MID_URL_SERVERMAP: + rVal <<= IsServerMap(); + break; + default: + OSL_ENSURE( false, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + +bool SwFormatURL::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + // here we convert always! + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_URL_URL: + { + OUString sTmp; + rVal >>= sTmp; + SetURL( sTmp, m_bIsServerMap ); + } + break; + case MID_URL_TARGET: + { + OUString sTmp; + rVal >>= sTmp; + SetTargetFrameName( sTmp ); + } + break; + case MID_URL_HYPERLINKNAME: + { + OUString sTmp; + rVal >>= sTmp; + SetName( sTmp ); + } + break; + case MID_URL_CLIENTMAP: + { + uno::Reference xCont; + if(!rVal.hasValue()) + m_pMap.reset(); + else if(rVal >>= xCont) + { + if(!m_pMap) + m_pMap.reset(new ImageMap); + bRet = SvUnoImageMap_fillImageMap( xCont, *m_pMap ); + } + else + bRet = false; + } + break; + case MID_URL_SERVERMAP: + m_bIsServerMap = *o3tl::doAccess(rVal); + break; + default: + OSL_ENSURE( false, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + +SwFormatEditInReadonly* SwFormatEditInReadonly::Clone( SfxItemPool* ) const +{ + return new SwFormatEditInReadonly( *this ); +} + +SwFormatLayoutSplit* SwFormatLayoutSplit::Clone( SfxItemPool* ) const +{ + return new SwFormatLayoutSplit( *this ); +} + +SwFormatRowSplit* SwFormatRowSplit::Clone( SfxItemPool* ) const +{ + return new SwFormatRowSplit( *this ); +} + +SwFormatNoBalancedColumns* SwFormatNoBalancedColumns::Clone( SfxItemPool* ) const +{ + return new SwFormatNoBalancedColumns( *this ); +} + +void SwFormatNoBalancedColumns::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatNoBalancedColumns")); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(OString::boolean(GetValue()).getStr())); + xmlTextWriterEndElement(pWriter); +} + +// class SwFormatFootnoteEndAtTextEnd + +sal_uInt16 SwFormatFootnoteEndAtTextEnd::GetValueCount() const +{ + return sal_uInt16( FTNEND_ATTXTEND_END ); +} + +SwFormatFootnoteEndAtTextEnd& SwFormatFootnoteEndAtTextEnd::operator=( + const SwFormatFootnoteEndAtTextEnd& rAttr ) +{ + SfxEnumItem::SetValue( rAttr.GetValue() ); + m_aFormat = rAttr.m_aFormat; + m_nOffset = rAttr.m_nOffset; + m_sPrefix = rAttr.m_sPrefix; + m_sSuffix = rAttr.m_sSuffix; + return *this; +} + +bool SwFormatFootnoteEndAtTextEnd::operator==( const SfxPoolItem& rItem ) const +{ + const SwFormatFootnoteEndAtTextEnd& rAttr = static_cast(rItem); + return SfxEnumItem::operator==( rAttr ) && + m_aFormat.GetNumberingType() == rAttr.m_aFormat.GetNumberingType() && + m_nOffset == rAttr.m_nOffset && + m_sPrefix == rAttr.m_sPrefix && + m_sSuffix == rAttr.m_sSuffix; +} + +bool SwFormatFootnoteEndAtTextEnd::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + nMemberId &= ~CONVERT_TWIPS; + switch(nMemberId) + { + case MID_COLLECT : + rVal <<= GetValue() >= FTNEND_ATTXTEND; + break; + case MID_RESTART_NUM : + rVal <<= GetValue() >= FTNEND_ATTXTEND_OWNNUMSEQ; + break; + case MID_NUM_START_AT: rVal <<= static_cast(m_nOffset); break; + case MID_OWN_NUM : + rVal <<= GetValue() >= FTNEND_ATTXTEND_OWNNUMANDFMT; + break; + case MID_NUM_TYPE : rVal <<= static_cast(m_aFormat.GetNumberingType()); break; + case MID_PREFIX : rVal <<= m_sPrefix; break; + case MID_SUFFIX : rVal <<= m_sSuffix; break; + default: return false; + } + return true; +} + +bool SwFormatFootnoteEndAtTextEnd::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + bool bRet = true; + nMemberId &= ~CONVERT_TWIPS; + switch(nMemberId) + { + case MID_COLLECT : + { + bool bVal = *o3tl::doAccess(rVal); + if(!bVal && GetValue() >= FTNEND_ATTXTEND) + SetValue(FTNEND_ATPGORDOCEND); + else if(bVal && GetValue() < FTNEND_ATTXTEND) + SetValue(FTNEND_ATTXTEND); + } + break; + case MID_RESTART_NUM : + { + bool bVal = *o3tl::doAccess(rVal); + if(!bVal && GetValue() >= FTNEND_ATTXTEND_OWNNUMSEQ) + SetValue(FTNEND_ATTXTEND); + else if(bVal && GetValue() < FTNEND_ATTXTEND_OWNNUMSEQ) + SetValue(FTNEND_ATTXTEND_OWNNUMSEQ); + } + break; + case MID_NUM_START_AT: + { + sal_Int16 nVal = 0; + rVal >>= nVal; + if(nVal >= 0) + m_nOffset = nVal; + else + bRet = false; + } + break; + case MID_OWN_NUM : + { + bool bVal = *o3tl::doAccess(rVal); + if(!bVal && GetValue() >= FTNEND_ATTXTEND_OWNNUMANDFMT) + SetValue(FTNEND_ATTXTEND_OWNNUMSEQ); + else if(bVal && GetValue() < FTNEND_ATTXTEND_OWNNUMANDFMT) + SetValue(FTNEND_ATTXTEND_OWNNUMANDFMT); + } + break; + case MID_NUM_TYPE : + { + sal_Int16 nVal = 0; + rVal >>= nVal; + if(nVal >= 0 && + (nVal <= SVX_NUM_ARABIC || + SVX_NUM_CHARS_UPPER_LETTER_N == nVal || + SVX_NUM_CHARS_LOWER_LETTER_N == nVal )) + m_aFormat.SetNumberingType(static_cast(nVal)); + else + bRet = false; + } + break; + case MID_PREFIX : + { + OUString sVal; rVal >>= sVal; + m_sPrefix = sVal; + } + break; + case MID_SUFFIX : + { + OUString sVal; rVal >>= sVal; + m_sSuffix = sVal; + } + break; + default: bRet = false; + } + return bRet; +} + +// class SwFormatFootnoteAtTextEnd + +SwFormatFootnoteAtTextEnd* SwFormatFootnoteAtTextEnd::Clone( SfxItemPool* ) const +{ + return new SwFormatFootnoteAtTextEnd(*this); +} + +// class SwFormatEndAtTextEnd + +SwFormatEndAtTextEnd* SwFormatEndAtTextEnd::Clone( SfxItemPool* ) const +{ + return new SwFormatEndAtTextEnd(*this); +} + +//class SwFormatChain + +bool SwFormatChain::operator==( const SfxPoolItem &rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + + return GetPrev() == static_cast(rAttr).GetPrev() && + GetNext() == static_cast(rAttr).GetNext(); +} + +SwFormatChain::SwFormatChain( const SwFormatChain &rCpy ) : + SfxPoolItem( RES_CHAIN ) +{ + SetPrev( rCpy.GetPrev() ); + SetNext( rCpy.GetNext() ); +} + +SwFormatChain* SwFormatChain::Clone( SfxItemPool* ) const +{ + SwFormatChain *pRet = new SwFormatChain; + pRet->SetPrev( GetPrev() ); + pRet->SetNext( GetNext() ); + return pRet; +} + +void SwFormatChain::SetPrev( SwFlyFrameFormat *pFormat ) +{ + if ( pFormat ) + pFormat->Add( &m_aPrev ); + else + m_aPrev.EndListeningAll(); +} + +void SwFormatChain::SetNext( SwFlyFrameFormat *pFormat ) +{ + if ( pFormat ) + pFormat->Add( &m_aNext ); + else + m_aNext.EndListeningAll(); +} + +bool SwFormatChain::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + // here we convert always! + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + OUString aRet; + switch ( nMemberId ) + { + case MID_CHAIN_PREVNAME: + if ( GetPrev() ) + aRet = GetPrev()->GetName(); + break; + case MID_CHAIN_NEXTNAME: + if ( GetNext() ) + aRet = GetNext()->GetName(); + break; + default: + OSL_ENSURE( false, "unknown MemberId" ); + bRet = false; + } + rVal <<= aRet; + return bRet; +} + +SwFormatLineNumber::SwFormatLineNumber() : + SfxPoolItem( RES_LINENUMBER ) +{ + m_nStartValue = 0; + m_bCountLines = true; +} + +SwFormatLineNumber::~SwFormatLineNumber() +{ +} + +bool SwFormatLineNumber::operator==( const SfxPoolItem &rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + + return m_nStartValue == static_cast(rAttr).GetStartValue() && + m_bCountLines == static_cast(rAttr).IsCount(); +} + +SwFormatLineNumber* SwFormatLineNumber::Clone( SfxItemPool* ) const +{ + return new SwFormatLineNumber( *this ); +} + +bool SwFormatLineNumber::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + // here we convert always! + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_LINENUMBER_COUNT: + rVal <<= IsCount(); + break; + case MID_LINENUMBER_STARTVALUE: + rVal <<= static_cast(GetStartValue()); + break; + default: + OSL_ENSURE( false, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + +bool SwFormatLineNumber::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + // here we convert always! + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_LINENUMBER_COUNT: + SetCountLines( *o3tl::doAccess(rVal) ); + break; + case MID_LINENUMBER_STARTVALUE: + { + sal_Int32 nVal = 0; + if(rVal >>= nVal) + SetStartValue( nVal ); + else + bRet = false; + } + break; + default: + OSL_ENSURE( false, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + +SwTextGridItem::SwTextGridItem() + : SfxPoolItem( RES_TEXTGRID ), m_aColor( COL_LIGHTGRAY ), m_nLines( 20 ) + , m_nBaseHeight( 400 ), m_nRubyHeight( 200 ), m_eGridType( GRID_NONE ) + , m_bRubyTextBelow( false ), m_bPrintGrid( true ), m_bDisplayGrid( true ) + , m_nBaseWidth(400), m_bSnapToChars( true ), m_bSquaredMode(true) +{ +} + +SwTextGridItem::~SwTextGridItem() +{ +} + +bool SwTextGridItem::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + SwTextGridItem const& rOther(static_cast(rAttr)); + return m_eGridType == rOther.GetGridType() + && m_nLines == rOther.GetLines() + && m_nBaseHeight == rOther.GetBaseHeight() + && m_nRubyHeight == rOther.GetRubyHeight() + && m_bRubyTextBelow == rOther.GetRubyTextBelow() + && m_bDisplayGrid == rOther.GetDisplayGrid() + && m_bPrintGrid == rOther.GetPrintGrid() + && m_aColor == rOther.GetColor() + && m_nBaseWidth == rOther.GetBaseWidth() + && m_bSnapToChars == rOther.GetSnapToChars() + && m_bSquaredMode == rOther.GetSquaredMode(); +} + +SwTextGridItem* SwTextGridItem::Clone( SfxItemPool* ) const +{ + return new SwTextGridItem( *this ); +} + +bool SwTextGridItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + bool bRet = true; + + switch( nMemberId & ~CONVERT_TWIPS ) + { + case MID_GRID_COLOR: + rVal <<= GetColor(); + break; + case MID_GRID_LINES: + rVal <<= GetLines(); + break; + case MID_GRID_RUBY_BELOW: + rVal <<= m_bRubyTextBelow; + break; + case MID_GRID_PRINT: + rVal <<= m_bPrintGrid; + break; + case MID_GRID_DISPLAY: + rVal <<= m_bDisplayGrid; + break; + case MID_GRID_BASEHEIGHT: + OSL_ENSURE( (nMemberId & CONVERT_TWIPS) != 0, + "This value needs TWIPS-MM100 conversion" ); + rVal <<= static_cast(convertTwipToMm100(m_nBaseHeight)); + break; + case MID_GRID_BASEWIDTH: + OSL_ENSURE( (nMemberId & CONVERT_TWIPS) != 0, + "This value needs TWIPS-MM100 conversion" ); + rVal <<= static_cast(convertTwipToMm100(m_nBaseWidth)); + break; + case MID_GRID_RUBYHEIGHT: + OSL_ENSURE( (nMemberId & CONVERT_TWIPS) != 0, + "This value needs TWIPS-MM100 conversion" ); + rVal <<= static_cast(convertTwipToMm100(m_nRubyHeight)); + break; + case MID_GRID_TYPE: + switch( GetGridType() ) + { + case GRID_NONE: + rVal <<= text::TextGridMode::NONE; + break; + case GRID_LINES_ONLY: + rVal <<= text::TextGridMode::LINES; + break; + case GRID_LINES_CHARS: + rVal <<= text::TextGridMode::LINES_AND_CHARS; + break; + default: + OSL_FAIL("unknown SwTextGrid value"); + bRet = false; + break; + } + break; + case MID_GRID_SNAPTOCHARS: + rVal <<= m_bSnapToChars; + break; + case MID_GRID_STANDARD_MODE: + rVal <<= !m_bSquaredMode; + break; + default: + OSL_FAIL("Unknown SwTextGridItem member"); + bRet = false; + break; + } + + return bRet; +} + +bool SwTextGridItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + bool bRet = true; + switch( nMemberId & ~CONVERT_TWIPS ) + { + case MID_GRID_COLOR: + { + sal_Int32 nTmp = 0; + bRet = (rVal >>= nTmp); + if( bRet ) + SetColor( Color(nTmp) ); + } + break; + case MID_GRID_LINES: + { + sal_Int16 nTmp = 0; + bRet = (rVal >>= nTmp); + if( bRet && (nTmp >= 0) ) + SetLines( static_cast(nTmp) ); + else + bRet = false; + } + break; + case MID_GRID_RUBY_BELOW: + SetRubyTextBelow( *o3tl::doAccess(rVal) ); + break; + case MID_GRID_PRINT: + SetPrintGrid( *o3tl::doAccess(rVal) ); + break; + case MID_GRID_DISPLAY: + SetDisplayGrid( *o3tl::doAccess(rVal) ); + break; + case MID_GRID_BASEHEIGHT: + case MID_GRID_BASEWIDTH: + case MID_GRID_RUBYHEIGHT: + { + OSL_ENSURE( (nMemberId & CONVERT_TWIPS) != 0, + "This value needs TWIPS-MM100 conversion" ); + sal_Int32 nTmp = 0; + bRet = (rVal >>= nTmp); + nTmp = convertMm100ToTwip( nTmp ); + if( bRet && (nTmp >= 0) && ( nTmp <= SAL_MAX_UINT16) ) + { + // rhbz#1043551 round up to 5pt -- 0 causes divide-by-zero + // in layout; 1pt ties the painting code up in knots for + // minutes with bazillion lines... +#define MIN_TEXTGRID_SIZE 100 + if( (nMemberId & ~CONVERT_TWIPS) == MID_GRID_BASEHEIGHT ) + { + nTmp = std::max(nTmp, MIN_TEXTGRID_SIZE); + SetBaseHeight( static_cast(nTmp) ); + } + else if( (nMemberId & ~CONVERT_TWIPS) == MID_GRID_BASEWIDTH ) + { + nTmp = std::max(nTmp, MIN_TEXTGRID_SIZE); + SetBaseWidth( static_cast(nTmp) ); + } + else + SetRubyHeight( static_cast(nTmp) ); + } + else + bRet = false; + } + break; + case MID_GRID_TYPE: + { + sal_Int16 nTmp = 0; + bRet = (rVal >>= nTmp); + if( bRet ) + { + switch( nTmp ) + { + case text::TextGridMode::NONE: + SetGridType( GRID_NONE ); + break; + case text::TextGridMode::LINES: + SetGridType( GRID_LINES_ONLY ); + break; + case text::TextGridMode::LINES_AND_CHARS: + SetGridType( GRID_LINES_CHARS ); + break; + default: + bRet = false; + break; + } + } + break; + } + case MID_GRID_SNAPTOCHARS: + SetSnapToChars( *o3tl::doAccess(rVal) ); + break; + case MID_GRID_STANDARD_MODE: + { + bool bStandard = *o3tl::doAccess(rVal); + SetSquaredMode( !bStandard ); + break; + } + default: + OSL_FAIL("Unknown SwTextGridItem member"); + bRet = false; + } + + return bRet; +} + +void SwTextGridItem::SwitchPaperMode(bool bNew) +{ + if (bNew == m_bSquaredMode) + { + //same paper mode, not switch + return; + } + + // use default value when grid is disable + if (m_eGridType == GRID_NONE) + { + m_bSquaredMode = bNew; + Init(); + return; + } + + if (m_bSquaredMode) + { + //switch from "squared mode" to "standard mode" + m_nBaseWidth = m_nBaseHeight; + m_nBaseHeight = m_nBaseHeight + m_nRubyHeight; + m_nRubyHeight = 0; + } + else + { + //switch from "standard mode" to "squared mode" + m_nRubyHeight = m_nBaseHeight/3; + m_nBaseHeight = m_nBaseHeight - m_nRubyHeight; + m_nBaseWidth = m_nBaseHeight; + } + m_bSquaredMode = !m_bSquaredMode; +} + +void SwTextGridItem::Init() +{ + if (m_bSquaredMode) + { + m_nLines = 20; + m_nBaseHeight = 400; + m_nRubyHeight = 200; + m_eGridType = GRID_NONE; + m_bRubyTextBelow = false; + m_bPrintGrid = true; + m_bDisplayGrid = true; + m_bSnapToChars = true; + m_nBaseWidth = 400; + } + else + { + m_nLines = 44; + m_nBaseHeight = 312; + m_nRubyHeight = 0; + m_eGridType = GRID_NONE; + m_bRubyTextBelow = false; + m_bPrintGrid = true; + m_bDisplayGrid = true; + m_nBaseWidth = 210; + m_bSnapToChars = true; + } +} + +SwHeaderAndFooterEatSpacingItem* SwHeaderAndFooterEatSpacingItem::Clone( SfxItemPool* ) const +{ + return new SwHeaderAndFooterEatSpacingItem( Which(), GetValue() ); +} + +SwFrameFormat::SwFrameFormat( + SwAttrPool& rPool, + const char* pFormatNm, + SwFrameFormat *pDrvdFrame, + sal_uInt16 nFormatWhich, + const sal_uInt16* pWhichRange) +: SwFormat(rPool, pFormatNm, (pWhichRange ? pWhichRange : aFrameFormatSetRange), pDrvdFrame, nFormatWhich), + m_wXObject(), + maFillAttributes(), + m_ffList(nullptr), + m_pOtherTextBoxFormat(nullptr) +{ +} + +SwFrameFormat::SwFrameFormat( + SwAttrPool& rPool, + const OUString &rFormatNm, + SwFrameFormat *pDrvdFrame, + sal_uInt16 nFormatWhich, + const sal_uInt16* pWhichRange) +: SwFormat(rPool, rFormatNm, (pWhichRange ? pWhichRange : aFrameFormatSetRange), pDrvdFrame, nFormatWhich), + m_wXObject(), + maFillAttributes(), + m_ffList(nullptr), + m_pOtherTextBoxFormat(nullptr) +{ +} + +SwFrameFormat::~SwFrameFormat() +{ + if( !GetDoc()->IsInDtor()) + { + const SwFormatAnchor& rAnchor = GetAnchor(); + if (rAnchor.GetContentAnchor() != nullptr) + { + rAnchor.GetContentAnchor()->nNode.GetNode().RemoveAnchoredFly(this); + } + } + + if( nullptr != m_pOtherTextBoxFormat ) + { + m_pOtherTextBoxFormat->SetOtherTextBoxFormat( nullptr ); + m_pOtherTextBoxFormat = nullptr; + } +} + +void SwFrameFormat::SetName( const OUString& rNewName, bool bBroadcast ) +{ + if (m_ffList != nullptr) { + SwFrameFormats::iterator it = m_ffList->find( this ); + assert( m_ffList->end() != it ); + SAL_INFO_IF(m_aFormatName == rNewName, "sw.core", "SwFrmFmt not really renamed, as both names are equal"); + + SwStringMsgPoolItem aOld( RES_NAME_CHANGED, m_aFormatName ); + // As it's a non-unique list, rename should never fail! + bool const renamed = + m_ffList->m_PosIndex.modify( it, + change_name( rNewName ), change_name( m_aFormatName ) ); + assert(renamed); + (void)renamed; // unused in NDEBUG + if (bBroadcast) { + SwStringMsgPoolItem aNew( RES_NAME_CHANGED, rNewName ); + ModifyNotification( &aOld, &aNew ); + } + } + else + SwFormat::SetName( rNewName, bBroadcast ); +} + +void SwFrameFormat::SetOtherTextBoxFormat( SwFrameFormat *pFormat ) +{ + if( nullptr != pFormat ) + { + assert( (Which() == RES_DRAWFRMFMT && pFormat->Which() == RES_FLYFRMFMT) + || (Which() == RES_FLYFRMFMT && pFormat->Which() == RES_DRAWFRMFMT) ); + assert( nullptr == m_pOtherTextBoxFormat ); + } + else + { + assert( nullptr != m_pOtherTextBoxFormat ); + } + bool bChanged = m_pOtherTextBoxFormat != pFormat; + m_pOtherTextBoxFormat = pFormat; + + SdrObject* pObj = FindSdrObject(); + + if (pObj) + { + SwFlyDrawObj* pSwFlyDraw = dynamic_cast(pObj); + + if (pSwFlyDraw) + pSwFlyDraw->SetTextBox(true); + } + + if (m_pOtherTextBoxFormat && bChanged && Which() == RES_DRAWFRMFMT) + { + // This is a shape of a shape+frame pair and my frame has changed. Make sure my content is + // in sync with the frame's content. + if (GetAttrSet().GetContent() != m_pOtherTextBoxFormat->GetAttrSet().GetContent()) + { + SwAttrSet aSet(GetAttrSet()); + SwFormatContent aContent(m_pOtherTextBoxFormat->GetAttrSet().GetContent()); + aSet.Put(aContent); + SetFormatAttr(aSet); + } + } +} + +bool SwFrameFormat::supportsFullDrawingLayerFillAttributeSet() const +{ + return true; +} + +void SwFrameFormat::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew ) +{ + if (pNew) + { + SwFormatHeader const *pH = nullptr; + SwFormatFooter const *pF = nullptr; + + const sal_uInt16 nWhich = pNew->Which(); + + if( RES_ATTRSET_CHG == nWhich ) + { + static_cast(pNew)->GetChgSet()->GetItemState( + RES_HEADER, false, reinterpret_cast(&pH) ); + static_cast(pNew)->GetChgSet()->GetItemState( + RES_FOOTER, false, reinterpret_cast(&pF) ); + + // reset fill information + if (maFillAttributes && supportsFullDrawingLayerFillAttributeSet()) + { + SfxItemIter aIter(*static_cast(pNew)->GetChgSet()); + bool bReset(false); + + for(const SfxPoolItem* pItem = aIter.GetCurItem(); pItem && !bReset; pItem = aIter.NextItem()) + { + bReset = !IsInvalidItem(pItem) && pItem->Which() >= XATTR_FILL_FIRST && pItem->Which() <= XATTR_FILL_LAST; + } + + if(bReset) + { + maFillAttributes.reset(); + } + } + } + else if(RES_FMT_CHG == nWhich) + { + // reset fill information on format change (e.g. style changed) + if (maFillAttributes && supportsFullDrawingLayerFillAttributeSet()) + { + maFillAttributes.reset(); + } + } + else if( RES_HEADER == nWhich ) + pH = static_cast(pNew); + else if( RES_FOOTER == nWhich ) + pF = static_cast(pNew); + + if( pH && pH->IsActive() && !pH->GetHeaderFormat() ) + { //If he doesn't have one, I'll add one + SwFrameFormat *pFormat = GetDoc()->getIDocumentLayoutAccess().MakeLayoutFormat( RndStdIds::HEADER, nullptr ); + const_cast(pH)->RegisterToFormat( *pFormat ); + } + + if( pF && pF->IsActive() && !pF->GetFooterFormat() ) + { //If he doesn't have one, I'll add one + SwFrameFormat *pFormat = GetDoc()->getIDocumentLayoutAccess().MakeLayoutFormat( RndStdIds::FOOTER, nullptr ); + const_cast(pF)->RegisterToFormat( *pFormat ); + } + } + + SwFormat::Modify( pOld, pNew ); + + if (pOld && (RES_REMOVE_UNO_OBJECT == pOld->Which())) + { // invalidate cached uno object + SetXObject(uno::Reference(nullptr)); + } + + const SwPosition* oldAnchorPosition = nullptr; + const SwPosition* newAnchorPosition = nullptr; + if( pNew && pNew->Which() == RES_ATTRSET_CHG ) + { + const SfxPoolItem* tmp = nullptr; + static_cast< const SwAttrSetChg* >(pNew)->GetChgSet()->GetItemState( RES_ANCHOR, false, &tmp ); + if( tmp ) + { + newAnchorPosition = static_cast< const SwFormatAnchor* >( tmp )->GetContentAnchor(); + assert(newAnchorPosition == nullptr || // style's set must not contain position! + static_cast(pNew)->GetTheChgdSet() == &m_aSet); + } + } + if( pNew && pNew->Which() == RES_ANCHOR ) + newAnchorPosition = static_cast< const SwFormatAnchor* >( pNew )->GetContentAnchor(); + if( pOld && pOld->Which() == RES_ATTRSET_CHG ) + { + const SfxPoolItem* tmp = nullptr; + static_cast< const SwAttrSetChg* >(pOld)->GetChgSet()->GetItemState( RES_ANCHOR, false, &tmp ); + if( tmp ) + { + oldAnchorPosition = static_cast< const SwFormatAnchor* >( tmp )->GetContentAnchor(); + assert(oldAnchorPosition == nullptr || // style's set must not contain position! + static_cast(pOld)->GetTheChgdSet() == &m_aSet); + } + } + if( pOld && pOld->Which() == RES_ANCHOR ) + oldAnchorPosition = static_cast< const SwFormatAnchor* >( pOld )->GetContentAnchor(); + if( oldAnchorPosition != nullptr && ( newAnchorPosition == nullptr || oldAnchorPosition->nNode.GetIndex() != newAnchorPosition->nNode.GetIndex())) + { + oldAnchorPosition->nNode.GetNode().RemoveAnchoredFly(this); + } + if( newAnchorPosition != nullptr && ( oldAnchorPosition == nullptr || oldAnchorPosition->nNode.GetIndex() != newAnchorPosition->nNode.GetIndex())) + { + newAnchorPosition->nNode.GetNode().AddAnchoredFly(this); + } +} + +void SwFrameFormat::RegisterToFormat( SwFormat& rFormat ) +{ + rFormat.Add( this ); +} + +/// Delete all Frames that are registered in aDepend. +void SwFrameFormat::DelFrames() +{ + SwIterator aIter( *this ); + SwFrame * pLast = aIter.First(); + if( pLast ) + do { + pLast->Cut(); + SwFrame::DestroyFrame(pLast); + } while( nullptr != ( pLast = aIter.Next() )); +} + +void SwFrameFormat::MakeFrames() +{ + assert(false); // unimplemented in base class +} + +SwRect SwFrameFormat::FindLayoutRect( const bool bPrtArea, const Point* pPoint ) const +{ + SwRect aRet; + SwFrame *pFrame = nullptr; + if( dynamic_cast( this ) != nullptr ) + { + // get the Frame using Node2Layout + const SwSectionNode* pSectNd = static_cast(this)->GetSectionNode(); + if( pSectNd ) + { + SwNode2Layout aTmp( *pSectNd, pSectNd->GetIndex() - 1 ); + pFrame = aTmp.NextFrame(); + + if( pFrame && !pFrame->KnowsFormat(*this) ) + { + // the Section doesn't have his own Frame, so if someone + // needs the real size, we have to implement this by requesting + // the matching Frame from the end. + // PROBLEM: what happens if SectionFrames overlaps multiple + // pages? + if( bPrtArea ) + aRet = pFrame->getFramePrintArea(); + else + { + aRet = pFrame->getFrameArea(); + aRet.Pos().AdjustY( -1 ); + } + pFrame = nullptr; // the rect is finished by now + } + } + } + else + { + const SwFrameType nFrameType = RES_FLYFRMFMT == Which() ? SwFrameType::Fly : FRM_ALL; + std::pair tmp; + if (pPoint) + { + tmp.first = *pPoint; + tmp.second = false; + } + pFrame = ::GetFrameOfModify(nullptr, *this, nFrameType, nullptr, pPoint ? &tmp : nullptr); + } + + if( pFrame ) + { + if( bPrtArea ) + aRet = pFrame->getFramePrintArea(); + else + aRet = pFrame->getFrameArea(); + } + return aRet; +} + +SdrObject* SwFrameFormat::FindRealSdrObject() +{ + if( RES_FLYFRMFMT == Which() ) + { + Point aNullPt; + std::pair const tmp(aNullPt, false); + SwFlyFrame* pFly = static_cast(::GetFrameOfModify( nullptr, *this, SwFrameType::Fly, + nullptr, &tmp)); + return pFly ? pFly->GetVirtDrawObj() : nullptr; + } + return FindSdrObject(); +} + +bool SwFrameFormat::IsLowerOf( const SwFrameFormat& rFormat ) const +{ + //Also linking from inside to outside or from outside to inside is not + //allowed. + SwFlyFrame *pSFly = SwIterator(*this).First(); + if( pSFly ) + { + SwFlyFrame *pAskFly = SwIterator(rFormat).First(); + if( pAskFly ) + return pSFly->IsLowerOf( pAskFly ); + } + + // let's try it using the node positions + const SwFormatAnchor* pAnchor = &rFormat.GetAnchor(); + if ((RndStdIds::FLY_AT_PAGE != pAnchor->GetAnchorId()) && pAnchor->GetContentAnchor()) + { + const SwFrameFormats& rFormats = *GetDoc()->GetSpzFrameFormats(); + const SwNode* pFlyNd = pAnchor->GetContentAnchor()->nNode.GetNode(). + FindFlyStartNode(); + while( pFlyNd ) + { + // then we walk up using the anchor + size_t n; + for( n = 0; n < rFormats.size(); ++n ) + { + const SwFrameFormat* pFormat = rFormats[ n ]; + const SwNodeIndex* pIdx = pFormat->GetContent().GetContentIdx(); + if( pIdx && pFlyNd == &pIdx->GetNode() ) + { + if( pFormat == this ) + return true; + + pAnchor = &pFormat->GetAnchor(); + if ((RndStdIds::FLY_AT_PAGE == pAnchor->GetAnchorId()) || + !pAnchor->GetContentAnchor() ) + { + return false; + } + + pFlyNd = pAnchor->GetContentAnchor()->nNode.GetNode(). + FindFlyStartNode(); + break; + } + } + if( n >= rFormats.size() ) + { + OSL_ENSURE( false, "Fly section but no format found" ); + return false; + } + } + } + return false; +} + +// #i31698# +SwFrameFormat::tLayoutDir SwFrameFormat::GetLayoutDir() const +{ + return SwFrameFormat::HORI_L2R; +} + +void SwFrameFormat::SetLayoutDir( const SwFrameFormat::tLayoutDir ) +{ + // empty body, because default implementation does nothing +} + +// #i28749# +sal_Int16 SwFrameFormat::GetPositionLayoutDir() const +{ + return text::PositionLayoutDir::PositionInLayoutDirOfAnchor; +} +void SwFrameFormat::SetPositionLayoutDir( const sal_Int16 ) +{ + // empty body, because default implementation does nothing +} + +OUString SwFrameFormat::GetDescription() const +{ + return SwResId(STR_FRAME); +} + +void SwFrameFormat::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + xmlTextWriterStartElement(pWriter, BAD_CAST("SwFrameFormat")); + xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("name"), BAD_CAST(GetName().toUtf8().getStr())); + xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("whichId"), "%d", Which()); + + const char* pWhich = nullptr; + switch (Which()) + { + case RES_FLYFRMFMT: + pWhich = "fly frame format"; + break; + case RES_DRAWFRMFMT: + pWhich = "draw frame format"; + break; + } + if (pWhich) + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("which"), BAD_CAST(pWhich)); + + if (m_pOtherTextBoxFormat) + { + xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("OtherTextBoxFormat"), "%p", m_pOtherTextBoxFormat); + } + + GetAttrSet().dumpAsXml(pWriter); + + if (const SdrObject* pSdrObject = FindSdrObject()) + pSdrObject->dumpAsXml(pWriter); + + xmlTextWriterEndElement(pWriter); +} + +void SwFrameFormats::dumpAsXml(xmlTextWriterPtr pWriter, const char* pName) const +{ + xmlTextWriterStartElement(pWriter, BAD_CAST(pName)); + for (const SwFrameFormat *pFormat : m_PosIndex) + pFormat->dumpAsXml(pWriter); + xmlTextWriterEndElement(pWriter); +} + + +SwFlyFrameFormat::SwFlyFrameFormat( SwAttrPool& rPool, const OUString &rFormatNm, SwFrameFormat *pDrvdFrame ) + : SwFrameFormat( rPool, rFormatNm, pDrvdFrame, RES_FLYFRMFMT ) +{} + +SwFlyFrameFormat::~SwFlyFrameFormat() +{ + SwIterator aIter( *this ); + SwFlyFrame * pLast = aIter.First(); + if( pLast ) + do + { + SwFrame::DestroyFrame(pLast); + } while( nullptr != ( pLast = aIter.Next() )); + +} + +SwFlyDrawContact* SwFlyFrameFormat::GetOrCreateContact() +{ + if(!m_pContact) + { + SwDrawModel* pDrawModel(GetDoc()->getIDocumentDrawModelAccess().GetOrCreateDrawModel()); + m_pContact.reset(new SwFlyDrawContact(this, *pDrawModel)); + } + + return m_pContact.get(); +} + +/// Creates the Frames if the format describes a paragraph-bound frame. +/// MA: 1994-02-14: creates the Frames also for frames anchored at page. +void SwFlyFrameFormat::MakeFrames() +{ + // is there a layout? + if( !GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell() ) + return; + + SwModify *pModify = nullptr; + // OD 24.07.2003 #111032# - create local copy of anchor attribute for possible changes. + SwFormatAnchor aAnchorAttr( GetAnchor() ); + switch( aAnchorAttr.GetAnchorId() ) + { + case RndStdIds::FLY_AS_CHAR: + case RndStdIds::FLY_AT_PARA: + case RndStdIds::FLY_AT_CHAR: + if( aAnchorAttr.GetContentAnchor() ) + { + pModify = aAnchorAttr.GetContentAnchor()->nNode.GetNode().GetContentNode(); + } + break; + + case RndStdIds::FLY_AT_FLY: + if( aAnchorAttr.GetContentAnchor() ) + { + //First search in the content because this is O(1) + //This can go wrong for linked frames because in this case it's + //possible, that no Frame exists for this content. + //In such a situation we also need to search from StartNode to + //FrameFormat. + SwNodeIndex aIdx( aAnchorAttr.GetContentAnchor()->nNode ); + SwContentNode *pCNd = GetDoc()->GetNodes().GoNext( &aIdx ); + // #i105535# + if ( pCNd == nullptr ) + { + pCNd = aAnchorAttr.GetContentAnchor()->nNode.GetNode().GetContentNode(); + } + if ( pCNd ) + { + if (SwIterator(*pCNd).First()) + { + pModify = pCNd; + } + } + // #i105535# + if ( pModify == nullptr ) + { + const SwNodeIndex &rIdx = aAnchorAttr.GetContentAnchor()->nNode; + SwFrameFormats& rFormats = *GetDoc()->GetSpzFrameFormats(); + for( size_t i = 0; i < rFormats.size(); ++i ) + { + SwFrameFormat* pFlyFormat = rFormats[i]; + if( pFlyFormat->GetContent().GetContentIdx() && + rIdx == *pFlyFormat->GetContent().GetContentIdx() ) + { + pModify = pFlyFormat; + break; + } + } + } + } + break; + + case RndStdIds::FLY_AT_PAGE: + { + sal_uInt16 nPgNum = aAnchorAttr.GetPageNum(); + SwPageFrame *pPage = static_cast(GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout()->Lower()); + if( nPgNum == 0 && aAnchorAttr.GetContentAnchor() ) + { + SwContentNode *pCNd = aAnchorAttr.GetContentAnchor()->nNode.GetNode().GetContentNode(); + SwIterator aIter(*pCNd); + for ( SwFrame* pFrame = aIter.First(); pFrame != nullptr; pFrame = aIter.Next() ) + { + pPage = pFrame->FindPageFrame(); + if( pPage ) + { + nPgNum = pPage->GetPhyPageNum(); + aAnchorAttr.SetPageNum( nPgNum ); + aAnchorAttr.SetAnchor( nullptr ); + SetFormatAttr( aAnchorAttr ); + break; + } + } + } + while ( pPage ) + { + if ( pPage->GetPhyPageNum() == nPgNum ) + { + // #i50432# - adjust synopsis of + pPage->PlaceFly( nullptr, this ); + break; + } + pPage = static_cast(pPage->GetNext()); + } + } + break; + default: + break; + } + + if( pModify ) + { + SwIterator aIter(*pModify); + for( SwFrame *pFrame = aIter.First(); pFrame; pFrame = aIter.Next() ) + { + bool bAdd = !pFrame->IsContentFrame() || + !static_cast(pFrame)->IsFollow(); + + if ( RndStdIds::FLY_AT_FLY == aAnchorAttr.GetAnchorId() && !pFrame->IsFlyFrame() ) + { + SwFrame* pFlyFrame = pFrame->FindFlyFrame(); + if ( pFlyFrame ) + { + pFrame = pFlyFrame; + } + else + { + aAnchorAttr.SetType( RndStdIds::FLY_AT_PARA ); + SetFormatAttr( aAnchorAttr ); + MakeFrames(); + return; + } + } + + if (bAdd) + { + switch (aAnchorAttr.GetAnchorId()) + { + case RndStdIds::FLY_AS_CHAR: + case RndStdIds::FLY_AT_PARA: + case RndStdIds::FLY_AT_CHAR: + { + assert(pFrame->IsTextFrame()); + bAdd = IsAnchoredObjShown(*static_cast(pFrame), aAnchorAttr); + } + break; + default: + break; + } + } + + if (bAdd && pFrame->GetDrawObjs()) + { + // #i28701# - new type + SwSortedObjs &rObjs = *pFrame->GetDrawObjs(); + for(SwAnchoredObject* pObj : rObjs) + { + // #i28701# - consider changed type of + // entries. + if( dynamic_cast( pObj) != nullptr && + (&pObj->GetFrameFormat()) == this ) + { + bAdd = false; + break; + } + } + } + + if( bAdd ) + { + SwFlyFrame *pFly = nullptr; // avoid warnings + switch( aAnchorAttr.GetAnchorId() ) + { + case RndStdIds::FLY_AT_FLY: + pFly = new SwFlyLayFrame( this, pFrame, pFrame ); + break; + + case RndStdIds::FLY_AT_PARA: + case RndStdIds::FLY_AT_CHAR: + pFly = new SwFlyAtContentFrame( this, pFrame, pFrame ); + break; + + case RndStdIds::FLY_AS_CHAR: + pFly = new SwFlyInContentFrame( this, pFrame, pFrame ); + break; + + default: + assert(false && "New anchor type" ); + } + pFrame->AppendFly( pFly ); + pFly->GetFormat()->SetObjTitle(GetObjTitle()); + pFly->GetFormat()->SetObjDescription(GetObjDescription()); + SwPageFrame *pPage = pFly->FindPageFrame(); + if( pPage ) + ::RegistFlys( pPage, pFly ); + } + } + } +} + +SwFlyFrame* SwFlyFrameFormat::GetFrame( const Point* pPoint ) const +{ + std::pair tmp; + if (pPoint) + { + tmp.first = *pPoint; + tmp.second = false; + } + return static_cast(::GetFrameOfModify( nullptr, *this, SwFrameType::Fly, + nullptr, &tmp)); +} + +SwAnchoredObject* SwFlyFrameFormat::GetAnchoredObj() const +{ + SwFlyFrame* pFlyFrame( GetFrame() ); + if ( pFlyFrame ) + { + return dynamic_cast(pFlyFrame); + } + else + { + return nullptr; + } +} + +bool SwFlyFrameFormat::GetInfo( SfxPoolItem& rInfo ) const +{ + bool bRet = true; + switch( rInfo.Which() ) + { + case RES_CONTENT_VISIBLE: + { + static_cast(rInfo).pObject = SwIterator( *this ).First(); + } + bRet = false; + break; + + default: + bRet = SwFrameFormat::GetInfo( rInfo ); + break; + } + return bRet; +} + +// #i73249# +void SwFlyFrameFormat::SetObjTitle( const OUString& rTitle, bool bBroadcast ) +{ + SdrObject* pMasterObject = FindSdrObject(); + OSL_ENSURE( pMasterObject, " - missing instance" ); + msTitle = rTitle; + if ( !pMasterObject ) + { + return; + } + + if( bBroadcast ) + { + SwStringMsgPoolItem aOld( RES_TITLE_CHANGED, pMasterObject->GetTitle() ); + SwStringMsgPoolItem aNew( RES_TITLE_CHANGED, rTitle ); + pMasterObject->SetTitle( rTitle ); + ModifyNotification( &aOld, &aNew ); + } + else + { + pMasterObject->SetTitle( rTitle ); + } +} + +OUString SwFlyFrameFormat::GetObjTitle() const +{ + const SdrObject* pMasterObject = FindSdrObject(); + OSL_ENSURE( pMasterObject, " - missing instance" ); + if ( !pMasterObject ) + { + return msTitle; + } + if (!pMasterObject->GetTitle().isEmpty()) + return pMasterObject->GetTitle(); + else + return msTitle; +} + +void SwFlyFrameFormat::SetObjDescription( const OUString& rDescription, bool bBroadcast ) +{ + SdrObject* pMasterObject = FindSdrObject(); + OSL_ENSURE( pMasterObject, " - missing instance" ); + msDesc = rDescription; + if ( !pMasterObject ) + { + return; + } + + if( bBroadcast ) + { + SwStringMsgPoolItem aOld( RES_DESCRIPTION_CHANGED, pMasterObject->GetDescription() ); + SwStringMsgPoolItem aNew( RES_DESCRIPTION_CHANGED, rDescription ); + pMasterObject->SetDescription( rDescription ); + ModifyNotification( &aOld, &aNew ); + } + else + { + pMasterObject->SetDescription( rDescription ); + } +} + +OUString SwFlyFrameFormat::GetObjDescription() const +{ + const SdrObject* pMasterObject = FindSdrObject(); + OSL_ENSURE( pMasterObject, " - missing instance" ); + if ( !pMasterObject ) + { + return msDesc; + } + if (!pMasterObject->GetDescription().isEmpty()) + return pMasterObject->GetDescription(); + else + return msDesc; +} + +/** SwFlyFrameFormat::IsBackgroundTransparent - for #99657# + + OD 22.08.2002 - overriding virtual method and its default implementation, + because format of fly frame provides transparent backgrounds. + Method determines, if background of fly frame is transparent. + + @return true, if background color is transparent, but not "no fill" + or the transparency of an existing background graphic is set. +*/ +bool SwFlyFrameFormat::IsBackgroundTransparent() const +{ + if (supportsFullDrawingLayerFillAttributeSet() && getSdrAllFillAttributesHelper()) + { + return getSdrAllFillAttributesHelper()->isTransparent(); + } + + // NOTE: If background color is "no fill"/"auto fill" (COL_TRANSPARENT) + // and there is no background graphic, it "inherites" the background + // from its anchor. + std::unique_ptr aBackground(makeBackgroundBrushItem()); + if ( aBackground && + (aBackground->GetColor().GetTransparency() != 0) && + (aBackground->GetColor() != COL_TRANSPARENT) + ) + { + return true; + } + else + { + const GraphicObject *pTmpGrf = aBackground->GetGraphicObject(); + if ( pTmpGrf && + (pTmpGrf->GetAttr().GetTransparency() != 0) + ) + { + return true; + } + } + + return false; +} + +/** SwFlyFrameFormat::IsBackgroundBrushInherited - for #103898# + + OD 08.10.2002 - method to determine, if the brush for drawing the + background is "inherited" from its parent/grandparent. + This is the case, if no background graphic is set and the background + color is "no fill"/"auto fill" + NOTE: condition is "copied" from method isUsed(); + } + else + { + std::unique_ptr aBackground(makeBackgroundBrushItem()); + if ( aBackground && + (aBackground->GetColor() == COL_TRANSPARENT) && + !(aBackground->GetGraphicObject()) ) + { + return true; + } + } + + return false; +} + +SwHandleAnchorNodeChg::SwHandleAnchorNodeChg( SwFlyFrameFormat& _rFlyFrameFormat, + const SwFormatAnchor& _rNewAnchorFormat, + SwFlyFrame const * _pKeepThisFlyFrame ) + : mrFlyFrameFormat( _rFlyFrameFormat ), + mbAnchorNodeChanged( false ), + mpWrtShell(nullptr) +{ + const SwFormatAnchor& aOldAnchorFormat(_rFlyFrameFormat.GetAnchor()); + const RndStdIds nNewAnchorType( _rNewAnchorFormat.GetAnchorId() ); + if ( ((nNewAnchorType == RndStdIds::FLY_AT_PARA) || + (nNewAnchorType == RndStdIds::FLY_AT_CHAR)) && + _rNewAnchorFormat.GetContentAnchor() && + _rNewAnchorFormat.GetContentAnchor()->nNode.GetNode().GetContentNode() ) + { + if ( aOldAnchorFormat.GetAnchorId() == nNewAnchorType && + aOldAnchorFormat.GetContentAnchor() && + aOldAnchorFormat.GetContentAnchor()->nNode.GetNode().GetContentNode() && + aOldAnchorFormat.GetContentAnchor()->nNode != + _rNewAnchorFormat.GetContentAnchor()->nNode ) + { + // determine 'old' number of anchor frames + sal_uInt32 nOldNumOfAnchFrame( 0 ); + SwIterator aOldIter( + *(aOldAnchorFormat.GetContentAnchor()->nNode.GetNode().GetContentNode()) ); + for( SwFrame* pOld = aOldIter.First(); pOld; pOld = aOldIter.Next() ) + { + ++nOldNumOfAnchFrame; + } + // determine 'new' number of anchor frames + sal_uInt32 nNewNumOfAnchFrame( 0 ); + SwIterator aNewIter( + *(_rNewAnchorFormat.GetContentAnchor()->nNode.GetNode().GetContentNode()) ); + for( SwFrame* pNew = aNewIter.First(); pNew; pNew = aNewIter.Next() ) + { + ++nNewNumOfAnchFrame; + } + if ( nOldNumOfAnchFrame != nNewNumOfAnchFrame ) + { + // delete existing fly frames except <_pKeepThisFlyFrame> + SwIterator aIter( mrFlyFrameFormat ); + SwFrame* pFrame = aIter.First(); + if ( pFrame ) + { + do { + if ( pFrame != _pKeepThisFlyFrame ) + { + pFrame->Cut(); + SwFrame::DestroyFrame(pFrame); + } + } while( nullptr != ( pFrame = aIter.Next() )); + } + // indicate, that re-creation of fly frames necessary + mbAnchorNodeChanged = true; + } + } + } + + if (aOldAnchorFormat.GetContentAnchor() + && aOldAnchorFormat.GetAnchorId() == RndStdIds::FLY_AT_CHAR) + { + mpCommentAnchor.reset(new SwPosition(*aOldAnchorFormat.GetContentAnchor())); + } + + if (_pKeepThisFlyFrame) + { + SwViewShell* pViewShell = _pKeepThisFlyFrame->getRootFrame()->GetCurrShell(); + mpWrtShell = dynamic_cast(pViewShell); + } +} + +SwHandleAnchorNodeChg::~SwHandleAnchorNodeChg() COVERITY_NOEXCEPT_FALSE +{ + if ( mbAnchorNodeChanged ) + { + mrFlyFrameFormat.MakeFrames(); + } + + // See if the fly frame had a comment: if so, move it to the new anchor as well. + if (!mpCommentAnchor) + { + return; + } + + SwTextNode* pTextNode = mpCommentAnchor->nNode.GetNode().GetTextNode(); + if (!pTextNode) + { + return; + } + + const SwTextField* pField = pTextNode->GetFieldTextAttrAt(mpCommentAnchor->nContent.GetIndex()); + if (!pField || pField->GetFormatField().GetField()->GetTyp()->Which() != SwFieldIds::Postit) + { + return; + } + + if (!mpWrtShell) + { + return; + } + + // Save current cursor position, so we can restore it later. + mpWrtShell->Push(); + + // Set up the source of the move: the old comment anchor. + { + SwPaM& rCursor = mpWrtShell->GetCurrentShellCursor(); + *rCursor.GetPoint() = *mpCommentAnchor; + rCursor.SetMark(); + *rCursor.GetMark() = *mpCommentAnchor; + ++rCursor.GetMark()->nContent; + } + + // Set up the target of the move: the new comment anchor. + const SwFormatAnchor& rNewAnchorFormat = mrFlyFrameFormat.GetAnchor(); + mpWrtShell->CreateCursor(); + *mpWrtShell->GetCurrentShellCursor().GetPoint() = *rNewAnchorFormat.GetContentAnchor(); + + // Move by copying and deleting. + mpWrtShell->SwEditShell::Copy(mpWrtShell); + mpWrtShell->DestroyCursor(); + + mpWrtShell->Delete(); + + mpWrtShell->Pop(SwCursorShell::PopMode::DeleteCurrent); +} + +namespace sw +{ + DrawFrameFormatHint::~DrawFrameFormatHint() {} + CheckDrawFrameFormatLayerHint::~CheckDrawFrameFormatLayerHint() {} + ContactChangedHint::~ContactChangedHint() {} + DrawFormatLayoutCopyHint::~DrawFormatLayoutCopyHint() {} + WW8AnchorConvHint::~WW8AnchorConvHint() {} + RestoreFlyAnchorHint::~RestoreFlyAnchorHint() {} + CreatePortionHint::~CreatePortionHint() {} + FindSdrObjectHint::~FindSdrObjectHint() {} + CollectTextObjectsHint::~CollectTextObjectsHint() {} + GetZOrderHint::~GetZOrderHint() {} + GetObjectConnectedHint::~GetObjectConnectedHint() {} +} + +SwDrawFrameFormat::~SwDrawFrameFormat() +{ + CallSwClientNotify(sw::DrawFrameFormatHint(sw::DrawFrameFormatHintId::DYING)); +} + +void SwDrawFrameFormat::MakeFrames() +{ + CallSwClientNotify(sw::DrawFrameFormatHint(sw::DrawFrameFormatHintId::MAKE_FRAMES)); +} + +void SwDrawFrameFormat::DelFrames() +{ + CallSwClientNotify(sw::DrawFrameFormatHint(sw::DrawFrameFormatHintId::DELETE_FRAMES)); +} + +// #i31698# +SwFrameFormat::tLayoutDir SwDrawFrameFormat::GetLayoutDir() const +{ + return meLayoutDir; +} + +void SwDrawFrameFormat::SetLayoutDir( const SwFrameFormat::tLayoutDir _eLayoutDir ) +{ + meLayoutDir = _eLayoutDir; +} + +// #i28749# +sal_Int16 SwDrawFrameFormat::GetPositionLayoutDir() const +{ + return mnPositionLayoutDir; +} +void SwDrawFrameFormat::SetPositionLayoutDir( const sal_Int16 _nPositionLayoutDir ) +{ + switch ( _nPositionLayoutDir ) + { + case text::PositionLayoutDir::PositionInHoriL2R: + case text::PositionLayoutDir::PositionInLayoutDirOfAnchor: + { + mnPositionLayoutDir = _nPositionLayoutDir; + } + break; + default: + { + OSL_FAIL( " - invalid attribute value." ); + } + } +} + +OUString SwDrawFrameFormat::GetDescription() const +{ + OUString aResult; + const SdrObject * pSdrObj = FindSdrObject(); + + if (pSdrObj) + { + if (pSdrObj != m_pSdrObjectCached) + { + m_sSdrObjectCachedComment = SdrUndoNewObj::GetComment(*pSdrObj); + m_pSdrObjectCached = pSdrObj; + } + + aResult = m_sSdrObjectCachedComment; + } + else + aResult = SwResId(STR_GRAPHIC); + + return aResult; +} + +IMapObject* SwFrameFormat::GetIMapObject( const Point& rPoint, + const SwFlyFrame *pFly ) const +{ + const SwFormatURL &rURL = GetURL(); + if( !rURL.GetMap() ) + return nullptr; + + if( !pFly ) + { + pFly = SwIterator( *this ).First(); + if( !pFly ) + return nullptr; + } + + //Original size for OLE and graphic is TwipSize, otherwise the size of + //FrameFormat of the Fly. + const SwFrame *pRef; + const SwNoTextNode *pNd = nullptr; + Size aOrigSz; + if( pFly->Lower() && pFly->Lower()->IsNoTextFrame() ) + { + pRef = pFly->Lower(); + pNd = static_cast(pRef)->GetNode()->GetNoTextNode(); + aOrigSz = pNd->GetTwipSize(); + } + else + { + pRef = pFly; + aOrigSz = pFly->GetFormat()->GetFrameSize().GetSize(); + } + + if( !aOrigSz.IsEmpty() ) + { + Point aPos( rPoint ); + Size aActSz ( pRef == pFly ? pFly->getFrameArea().SSize() : pRef->getFramePrintArea().SSize() ); + const MapMode aSrc ( MapUnit::MapTwip ); + const MapMode aDest( MapUnit::Map100thMM ); + aOrigSz = OutputDevice::LogicToLogic( aOrigSz, aSrc, aDest ); + aActSz = OutputDevice::LogicToLogic( aActSz, aSrc, aDest ); + aPos -= pRef->getFrameArea().Pos(); + aPos -= pRef->getFramePrintArea().Pos(); + aPos = OutputDevice::LogicToLogic( aPos, aSrc, aDest ); + sal_uInt32 nFlags = 0; + if ( pFly != pRef && pNd->IsGrfNode() ) + { + const MirrorGraph nMirror = pNd->GetSwAttrSet(). + GetMirrorGrf().GetValue(); + if ( MirrorGraph::Both == nMirror ) + nFlags = IMAP_MIRROR_HORZ | IMAP_MIRROR_VERT; + else if ( MirrorGraph::Vertical == nMirror ) + nFlags = IMAP_MIRROR_VERT; + else if ( MirrorGraph::Horizontal == nMirror ) + nFlags = IMAP_MIRROR_HORZ; + + } + return const_cast(rURL.GetMap())->GetHitIMapObject( aOrigSz, + aActSz, aPos, nFlags ); + } + + return nullptr; +} + +drawinglayer::attribute::SdrAllFillAttributesHelperPtr SwFrameFormat::getSdrAllFillAttributesHelper() const +{ + if (supportsFullDrawingLayerFillAttributeSet()) + { + // create FillAttributes on demand + if(!maFillAttributes) + { + const_cast< SwFrameFormat* >(this)->maFillAttributes = std::make_shared(GetAttrSet()); + } + } + else + { + // FALLBACKBREAKHERE assert wrong usage + OSL_ENSURE(false, "getSdrAllFillAttributesHelper() call only valid for RES_FLYFRMFMT and RES_FRMFMT (!)"); + } + + return maFillAttributes; +} + +namespace sw { + +bool IsFlyFrameFormatInHeader(const SwFrameFormat& rFormat) +{ + const SwFlyFrameFormat* pFlyFrameFormat = dynamic_cast(&rFormat); + if (!pFlyFrameFormat) + return false; + SwFlyFrame* pFlyFrame = pFlyFrameFormat->GetFrame(); + if (!pFlyFrame) // fdo#54648: "hidden" drawing object has no layout frame + { + return false; + } + SwPageFrame* pPageFrame = pFlyFrame->FindPageFrameOfAnchor(); + SwFrame* pHeader = pPageFrame->Lower(); + if (pHeader->GetType() == SwFrameType::Header) + { + const SwFrame* pFrame = pFlyFrame->GetAnchorFrame(); + while (pFrame) + { + if (pFrame == pHeader) + return true; + pFrame = pFrame->GetUpper(); + } + } + return false; +} + +void CheckAnchoredFlyConsistency(SwDoc const& rDoc) +{ +#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG + SwNodes const& rNodes(rDoc.GetNodes()); + sal_uLong const count(rNodes.Count()); + for (sal_uLong i = 0; i != count; ++i) + { + SwNode const*const pNode(rNodes[i]); + std::vector const*const pFlys(pNode->GetAnchoredFlys()); + if (pFlys) + { + for (const auto& rpFly : *pFlys) + { + SwFormatAnchor const& rAnchor((*rpFly).GetAnchor(false)); + assert(&rAnchor.GetContentAnchor()->nNode.GetNode() == pNode); + } + } + } + SwFrameFormats const*const pSpzFrameFormats(rDoc.GetSpzFrameFormats()); + if (pSpzFrameFormats) + { + for (auto it = pSpzFrameFormats->begin(); it != pSpzFrameFormats->end(); ++it) + { + SwFormatAnchor const& rAnchor((**it).GetAnchor(false)); + if (RndStdIds::FLY_AT_PAGE == rAnchor.GetAnchorId()) + { + assert(!rAnchor.GetContentAnchor() + // for invalid documents that lack text:anchor-page-number + // it may have an anchor before MakeFrames() is called + || (!SwIterator(**it).First())); + } + else + { + SwNode & rNode(rAnchor.GetContentAnchor()->nNode.GetNode()); + std::vector const*const pFlys(rNode.GetAnchoredFlys()); + assert(std::find(pFlys->begin(), pFlys->end(), *it) != pFlys->end()); + switch (rAnchor.GetAnchorId()) + { + case RndStdIds::FLY_AT_FLY: + assert(rNode.IsStartNode()); + break; + case RndStdIds::FLY_AT_PARA: + assert(rNode.IsTextNode() || rNode.IsTableNode()); + break; + case RndStdIds::FLY_AS_CHAR: + case RndStdIds::FLY_AT_CHAR: + assert(rNode.IsTextNode()); + break; + default: + assert(false); + break; + } + } + } + } +#else + (void) rDoc; +#endif +} + +} // namespace sw + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3