summaryrefslogtreecommitdiffstats
path: root/sw/source/core/layout/atrfrm.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/layout/atrfrm.cxx')
-rw-r--r--sw/source/core/layout/atrfrm.cxx3711
1 files changed, 3711 insertions, 0 deletions
diff --git a/sw/source/core/layout/atrfrm.cxx b/sw/source/core/layout/atrfrm.cxx
new file mode 100644
index 000000000..df2d8e974
--- /dev/null
+++ b/sw/source/core/layout/atrfrm.cxx
@@ -0,0 +1,3711 @@
+/* -*- 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 <sal/config.h>
+
+#include <com/sun/star/style/VerticalAlignment.hpp>
+#include <com/sun/star/text/ColumnSeparatorStyle.hpp>
+#include <com/sun/star/text/WrapTextMode.hpp>
+#include <com/sun/star/text/TextContentAnchorType.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/text/TextGridMode.hpp>
+#include <com/sun/star/text/XTextColumns.hpp>
+#include <sal/log.hxx>
+#include <o3tl/any.hxx>
+#include <o3tl/safeint.hxx>
+#include <osl/diagnose.h>
+#include <svtools/unoimap.hxx>
+#include <tools/UnitConversion.hxx>
+#include <vcl/imap.hxx>
+#include <vcl/imapobj.hxx>
+#include <unotools/intlwrapper.hxx>
+#include <unotools/syslocale.hxx>
+#include <frmfmt.hxx>
+#include <unocoll.hxx>
+#include <fmtclds.hxx>
+#include <fmtornt.hxx>
+#include <fmthdft.hxx>
+#include <fmtpdsc.hxx>
+#include <fmtcntnt.hxx>
+#include <fmtfsize.hxx>
+#include <fmtfordr.hxx>
+#include <fmtsrnd.hxx>
+#include <fmtlsplt.hxx>
+#include <fmtrowsplt.hxx>
+#include <fmtftntx.hxx>
+#include <fmteiro.hxx>
+#include <fmturl.hxx>
+#include <fmtcnct.hxx>
+#include <section.hxx>
+#include <fmtline.hxx>
+#include <tgrditem.hxx>
+#include <hfspacingitem.hxx>
+#include <IDocumentDrawModelAccess.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <IDocumentContentOperations.hxx>
+#include <IDocumentLayoutAccess.hxx>
+#include <pagefrm.hxx>
+#include <rootfrm.hxx>
+#include <cntfrm.hxx>
+#include <notxtfrm.hxx>
+#include <txtfrm.hxx>
+#include <crsrsh.hxx>
+#include <dflyobj.hxx>
+#include <dcontact.hxx>
+#include <frmtool.hxx>
+#include <flyfrms.hxx>
+#include <pagedesc.hxx>
+#include <grfatr.hxx>
+#include <ndnotxt.hxx>
+#include <node2lay.hxx>
+#include <fmtclbl.hxx>
+#include <swunohelper.hxx>
+#include <unoframe.hxx>
+#include <SwStyleNameMapper.hxx>
+#include <editeng/brushitem.hxx>
+#include <vcl/GraphicObject.hxx>
+#include <unomid.h>
+#include <strings.hrc>
+#include <svx/svdundo.hxx>
+#include <svx/SvxXTextColumns.hxx>
+#include <sortedobjs.hxx>
+#include <HandleAnchorNodeChg.hxx>
+#include <calbck.hxx>
+#include <pagedeschint.hxx>
+#include <drawdoc.hxx>
+#include <hints.hxx>
+#include <frameformats.hxx>
+#include <unoprnms.hxx>
+
+#include <ndtxt.hxx>
+
+#include <svx/sdr/attribute/sdrallfillattributeshelper.hxx>
+#include <svl/itemiter.hxx>
+#include <wrtsh.hxx>
+#include <txtfld.hxx>
+#include <cellatr.hxx>
+
+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<SwClient,SwFrameFormat> aIter(*pFormat);
+ for(SwClient* pLast = aIter.First(); bDel && pLast; pLast = aIter.Next())
+ if (dynamic_cast<const SwFrame*>(pLast) == nullptr)
+ bDel = false;
+ }
+
+ if ( !bDel )
+ return;
+
+ // 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<SwFormatContent&>(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 <pDoc->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();
+ SwNodeOffset nEnd = pNode->EndOfSectionIndex();
+ while ( aIdx < nEnd )
+ {
+ if ( pNode->IsContentNode() &&
+ static_cast<SwContentNode*>(pNode)->HasWriterListeners() )
+ {
+ SwCursorShell *pShell = SwIterator<SwCursorShell,SwContentNode>( *static_cast<SwContentNode*>(pNode) ).First();
+ if( pShell )
+ {
+ pShell->ParkCursor( aIdx );
+ 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(tools::Long lMult, tools::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<const SwFormatFrameSize&>(rAttr).m_eFrameHeightType &&
+ m_eFrameWidthType == static_cast<const SwFormatFrameSize&>(rAttr).m_eFrameWidthType &&
+ SvxSizeItem::operator==(rAttr)&&
+ m_nWidthPercent == static_cast<const SwFormatFrameSize&>(rAttr).GetWidthPercent() &&
+ m_eWidthPercentRelation == static_cast<const SwFormatFrameSize&>(rAttr).GetWidthPercentRelation() &&
+ m_nHeightPercent == static_cast<const SwFormatFrameSize&>(rAttr).GetHeightPercent() &&
+ m_eHeightPercentRelation == static_cast<const SwFormatFrameSize&>(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<sal_Int16>(GetHeightPercent() != SwFormatFrameSize::SYNCED ? GetHeightPercent() : 0);
+ break;
+ case MID_FRMSIZE_REL_HEIGHT_RELATION:
+ rVal <<= GetHeightPercentRelation();
+ break;
+ case MID_FRMSIZE_REL_WIDTH:
+ rVal <<= static_cast<sal_Int16>(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<sal_Int32>(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<sal_Int32>(convertTwipToMm100(GetHeight() < MINLAY ? MINLAY : GetHeight() ));
+ break;
+ case MID_FRMSIZE_SIZE_TYPE:
+ rVal <<= static_cast<sal_Int16>(GetHeightSizeType());
+ break;
+ case MID_FRMSIZE_IS_AUTO_HEIGHT:
+ rVal <<= SwFrameSize::Fixed != GetHeightSizeType();
+ break;
+ case MID_FRMSIZE_WIDTH_TYPE:
+ rVal <<= static_cast<sal_Int16>(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(o3tl::toTwips(aTmp.Height(), o3tl::Length::mm100));
+ aTmp.setWidth(o3tl::toTwips(aTmp.Width(), o3tl::Length::mm100));
+ }
+ SetSize(aTmp);
+ }
+ }
+ break;
+ case MID_FRMSIZE_REL_HEIGHT:
+ {
+ sal_Int16 nSet = 0;
+ rVal >>= nSet;
+ if(nSet >= 0 && nSet < SwFormatFrameSize::SYNCED)
+ SetHeightPercent(static_cast<sal_uInt8>(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<sal_uInt8>(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<bool>(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<bool>(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 = o3tl::toTwips(nWd, o3tl::Length::mm100);
+ 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 = o3tl::toTwips(nHg, o3tl::Length::mm100);
+ 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<int>(SwFrameSize::Minimum) )
+ {
+ SetHeightSizeType(static_cast<SwFrameSize>(nType));
+ }
+ else
+ bRet = false;
+ }
+ break;
+ case MID_FRMSIZE_IS_AUTO_HEIGHT:
+ {
+ bool bSet = *o3tl::doAccess<bool>(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<int>(SwFrameSize::Minimum) )
+ {
+ SetWidthSizeType(static_cast<SwFrameSize>(nType));
+ }
+ else
+ bRet = false;
+ }
+ break;
+ default:
+ bRet = false;
+ }
+ return bRet;
+}
+
+void SwFormatFrameSize::dumpAsXml(xmlTextWriterPtr pWriter) const
+{
+ (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatFrameSize"));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
+
+ std::stringstream aSize;
+ aSize << GetSize();
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("size"), BAD_CAST(aSize.str().c_str()));
+
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eFrameHeightType"), BAD_CAST(OString::number(static_cast<int>(m_eFrameHeightType)).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eFrameWidthType"), BAD_CAST(OString::number(static_cast<int>(m_eFrameWidthType)).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nWidthPercent"), BAD_CAST(OString::number(m_nWidthPercent).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eWidthPercentRelation"), BAD_CAST(OString::number(m_eWidthPercentRelation).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nHeightPercent"), BAD_CAST(OString::number(m_nHeightPercent).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eHeightPercentRelation"), BAD_CAST(OString::number(m_eHeightPercentRelation).getStr()));
+
+ (void)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<sw::BroadcastingModify*>(static_cast<const sw::BroadcastingModify*>(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<const SwFormatHeader&>(rAttr).GetRegisteredIn() &&
+ m_bActive == static_cast<const SwFormatHeader&>(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<sw::BroadcastingModify*>(static_cast<const sw::BroadcastingModify*>(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<const SwFormatFooter&>(rAttr).GetRegisteredIn() &&
+ m_bActive == static_cast<const SwFormatFooter&>(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<bool>(m_pStartNode) != static_cast<bool>(static_cast<const SwFormatContent&>(rAttr).m_pStartNode) )
+ return false;
+ if( m_pStartNode )
+ return ( *m_pStartNode == *static_cast<const SwFormatContent&>(rAttr).GetContentIdx() );
+ return true;
+}
+
+SwFormatContent* SwFormatContent::Clone( SfxItemPool* ) const
+{
+ return new SwFormatContent( *this );
+}
+
+void SwFormatContent::dumpAsXml(xmlTextWriterPtr pWriter) const
+{
+ (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatContent"));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
+ if (m_pStartNode)
+ {
+ (void)xmlTextWriterWriteAttribute(
+ pWriter, BAD_CAST("startNode"),
+ BAD_CAST(OString::number(sal_Int32(m_pStartNode->GetNode().GetIndex())).getStr()));
+ (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("startNodePtr"), "%p",
+ &m_pStartNode->GetNode());
+ }
+ (void)xmlTextWriterEndElement(pWriter);
+}
+
+// Partially implemented inline in hxx
+SwFormatPageDesc::SwFormatPageDesc( const SwFormatPageDesc &rCpy )
+ : SfxPoolItem( RES_PAGEDESC ),
+ SwClient( const_cast<SwPageDesc*>(rCpy.GetPageDesc()) ),
+ m_oNumOffset( rCpy.m_oNumOffset ),
+ m_pDefinedIn( nullptr )
+{
+}
+
+SwFormatPageDesc::SwFormatPageDesc( const SwPageDesc *pDesc )
+ : SfxPoolItem( RES_PAGEDESC ),
+ SwClient( const_cast<SwPageDesc*>(pDesc) ),
+ m_pDefinedIn( nullptr )
+{
+}
+
+SwFormatPageDesc &SwFormatPageDesc::operator=(const SwFormatPageDesc &rCpy)
+{
+ if(this == &rCpy)
+ return *this;
+
+ if (rCpy.GetPageDesc())
+ RegisterToPageDesc(*const_cast<SwPageDesc*>(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<const SwFormatPageDesc&>(rAttr).m_pDefinedIn ) &&
+ ( m_oNumOffset == static_cast<const SwFormatPageDesc&>(rAttr).m_oNumOffset ) &&
+ ( GetPageDesc() == static_cast<const SwFormatPageDesc&>(rAttr).GetPageDesc() );
+}
+
+SwFormatPageDesc* SwFormatPageDesc::Clone( SfxItemPool* ) const
+{
+ return new SwFormatPageDesc( *this );
+}
+
+void SwFormatPageDesc::SwClientNotify(const SwModify&, const SfxHint& rHint)
+{
+ if (const SwPageDescHint* pHint = dynamic_cast<const SwPageDescHint*>(&rHint))
+ {
+ // mba: shouldn't that be broadcasted also?
+ SwFormatPageDesc aDfltDesc(pHint->GetPageDesc());
+ SwPageDesc* pDesc = pHint->GetPageDesc();
+ const sw::BroadcastingModify* pMod = GetDefinedIn();
+ if(pMod)
+ {
+ if(auto pContentNode = dynamic_cast<const SwContentNode*>(pMod))
+ const_cast<SwContentNode*>(pContentNode)->SetAttr(aDfltDesc);
+ else if(auto pFormat = dynamic_cast<const SwFormat*>(pMod))
+ const_cast<SwFormat*>(pFormat)->SetFormatAttr( aDfltDesc );
+ else
+ {
+ SAL_WARN("sw.core", "SwFormatPageDesc registered at " << typeid(pMod).name() << ".");
+ RegisterToPageDesc(*pDesc);
+ }
+ }
+ else
+ // there could be an Undo-copy
+ RegisterToPageDesc(*pDesc);
+ }
+ else if (rHint.GetId() == SfxHintId::SwLegacyModify)
+ {
+ auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
+ if(RES_OBJECTDYING == pLegacy->GetWhich())
+ {
+ m_pDefinedIn = nullptr;
+ EndListeningAll();
+ }
+ }
+}
+
+void SwFormatPageDesc::RegisterToPageDesc( SwPageDesc& rDesc )
+{
+ rDesc.Add( this );
+}
+
+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<sal_uInt16> oOffset = GetNumOffset();
+ if (oOffset)
+ {
+ rVal <<= static_cast<sal_Int16>(*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
+{
+ (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatPageDesc"));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
+ if (m_oNumOffset)
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("oNumOffset"), BAD_CAST(OString::number(*m_oNumOffset).getStr()));
+ else
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("oNumOffset"), BAD_CAST("none"));
+ (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("pPageDesc"), "%p", GetPageDesc());
+ if (const SwPageDesc* pPageDesc = GetPageDesc())
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("presentation"), BAD_CAST(pPageDesc->GetName().toUtf8().getStr()));
+ (void)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
+{
+ (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwColumn"));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nWish"), BAD_CAST(OString::number(m_nWish).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nUpper"), BAD_CAST(OString::number(0).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nLower"), BAD_CAST(OString::number(0).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nLeft"), BAD_CAST(OString::number(m_nLeft).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nRight"), BAD_CAST(OString::number(m_nRight).getStr()));
+ (void)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<const SwFormatCol&>(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 )
+ {
+ tools::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<sal_uInt16>(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);
+
+ assert(nAct != 0);
+ //Convert the current width to the requested width.
+ for (SwColumn &rCol: m_aColumns)
+ {
+ tools::Long nTmp = rCol.GetWishWidth();
+ nTmp *= GetWishWidth();
+ nTmp = nAct == 0 ? nTmp : 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(SvxXTextColumns_createInstance(),
+ css::uno::UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertySet> xProps(xCols, css::uno::UNO_QUERY_THROW);
+
+ if (GetNumCols() > 0)
+ {
+ xCols->setColumnCount(GetNumCols());
+ const sal_uInt16 nItemGutterWidth = GetGutterWidth();
+ sal_Int32 nAutoDistance = IsOrtho() ? USHRT_MAX == nItemGutterWidth
+ ? DEF_GUTTER_WIDTH
+ : static_cast<sal_Int32>(nItemGutterWidth)
+ : 0;
+ nAutoDistance = convertTwipToMm100(nAutoDistance);
+ xProps->setPropertyValue(UNO_NAME_AUTOMATIC_DISTANCE, uno::Any(nAutoDistance));
+
+ if (!IsOrtho())
+ {
+ auto aTextColumns = xCols->getColumns();
+ text::TextColumn* pColumns = aTextColumns.getArray();
+ const SwColumns& rCols = GetColumns();
+ for (sal_Int32 i = 0; i < aTextColumns.getLength(); ++i)
+ {
+ const SwColumn* pCol = &rCols[i];
+
+ pColumns[i].Width = pCol->GetWishWidth();
+ pColumns[i].LeftMargin = convertTwipToMm100(pCol->GetLeft());
+ pColumns[i].RightMargin = convertTwipToMm100(pCol->GetRight());
+ }
+ xCols->setColumns(aTextColumns); // sets "IsAutomatic" property to false
+ }
+ }
+ uno::Any aVal;
+ aVal <<= o3tl::narrowing<sal_Int32>(
+ o3tl::convert(GetLineWidth(), o3tl::Length::twip, o3tl::Length::mm100));
+ xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_WIDTH, aVal);
+ aVal <<= GetLineColor();
+ xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_COLOR, aVal);
+ aVal <<= static_cast<sal_Int32>(GetLineHeight());
+ xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_RELATIVE_HEIGHT, aVal);
+ aVal <<= GetLineAdj() != COLADJ_NONE;
+ xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_IS_ON, aVal);
+ sal_Int16 nStyle;
+ switch (GetLineStyle())
+ {
+ case SvxBorderLineStyle::SOLID:
+ nStyle = css::text::ColumnSeparatorStyle::SOLID;
+ break;
+ case SvxBorderLineStyle::DOTTED:
+ nStyle = css::text::ColumnSeparatorStyle::DOTTED;
+ break;
+ case SvxBorderLineStyle::DASHED:
+ nStyle = css::text::ColumnSeparatorStyle::DASHED;
+ break;
+ case SvxBorderLineStyle::NONE:
+ default:
+ nStyle = css::text::ColumnSeparatorStyle::NONE;
+ break;
+ }
+ aVal <<= nStyle;
+ xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_STYLE, aVal);
+ style::VerticalAlignment eAlignment;
+ switch (GetLineAdj())
+ {
+ case COLADJ_TOP:
+ eAlignment = style::VerticalAlignment_TOP;
+ break;
+ case COLADJ_BOTTOM:
+ eAlignment = style::VerticalAlignment_BOTTOM;
+ break;
+ case COLADJ_CENTER:
+ case COLADJ_NONE:
+ default:
+ eAlignment = style::VerticalAlignment_MIDDLE;
+ }
+ aVal <<= eAlignment;
+ xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_VERTIVAL_ALIGNMENT, aVal);
+ 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<text::TextColumn> 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( o3tl::narrowing<sal_uInt16>(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 (o3tl::toTwips(pArray[i].LeftMargin, o3tl::Length::mm100));
+ aCol.SetRight(o3tl::toTwips(pArray[i].RightMargin, o3tl::Length::mm100));
+ m_aColumns.insert(m_aColumns.begin() + i, aCol);
+ }
+ bRet = true;
+ m_nWidth = nWidthSum;
+ m_bOrtho = false;
+
+ if (uno::Reference<beans::XPropertySet> xProps{ xCols, css::uno::UNO_QUERY })
+ {
+ xProps->getPropertyValue(UNO_NAME_IS_AUTOMATIC) >>= m_bOrtho;
+ xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_WIDTH) >>= m_nLineWidth;
+ m_nLineWidth = o3tl::toTwips(m_nLineWidth, o3tl::Length::mm100);
+ xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_COLOR) >>= m_aLineColor;
+ if (sal_Int32 nHeight;
+ xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_RELATIVE_HEIGHT) >>= nHeight)
+ m_nLineHeight = nHeight;
+ switch (xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_STYLE).get<sal_Int16>())
+ {
+ default:
+ case css::text::ColumnSeparatorStyle::NONE:
+ m_eLineStyle = SvxBorderLineStyle::NONE;
+ break;
+ case css::text::ColumnSeparatorStyle::SOLID:
+ m_eLineStyle = SvxBorderLineStyle::SOLID;
+ break;
+ case css::text::ColumnSeparatorStyle::DOTTED:
+ m_eLineStyle = SvxBorderLineStyle::DOTTED;
+ break;
+ case css::text::ColumnSeparatorStyle::DASHED:
+ m_eLineStyle = SvxBorderLineStyle::DASHED;
+ break;
+ }
+ if (!xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_IS_ON).get<bool>())
+ m_eAdj = COLADJ_NONE;
+ else switch (xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_VERTIVAL_ALIGNMENT).get<style::VerticalAlignment>())
+ {
+ 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
+{
+ (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatCol"));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eLineStyle"), BAD_CAST(OString::number(static_cast<sal_Int16>(m_eLineStyle)).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nLineWidth"), BAD_CAST(OString::number(m_nLineWidth).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("aLineColor"), BAD_CAST(m_aLineColor.AsRGBHexString().toUtf8().getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nLineHeight"), BAD_CAST(OString::number(m_nLineHeight).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eAdj"), BAD_CAST(OString::number(m_eAdj).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nWidth"), BAD_CAST(OString::number(m_nWidth).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nWidthAdjustValue"), BAD_CAST(OString::number(m_aWidthAdjustValue).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bOrtho"), BAD_CAST(OString::boolean(m_bOrtho).getStr()));
+
+ (void)xmlTextWriterStartElement(pWriter, BAD_CAST("aColumns"));
+ for (const SwColumn& rColumn : m_aColumns)
+ rColumn.dumpAsXml(pWriter);
+ (void)xmlTextWriterEndElement(pWriter);
+
+ (void)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<const SwFormatSurround&>(rAttr).GetValue() &&
+ m_bAnchorOnly== static_cast<const SwFormatSurround&>(rAttr).m_bAnchorOnly &&
+ m_bContour== static_cast<const SwFormatSurround&>(rAttr).m_bContour &&
+ m_bOutside== static_cast<const SwFormatSurround&>(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<css::text::WrapTextMode>(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<bool>(rVal) );
+ break;
+ case MID_SURROUND_CONTOUR:
+ SetContour( *o3tl::doAccess<bool>(rVal) );
+ break;
+ case MID_SURROUND_CONTOUROUTSIDE:
+ SetOutside( *o3tl::doAccess<bool>(rVal) );
+ break;
+ default:
+ OSL_ENSURE( false, "unknown MemberId" );
+ bRet = false;
+ }
+ return bRet;
+}
+
+void SwFormatSurround::dumpAsXml(xmlTextWriterPtr pWriter) const
+{
+ (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatSurround"));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(OString::number(static_cast<sal_Int32>(GetValue())).getStr()));
+
+ OUString aPresentation;
+ IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag());
+ GetPresentation(SfxItemPresentation::Nameless, MapUnit::Map100thMM, MapUnit::Map100thMM, aPresentation, aIntlWrapper);
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("presentation"), BAD_CAST(aPresentation.toUtf8().getStr()));
+
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bAnchorOnly"), BAD_CAST(OString::boolean(m_bAnchorOnly).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bContour"), BAD_CAST(OString::boolean(m_bContour).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bOutside"), BAD_CAST(OString::boolean(m_bOutside).getStr()));
+
+ (void)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<const SwFormatVertOrient&>(rAttr).m_nYPos &&
+ m_eOrient == static_cast<const SwFormatVertOrient&>(rAttr).m_eOrient &&
+ m_eRelation == static_cast<const SwFormatVertOrient&>(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<sal_Int32>(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 = o3tl::toTwips(nVal, o3tl::Length::mm100);
+ SetPos( nVal );
+ }
+ break;
+ default:
+ OSL_ENSURE( false, "unknown MemberId" );
+ bRet = false;
+ }
+ return bRet;
+}
+
+void SwFormatVertOrient::dumpAsXml(xmlTextWriterPtr pWriter) const
+{
+ (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatVertOrient"));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nYPos"), BAD_CAST(OString::number(m_nYPos).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eOrient"), BAD_CAST(OString::number(m_eOrient).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eRelation"), BAD_CAST(OString::number(m_eRelation).getStr()));
+ (void)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<const SwFormatHoriOrient&>(rAttr).m_nXPos &&
+ m_eOrient == static_cast<const SwFormatHoriOrient&>(rAttr).m_eOrient &&
+ m_eRelation == static_cast<const SwFormatHoriOrient&>(rAttr).m_eRelation &&
+ m_bPosToggle == static_cast<const SwFormatHoriOrient&>(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<sal_Int32>(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 = o3tl::toTwips(nVal, o3tl::Length::mm100);
+ SetPos( nVal );
+ }
+ break;
+ case MID_HORIORIENT_PAGETOGGLE:
+ SetPosToggle( *o3tl::doAccess<bool>(rVal));
+ break;
+ default:
+ OSL_ENSURE( false, "unknown MemberId" );
+ bRet = false;
+ }
+ return bRet;
+}
+
+void SwFormatHoriOrient::dumpAsXml(xmlTextWriterPtr pWriter) const
+{
+ (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatHoriOrient"));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nXPos"), BAD_CAST(OString::number(m_nXPos).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eOrient"), BAD_CAST(OString::number(m_eOrient).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eRelation"), BAD_CAST(OString::number(m_eRelation).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bPosToggle"), BAD_CAST(OString::boolean(m_bPosToggle).getStr()));
+ (void)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( ++s_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( ++s_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<SwStartNode*>(&pPos->nNode.GetNode()))
+ || (RndStdIds::FLY_AT_PARA == m_eAnchorId && dynamic_cast<SwTableNode*>(&pPos->nNode.GetNode()))
+ || dynamic_cast<SwTextNode*>(&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 = ++s_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<SwFormatAnchor const&>(rAttr));
+ // OD 2004-05-05 #i28701# - Note: <mnOrder> 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::s_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<sal_Int16>(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<text::XTextFrame> 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<text::TextContentAnchorType>(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
+{
+ (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatAnchor"));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
+
+ if (m_pContentAnchor)
+ {
+ std::stringstream aContentAnchor;
+ aContentAnchor << *m_pContentAnchor;
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_pContentAnchor"), BAD_CAST(aContentAnchor.str().c_str()));
+ }
+ else
+ (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("m_pContentAnchor"), "%p", m_pContentAnchor.get());
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_eAnchorType"), BAD_CAST(OString::number(static_cast<int>(m_eAnchorId)).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nPageNumber"), BAD_CAST(OString::number(m_nPageNumber).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nOrder"), BAD_CAST(OString::number(m_nOrder).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("s_nOrderCounter"), BAD_CAST(OString::number(s_nOrderCounter).getStr()));
+ OUString aPresentation;
+ IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag());
+ GetPresentation(SfxItemPresentation::Nameless, MapUnit::Map100thMM, MapUnit::Map100thMM, aPresentation, aIntlWrapper);
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("presentation"), BAD_CAST(aPresentation.toUtf8().getStr()));
+
+ (void)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<const SwFormatURL&>(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<container::XIndexContainer> 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<bool>(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
+{
+ (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatNoBalancedColumns"));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(OString::boolean(GetValue()).getStr()));
+ (void)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<const SwFormatFootnoteEndAtTextEnd&>(rItem);
+ return SfxEnumItem::operator==( rItem ) &&
+ 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<sal_Int16>(m_nOffset); break;
+ case MID_OWN_NUM :
+ rVal <<= GetValue() >= FTNEND_ATTXTEND_OWNNUMANDFMT;
+ break;
+ case MID_NUM_TYPE : rVal <<= static_cast<sal_Int16>(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<bool>(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<bool>(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<bool>(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<SvxNumType>(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<const SwFormatChain&>(rAttr).GetPrev() &&
+ GetNext() == static_cast<const SwFormatChain&>(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<const SwFormatLineNumber&>(rAttr).GetStartValue() &&
+ m_bCountLines == static_cast<const SwFormatLineNumber&>(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<sal_Int32>(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<bool>(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<SwTextGridItem const&>(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<sal_Int32>(convertTwipToMm100(m_nBaseHeight));
+ break;
+ case MID_GRID_BASEWIDTH:
+ OSL_ENSURE( (nMemberId & CONVERT_TWIPS) != 0,
+ "This value needs TWIPS-MM100 conversion" );
+ rVal <<= static_cast<sal_Int32>(convertTwipToMm100(m_nBaseWidth));
+ break;
+ case MID_GRID_RUBYHEIGHT:
+ OSL_ENSURE( (nMemberId & CONVERT_TWIPS) != 0,
+ "This value needs TWIPS-MM100 conversion" );
+ rVal <<= static_cast<sal_Int32>(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:
+ {
+ Color nTmp;
+ bRet = (rVal >>= nTmp);
+ if( bRet )
+ SetColor( nTmp );
+ }
+ break;
+ case MID_GRID_LINES:
+ {
+ sal_Int16 nTmp = 0;
+ bRet = (rVal >>= nTmp);
+ if( bRet && (nTmp >= 0) )
+ SetLines( o3tl::narrowing<sal_uInt16>(nTmp) );
+ else
+ bRet = false;
+ }
+ break;
+ case MID_GRID_RUBY_BELOW:
+ SetRubyTextBelow( *o3tl::doAccess<bool>(rVal) );
+ break;
+ case MID_GRID_PRINT:
+ SetPrintGrid( *o3tl::doAccess<bool>(rVal) );
+ break;
+ case MID_GRID_DISPLAY:
+ SetDisplayGrid( *o3tl::doAccess<bool>(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 = o3tl::toTwips(nTmp, o3tl::Length::mm100);
+ 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<sal_Int32>(nTmp, MIN_TEXTGRID_SIZE);
+ SetBaseHeight( o3tl::narrowing<sal_uInt16>(nTmp) );
+ }
+ else if( (nMemberId & ~CONVERT_TWIPS) == MID_GRID_BASEWIDTH )
+ {
+ nTmp = std::max<sal_Int32>(nTmp, MIN_TEXTGRID_SIZE);
+ SetBaseWidth( o3tl::narrowing<sal_uInt16>(nTmp) );
+ }
+ else
+ SetRubyHeight( o3tl::narrowing<sal_uInt16>(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<bool>(rVal) );
+ break;
+ case MID_GRID_STANDARD_MODE:
+ {
+ bool bStandard = *o3tl::doAccess<bool>(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 WhichRangesContainer& pWhichRange)
+: SwFormat(rPool, pFormatNm, pWhichRange, pDrvdFrame, nFormatWhich),
+ m_ffList(nullptr)
+{
+}
+
+SwFrameFormat::SwFrameFormat(
+ SwAttrPool& rPool,
+ const OUString &rFormatNm,
+ SwFrameFormat *pDrvdFrame,
+ sal_uInt16 nFormatWhich,
+ const WhichRangesContainer& pWhichRange)
+: SwFormat(rPool, rFormatNm, pWhichRange, pDrvdFrame, nFormatWhich),
+ m_ffList(nullptr)
+{
+}
+
+SwFrameFormat::~SwFrameFormat()
+{
+ if( !GetDoc()->IsInDtor())
+ {
+ const SwFormatAnchor& rAnchor = GetAnchor();
+ if (rAnchor.GetContentAnchor() != nullptr)
+ {
+ rAnchor.GetContentAnchor()->nNode.GetNode().RemoveAnchoredFly(this);
+ }
+ }
+
+ // Check if there any textboxes attached to this format.
+ if( nullptr == m_pOtherTextBoxFormats )
+ return;
+
+ // This is a fly-frame-format just delete this
+ // textbox entry from the textbox collection.
+ // Note: Do not delete it from the doc, as that
+ // is already in progress.
+ if (Which() == RES_FLYFRMFMT)
+ m_pOtherTextBoxFormats->DelTextBox(this);
+
+ // This is a draw-frame-format what belongs to
+ // a shape with textbox(es). Delete all of them.
+ if (Which() == RES_DRAWFRMFMT)
+ m_pOtherTextBoxFormats->ClearAll();
+
+ // Release the pointer.
+ m_pOtherTextBoxFormats.reset();
+}
+
+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");
+
+ const 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) {
+ const SwStringMsgPoolItem aNew( RES_NAME_CHANGED, rNewName );
+ GetNotifier().Broadcast(sw::LegacyModifyHint( &aOld, &aNew ));
+ }
+ }
+ else
+ SwFormat::SetName( rNewName, bBroadcast );
+}
+
+bool SwFrameFormat::supportsFullDrawingLayerFillAttributeSet() const
+{
+ return true;
+}
+
+void SwFrameFormat::SwClientNotify(const SwModify& rMod, const SfxHint& rHint)
+{
+ if (rHint.GetId() != SfxHintId::SwLegacyModify)
+ return;
+ auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
+ const sal_uInt16 nNewWhich = pLegacy->m_pNew ? pLegacy->m_pNew->Which() : 0;
+ const SwAttrSetChg* pNewAttrSetChg = nullptr;
+ const SwFormatHeader* pH = nullptr;
+ const SwFormatFooter* pF = nullptr;
+ const SwPosition* pNewAnchorPosition = nullptr;
+ switch(nNewWhich)
+ {
+ case RES_ATTRSET_CHG:
+ {
+ pNewAttrSetChg = static_cast<const SwAttrSetChg*>(pLegacy->m_pNew);
+ pH = pNewAttrSetChg->GetChgSet()->GetItem(RES_HEADER, false);
+ pF = pNewAttrSetChg->GetChgSet()->GetItem(RES_FOOTER, false);
+
+ // reset fill information
+ if(maFillAttributes && supportsFullDrawingLayerFillAttributeSet())
+ {
+ SfxItemIter aIter(*pNewAttrSetChg->GetChgSet());
+ for(const SfxPoolItem* pItem = aIter.GetCurItem(); pItem; pItem = aIter.NextItem())
+ {
+ if(!IsInvalidItem(pItem) && pItem->Which() >= XATTR_FILL_FIRST && pItem->Which() <= XATTR_FILL_LAST)
+ {
+ maFillAttributes.reset();
+ break;
+ }
+ }
+ }
+ const SwFormatAnchor* pAnchor = pNewAttrSetChg->GetChgSet()->GetItem(RES_ANCHOR, false);
+ if(pAnchor)
+ {
+ pNewAnchorPosition = pAnchor->GetContentAnchor();
+ assert(pNewAnchorPosition == nullptr || // style's set must not contain position!
+ pNewAttrSetChg->GetTheChgdSet() == &m_aSet);
+ }
+ break;
+ }
+ case RES_FMT_CHG:
+ {
+ // reset fill information on format change (e.g. style changed)
+ if(maFillAttributes && supportsFullDrawingLayerFillAttributeSet())
+ maFillAttributes.reset();
+ break;
+ }
+ case RES_HEADER:
+ pH = static_cast<const SwFormatHeader*>(pLegacy->m_pNew);
+ break;
+ case RES_FOOTER:
+ pF = static_cast<const SwFormatFooter*>(pLegacy->m_pNew);
+ break;
+ case RES_ANCHOR:
+ pNewAnchorPosition = static_cast<const SwFormatAnchor*>(pLegacy->m_pNew)->GetContentAnchor();
+ break;
+ }
+ const sal_uInt16 nOldWhich = pLegacy->m_pOld ? pLegacy->m_pOld->Which() : 0;
+ const SwPosition* pOldAnchorPosition = nullptr;
+ switch(nOldWhich)
+ {
+ case RES_ATTRSET_CHG:
+ {
+ const SwAttrSetChg* pOldAttrSetChg = nullptr;
+ pOldAttrSetChg = static_cast<const SwAttrSetChg*>(pLegacy->m_pOld);
+ const SwFormatAnchor* pAnchor = pOldAttrSetChg->GetChgSet()->GetItem(RES_ANCHOR, false);
+ if(pAnchor)
+ {
+ pOldAnchorPosition = pAnchor->GetContentAnchor();
+ assert(pOldAnchorPosition == nullptr || // style's set must not contain position!
+ pOldAttrSetChg->GetTheChgdSet() == &m_aSet);
+ }
+ break;
+ }
+ case RES_ANCHOR:
+ pOldAnchorPosition = static_cast<const SwFormatAnchor*>(pLegacy->m_pOld)->GetContentAnchor();
+ break;
+ case RES_REMOVE_UNO_OBJECT:
+ SetXObject(uno::Reference<uno::XInterface>(nullptr));
+ break;
+ }
+
+ assert(nOldWhich == nNewWhich || !nOldWhich || !nNewWhich);
+ 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<SwFormatHeader*>(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<SwFormatFooter*>(pF)->RegisterToFormat(*pFormat);
+ }
+ SwFormat::SwClientNotify(rMod, rHint);
+ if(pOldAnchorPosition != nullptr && (pNewAnchorPosition == nullptr || pOldAnchorPosition->nNode.GetIndex() != pNewAnchorPosition->nNode.GetIndex()))
+ pOldAnchorPosition->nNode.GetNode().RemoveAnchoredFly(this);
+ if(pNewAnchorPosition != nullptr && (pOldAnchorPosition == nullptr || pOldAnchorPosition->nNode.GetIndex() != pNewAnchorPosition->nNode.GetIndex()))
+ pNewAnchorPosition->nNode.GetNode().AddAnchoredFly(this);
+}
+
+void SwFrameFormat::RegisterToFormat( SwFormat& rFormat )
+{
+ rFormat.Add( this );
+}
+
+/// Delete all Frames that are registered in aDepend.
+void SwFrameFormat::DelFrames()
+{
+ SwIterator<SwFrame,SwFormat> 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( auto pSectionFormat = dynamic_cast<const SwSectionFormat*>( this ))
+ {
+ // get the Frame using Node2Layout
+ const SwSectionNode* pSectNd = pSectionFormat->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<Point, bool> 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<Point, bool> const tmp(aNullPt, false);
+ SwFlyFrame* pFly = static_cast<SwFlyFrame*>(::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<SwFlyFrame,SwFormat>(*this).First();
+ if( pSFly )
+ {
+ SwFlyFrame *pAskFly = SwIterator<SwFlyFrame,SwFormat>(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
+{
+ (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFrameFormat"));
+ (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("name"), BAD_CAST(GetName().toUtf8().getStr()));
+ (void)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)
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("which"), BAD_CAST(pWhich));
+
+ if (m_pOtherTextBoxFormats)
+ {
+ (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("OtherTextBoxFormat"), "%p", m_pOtherTextBoxFormats.get());
+ }
+
+ GetAttrSet().dumpAsXml(pWriter);
+
+ if (const SdrObject* pSdrObject = FindSdrObject())
+ pSdrObject->dumpAsXml(pWriter);
+
+ (void)xmlTextWriterEndElement(pWriter);
+}
+
+void SwFrameFormats::dumpAsXml(xmlTextWriterPtr pWriter, const char* pName) const
+{
+ (void)xmlTextWriterStartElement(pWriter, BAD_CAST(pName));
+ for (const SwFrameFormat *pFormat : m_PosIndex)
+ pFormat->dumpAsXml(pWriter);
+ (void)xmlTextWriterEndElement(pWriter);
+}
+
+
+SwFlyFrameFormat::SwFlyFrameFormat( SwAttrPool& rPool, const OUString &rFormatNm, SwFrameFormat *pDrvdFrame )
+ : SwFrameFormat( rPool, rFormatNm, pDrvdFrame, RES_FLYFRMFMT )
+{}
+
+SwFlyFrameFormat::~SwFlyFrameFormat()
+{
+ SwIterator<SwFlyFrame,SwFormat> 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;
+
+ sw::BroadcastingModify *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<SwFrame, SwContentNode, sw::IteratorMode::UnwrapMulti>(*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<SwPageFrame*>(GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout()->Lower());
+ if( nPgNum == 0 && aAnchorAttr.GetContentAnchor() )
+ {
+ SwContentNode *pCNd = aAnchorAttr.GetContentAnchor()->nNode.GetNode().GetContentNode();
+ SwIterator<SwFrame, SwContentNode, sw::IteratorMode::UnwrapMulti> 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 <PlaceFly(..)>
+ pPage->PlaceFly( nullptr, this );
+ break;
+ }
+ pPage = static_cast<SwPageFrame*>(pPage->GetNext());
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ if( !pModify )
+ return;
+
+ SwIterator<SwFrame, sw::BroadcastingModify, sw::IteratorMode::UnwrapMulti> aIter(*pModify);
+ for( SwFrame *pFrame = aIter.First(); pFrame; pFrame = aIter.Next() )
+ {
+ bool bAdd = !pFrame->IsContentFrame() ||
+ !static_cast<SwContentFrame*>(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<SwTextFrame*>(pFrame), aAnchorAttr);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (bAdd && pFrame->GetDrawObjs())
+ {
+ // #i28701# - new type <SwSortedObjs>
+ SwSortedObjs &rObjs = *pFrame->GetDrawObjs();
+ for(SwAnchoredObject* pObj : rObjs)
+ {
+ // #i28701# - consider changed type of
+ // <SwSortedObjs> entries.
+ if( pObj->DynCastFlyFrame() != 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<Point, bool> tmp;
+ if (pPoint)
+ {
+ tmp.first = *pPoint;
+ tmp.second = false;
+ }
+ return static_cast<SwFlyFrame*>(::GetFrameOfModify( nullptr, *this, SwFrameType::Fly,
+ nullptr, &tmp));
+}
+
+SwAnchoredObject* SwFlyFrameFormat::GetAnchoredObj() const
+{
+ SwFlyFrame* pFlyFrame( GetFrame() );
+ if ( pFlyFrame )
+ {
+ return pFlyFrame;
+ }
+ else
+ {
+ return nullptr;
+ }
+}
+
+bool SwFlyFrameFormat::GetInfo( SfxPoolItem& rInfo ) const
+{
+ bool bRet = true;
+ switch( rInfo.Which() )
+ {
+ case RES_CONTENT_VISIBLE:
+ {
+ static_cast<SwPtrMsgPoolItem&>(rInfo).pObject = SwIterator<SwFrame,SwFormat>( *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, "<SwFlyFrameFormat::SetObjTitle(..)> - missing <SdrObject> instance" );
+ msTitle = rTitle;
+ if ( !pMasterObject )
+ {
+ return;
+ }
+
+ const SwStringMsgPoolItem aOld(RES_TITLE_CHANGED, pMasterObject->GetTitle());
+ pMasterObject->SetTitle(rTitle);
+ if(bBroadcast)
+ {
+ const SwStringMsgPoolItem aNew(RES_TITLE_CHANGED, rTitle);
+ GetNotifier().Broadcast(sw::LegacyModifyHint(&aOld, &aNew));
+ }
+}
+
+OUString SwFlyFrameFormat::GetObjTitle() const
+{
+ const SdrObject* pMasterObject = FindSdrObject();
+ OSL_ENSURE( pMasterObject, "<SwFlyFrameFormat::GetObjTitle(..)> - missing <SdrObject> instance" );
+ if ( !pMasterObject )
+ {
+ return msTitle;
+ }
+ if (!pMasterObject->GetTitle().isEmpty())
+ return pMasterObject->GetTitle();
+ else
+ return msTitle;
+}
+
+void SwFlyFrameFormat::SetObjTooltip(const OUString& rTooltip)
+{
+ msTooltip = rTooltip;
+}
+
+const OUString & SwFlyFrameFormat::GetObjTooltip() const
+{
+ return msTooltip;
+}
+
+void SwFlyFrameFormat::SetObjDescription( const OUString& rDescription, bool bBroadcast )
+{
+ SdrObject* pMasterObject = FindSdrObject();
+ OSL_ENSURE( pMasterObject, "<SwFlyFrameFormat::SetDescription(..)> - missing <SdrObject> instance" );
+ msDesc = rDescription;
+ if ( !pMasterObject )
+ {
+ return;
+ }
+
+ const SwStringMsgPoolItem aOld( RES_DESCRIPTION_CHANGED, pMasterObject->GetDescription() );
+ pMasterObject->SetDescription( rDescription );
+ if(bBroadcast)
+ {
+ const SwStringMsgPoolItem aNew( RES_DESCRIPTION_CHANGED, rDescription );
+ GetNotifier().Broadcast(sw::LegacyModifyHint(&aOld, &aNew));
+ }
+}
+
+OUString SwFlyFrameFormat::GetObjDescription() const
+{
+ const SdrObject* pMasterObject = FindSdrObject();
+ OSL_ENSURE( pMasterObject, "<SwFlyFrameFormat::GetDescription(..)> - missing <SdrObject> 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<SvxBrushItem> aBackground(makeBackgroundBrushItem());
+ if ( aBackground->GetColor().IsTransparent() &&
+ aBackground->GetColor() != COL_TRANSPARENT
+ )
+ {
+ return true;
+ }
+ else
+ {
+ const GraphicObject *pTmpGrf = aBackground->GetGraphicObject();
+ if ( pTmpGrf &&
+ pTmpGrf->GetAttr().IsTransparent()
+ )
+ {
+ 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 <SwFrame::GetBackgroundBrush(..).
+
+ @return true, if background brush is "inherited" from parent/grandparent
+*/
+bool SwFlyFrameFormat::IsBackgroundBrushInherited() const
+{
+ if (supportsFullDrawingLayerFillAttributeSet() && getSdrAllFillAttributesHelper())
+ {
+ return !getSdrAllFillAttributesHelper()->isUsed();
+ }
+ else
+ {
+ std::unique_ptr<SvxBrushItem> aBackground(makeBackgroundBrushItem());
+ if ( (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<SwFrame, SwContentNode, sw::IteratorMode::UnwrapMulti> 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<SwFrame, SwContentNode, sw::IteratorMode::UnwrapMulti> 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<SwFrame,SwFormat> 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<SwWrtShell*>(pViewShell);
+ }
+}
+
+void SwHandleAnchorNodeChg::ImplDestroy()
+{
+ 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(false);
+
+ mpWrtShell->Pop(SwCursorShell::PopMode::DeleteCurrent);
+}
+
+SwHandleAnchorNodeChg::~SwHandleAnchorNodeChg()
+{
+ suppress_fun_call_w_exception(ImplDestroy());
+}
+
+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( "<SwDrawFrameFormat::SetPositionLayoutDir(..)> - 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<SwFlyFrame,SwFormat>( *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<const SwNoTextFrame*>(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 o3tl::Length aSrc ( o3tl::Length::twip );
+ const o3tl::Length aDest( o3tl::Length::mm100 );
+ aOrigSz = o3tl::convert( aOrigSz, aSrc, aDest );
+ aActSz = o3tl::convert( aActSz, aSrc, aDest );
+ aPos -= pRef->getFrameArea().Pos();
+ aPos -= pRef->getFramePrintArea().Pos();
+ aPos = o3tl::convert( 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<ImageMap*>(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<drawinglayer::attribute::SdrAllFillAttributesHelper>(GetAttrSet());
+ }
+ }
+ else
+ {
+ // FALLBACKBREAKHERE assert wrong usage
+ OSL_ENSURE(false, "getSdrAllFillAttributesHelper() call only valid for RES_FLYFRMFMT and RES_FRMFMT (!)");
+ }
+
+ return maFillAttributes;
+}
+
+void SwFrameFormat::MoveTableBox(SwTableBox& rTableBox, const SwFrameFormat* pOldFormat)
+{
+ Add(&rTableBox);
+ if(!pOldFormat)
+ return;
+ const auto& rOld = pOldFormat->GetFormatAttr(RES_BOXATR_FORMAT);
+ const auto& rNew = GetFormatAttr(RES_BOXATR_FORMAT);
+ if(rOld != rNew)
+ SwClientNotify(*this, sw::LegacyModifyHint(&rOld, &rNew));
+}
+
+
+namespace sw {
+
+bool IsFlyFrameFormatInHeader(const SwFrameFormat& rFormat)
+{
+ const SwFlyFrameFormat* pFlyFrameFormat = dynamic_cast<const SwFlyFrameFormat*>(&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());
+ SwNodeOffset const count(rNodes.Count());
+ for (SwNodeOffset i(0); i != count; ++i)
+ {
+ SwNode const*const pNode(rNodes[i]);
+ std::vector<SwFrameFormat*> const & rFlys(pNode->GetAnchoredFlys());
+ for (const auto& rpFly : rFlys)
+ {
+ SwFormatAnchor const& rAnchor((*rpFly).GetAnchor(false));
+ assert(&rAnchor.GetContentAnchor()->nNode.GetNode() == pNode);
+ }
+ }
+ SwFrameFormats const*const pSpzFrameFormats(rDoc.GetSpzFrameFormats());
+ if (!pSpzFrameFormats)
+ return;
+
+ 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<SwFrame, SwFrameFormat>(**it).First()));
+ }
+ else
+ {
+ SwNode & rNode(rAnchor.GetContentAnchor()->nNode.GetNode());
+ std::vector<SwFrameFormat*> const& rFlys(rNode.GetAnchoredFlys());
+ assert(std::find(rFlys.begin(), rFlys.end(), *it) != rFlys.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: */