/* -*- 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.GetNode() );
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;
}
ItemInstanceManager* SwFormatFrameSize::getItemInstanceManager() const
{
static HashedItemInstanceManager aInstanceManager(ItemType());
return &aInstanceManager;
}
size_t SwFormatFrameSize::hashCode() const
{
std::size_t seed(0);
o3tl::hash_combine(seed, Which());
o3tl::hash_combine(seed, GetHeightSizeType());
o3tl::hash_combine(seed, GetWidthSizeType());
o3tl::hash_combine(seed, GetWidthPercent());
o3tl::hash_combine(seed, GetWidthPercentRelation());
o3tl::hash_combine(seed, GetHeightPercent());
o3tl::hash_combine(seed, GetHeightPercentRelation());
o3tl::hash_combine(seed, GetSize().Width());
o3tl::hash_combine(seed, GetSize().Height());
return seed;
}
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}, SfxItemType::SwFormatFrameSizeType ),
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, SfxItemType::SwFormatFillOrderType, 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, SfxItemType::SwFormatHeaderType ),
SwClient( pHeaderFormat ),
m_bActive( pHeaderFormat )
{
}
SwFormatHeader::SwFormatHeader( const SwFormatHeader &rCpy )
: SfxPoolItem( RES_HEADER, SfxItemType::SwFormatHeaderType ),
SwClient( const_cast<sw::BroadcastingModify*>(static_cast<const sw::BroadcastingModify*>(rCpy.GetRegisteredIn())) ),
m_bActive( rCpy.IsActive() )
{
}
SwFormatHeader::SwFormatHeader( bool bOn )
: SfxPoolItem( RES_HEADER, SfxItemType::SwFormatHeaderType ),
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);
}
void SwFormatHeader::dumpAsXml(xmlTextWriterPtr pWriter) const
{
(void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatHeader"));
SfxPoolItem::dumpAsXml(pWriter);
const SwFrameFormat* pHeaderFormat = GetHeaderFormat();
if (pHeaderFormat)
{
pHeaderFormat->dumpAsXml(pWriter);
}
(void)xmlTextWriterEndElement(pWriter);
}
// Partially implemented inline in hxx
SwFormatFooter::SwFormatFooter( SwFrameFormat *pFooterFormat )
: SfxPoolItem( RES_FOOTER, SfxItemType::SwFormatFooterType ),
SwClient( pFooterFormat ),
m_bActive( pFooterFormat )
{
}
SwFormatFooter::SwFormatFooter( const SwFormatFooter &rCpy )
: SfxPoolItem( RES_FOOTER, SfxItemType::SwFormatFooterType ),
SwClient( const_cast<sw::BroadcastingModify*>(static_cast<const sw::BroadcastingModify*>(rCpy.GetRegisteredIn())) ),
m_bActive( rCpy.IsActive() )
{
}
SwFormatFooter::SwFormatFooter( bool bOn )
: SfxPoolItem( RES_FOOTER, SfxItemType::SwFormatFooterType ),
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 );
}
void SwFormatFooter::dumpAsXml(xmlTextWriterPtr pWriter) const
{
(void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatFooter"));
SfxPoolItem::dumpAsXml(pWriter);
const SwFrameFormat* pFooterFormat = GetFooterFormat();
if (pFooterFormat)
{
pFooterFormat->dumpAsXml(pWriter);
}
(void)xmlTextWriterEndElement(pWriter);
}
// Partially implemented inline in hxx
SwFormatContent::SwFormatContent( const SwFormatContent &rCpy )
: SfxPoolItem( RES_CNTNT, SfxItemType::SwFormatContentType )
, m_oStartNode( rCpy.m_oStartNode )
{
setNonShareable();
}
SwFormatContent::SwFormatContent( const SwStartNode *pStartNd )
: SfxPoolItem( RES_CNTNT, SfxItemType::SwFormatContentType )
{
setNonShareable();
if (pStartNd)
m_oStartNode = *pStartNd;
}
SwFormatContent::~SwFormatContent()
{
}
void SwFormatContent::SetNewContentIdx( const SwNodeIndex *pIdx )
{
if (pIdx)
m_oStartNode = *pIdx;
else
m_oStartNode.reset();
}
bool SwFormatContent::operator==( const SfxPoolItem& rAttr ) const
{
assert(SfxPoolItem::operator==(rAttr));
return m_oStartNode == static_cast<const SwFormatContent&>(rAttr).m_oStartNode;
}
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_oStartNode)
{
(void)xmlTextWriterWriteAttribute(
pWriter, BAD_CAST("startNode"),
BAD_CAST(OString::number(sal_Int32(m_oStartNode->GetNode().GetIndex())).getStr()));
(void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("startNodePtr"), "%p",
&m_oStartNode->GetNode());
}
(void)xmlTextWriterEndElement(pWriter);
}
// Partially implemented inline in hxx
SwFormatPageDesc::SwFormatPageDesc( const SwFormatPageDesc &rCpy )
: SfxPoolItem( RES_PAGEDESC, SfxItemType::SwFormatPageDescType ),
SwClient( const_cast<SwPageDesc*>(rCpy.GetPageDesc()) ),
m_oNumOffset( rCpy.m_oNumOffset ),
m_pDefinedIn( nullptr )
{
setNonShareable();
}
SwFormatPageDesc::SwFormatPageDesc( const SwPageDesc *pDesc )
: SfxPoolItem( RES_PAGEDESC, SfxItemType::SwFormatPageDescType ),
SwClient( const_cast<SwPageDesc*>(pDesc) ),
m_pDefinedIn( nullptr )
{
setNonShareable();
}
SwFormatPageDesc &SwFormatPageDesc::operator=(const SwFormatPageDesc &rCpy)
{
if (SfxPoolItem::areSame(*this, rCpy))
return *this;
ASSERT_CHANGE_REFCOUNTED_ITEM;
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() );
}
size_t SwFormatPageDesc::hashCode() const
{
std::size_t seed(0);
// note that we cannot include m_pDefinedIn in the hash because that is updated in SwAttrSet::SetModifyAtAttr
o3tl::hash_combine(seed, m_oNumOffset);
o3tl::hash_combine(seed, GetPageDesc());
return seed;
}
SwFormatPageDesc* SwFormatPageDesc::Clone( SfxItemPool* ) const
{
return new SwFormatPageDesc( *this );
}
void SwFormatPageDesc::SwClientNotify(const SwModify&, const SfxHint& rHint)
{
if(rHint.GetId() == SfxHintId::SwAutoFormatUsedHint)
{
if(GetRegisteredIn())
static_cast<const sw::AutoFormatUsedHint&>(rHint).SetUsed(); //TODO: recheck if this is really the right way to check for use
}
else if (rHint.GetId() == SfxHintId::SwPageDesc)
{
const SwPageDescHint* pHint = static_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 )
{
ASSERT_CHANGE_REFCOUNTED_ITEM;
// 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, SfxItemType::SwFormatColType ),
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 (!SfxPoolItem::areSame(*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, SfxItemType::SwFormatColType )
, 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, SfxItemType::SwFormatSurroundType, 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);
}
ItemInstanceManager* SwFormatVertOrient::getItemInstanceManager() const
{
static HashedItemInstanceManager aInstanceManager(ItemType());
return &aInstanceManager;
}
size_t SwFormatVertOrient::hashCode() const
{
std::size_t seed(0);
o3tl::hash_combine(seed, Which());
o3tl::hash_combine(seed, GetPos());
o3tl::hash_combine(seed, GetVertOrient());
o3tl::hash_combine(seed, GetRelationOrient());
return seed;
}
// Partially implemented inline in hxx
SwFormatVertOrient::SwFormatVertOrient( SwTwips nY, sal_Int16 eVert,
sal_Int16 eRel )
: SfxPoolItem( RES_VERT_ORIENT, SfxItemType::SwFormatVertOrientType ),
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);
}
ItemInstanceManager* SwFormatHoriOrient::getItemInstanceManager() const
{
static HashedItemInstanceManager aInstanceManager(ItemType());
return &aInstanceManager;
}
size_t SwFormatHoriOrient::hashCode() const
{
std::size_t seed(0);
o3tl::hash_combine(seed, Which());
o3tl::hash_combine(seed, GetPos());
o3tl::hash_combine(seed, GetHoriOrient());
o3tl::hash_combine(seed, GetRelationOrient());
o3tl::hash_combine(seed, IsPosToggle());
return seed;
}
// Partially implemented inline in hxx
SwFormatHoriOrient::SwFormatHoriOrient( SwTwips nX, sal_Int16 eHori,
sal_Int16 eRel, bool bPos )
: SfxPoolItem( RES_HORI_ORIENT, SfxItemType::SwFormatHoriOrientType ),
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);
}
SwFormatAnchor::SwFormatAnchor( RndStdIds nRnd, sal_uInt16 nPage )
: SfxPoolItem( RES_ANCHOR, SfxItemType::SwFormatAnchorType ),
m_eAnchorId( nRnd ),
m_nPageNumber( nPage ),
// OD 2004-05-05 #i28701# - get always new increased order number
m_nOrder( ++s_nOrderCounter )
{
setNonShareable();
assert( m_eAnchorId == RndStdIds::FLY_AT_PARA
|| m_eAnchorId == RndStdIds::FLY_AS_CHAR
|| m_eAnchorId == RndStdIds::FLY_AT_PAGE
|| m_eAnchorId == RndStdIds::FLY_AT_FLY
|| m_eAnchorId == RndStdIds::FLY_AT_CHAR);
// only FLY_AT_PAGE should have a valid page
assert( m_eAnchorId == RndStdIds::FLY_AT_PAGE || nPage == 0 );
}
SwFormatAnchor::SwFormatAnchor( const SwFormatAnchor &rCpy )
: SfxPoolItem( RES_ANCHOR, SfxItemType::SwFormatAnchorType )
, m_oContentAnchor( rCpy.m_oContentAnchor )
, m_eAnchorId( rCpy.m_eAnchorId )
, m_nPageNumber( rCpy.m_nPageNumber )
// OD 2004-05-05 #i28701# - get always new increased order number
, m_nOrder( ++s_nOrderCounter )
{
setNonShareable();
}
SwFormatAnchor::~SwFormatAnchor()
{
}
void SwFormatAnchor::SetAnchor( const SwPosition *pPos )
{
if (!pPos)
{
m_oContentAnchor.reset();
return;
}
// 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((RndStdIds::FLY_AT_FLY == m_eAnchorId && pPos->GetNode().GetStartNode())
|| (RndStdIds::FLY_AT_PARA == m_eAnchorId && pPos->GetNode().GetTableNode())
|| pPos->GetNode().GetTextNode());
// verify that the SwPosition being passed to us is not screwy
assert(!pPos->nContent.GetContentNode()
|| &pPos->nNode.GetNode() == pPos->nContent.GetContentNode());
m_oContentAnchor.emplace(*pPos);
// Flys anchored AT paragraph should not point into the paragraph content
if ((RndStdIds::FLY_AT_PARA == m_eAnchorId) || (RndStdIds::FLY_AT_FLY == m_eAnchorId))
m_oContentAnchor->nContent.Assign( nullptr, 0 );
}
SwNode* SwFormatAnchor::GetAnchorNode() const
{
if (!m_oContentAnchor)
return nullptr;
if (auto pCntNd = m_oContentAnchor->nContent.GetContentNode())
return const_cast<SwContentNode*>(pCntNd);
return &m_oContentAnchor->nNode.GetNode();
}
SwContentNode* SwFormatAnchor::GetAnchorContentNode() const
{
SwNode* pAnchorNode = GetAnchorNode();
if (pAnchorNode)
return pAnchorNode->GetContentNode();
return nullptr;
}
sal_Int32 SwFormatAnchor::GetAnchorContentOffset() const
{
if (!m_oContentAnchor)
return 0;
if (m_oContentAnchor->nContent.GetContentNode())
return m_oContentAnchor->nContent.GetIndex();
return 0;
}
SwFormatAnchor& SwFormatAnchor::operator=(const SwFormatAnchor& rAnchor)
{
if (!SfxPoolItem::areSame(*this, rAnchor))
{
m_eAnchorId = rAnchor.m_eAnchorId;
m_nPageNumber = rAnchor.m_nPageNumber;
// OD 2004-05-05 #i28701# - get always new increased order number
m_nOrder = ++s_nOrderCounter;
m_oContentAnchor = rAnchor.m_oContentAnchor;
}
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.m_eAnchorId &&
m_nPageNumber == rFormatAnchor.m_nPageNumber &&
// compare anchor: either both do not point into a textnode or
// both do (valid m_oContentAnchor) and the positions are equal
(m_oContentAnchor == rFormatAnchor.m_oContentAnchor) );
}
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 (m_eAnchorId)
{
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_oContentAnchor && RndStdIds::FLY_AT_FLY == m_eAnchorId)
{
SwFrameFormat* pFormat = m_oContentAnchor->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_oContentAnchor.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:
eAnchor = RndStdIds::FLY_AT_PARA;
break;
default:
eAnchor = RndStdIds::FLY_AT_PARA; // just to keep some compilers happy
assert(false);
}
SetType( eAnchor );
}
break;
case MID_ANCHOR_PAGENUM:
{
sal_Int16 nVal = 0;
if((rVal >>= nVal) && nVal > 0)
{
if (RndStdIds::FLY_AT_PAGE == m_eAnchorId)
{
SetPageNum( nVal );
// 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_oContentAnchor.reset();
}
else
{
assert(false && "cannot set page number on this anchor type");
bRet = false;
}
}
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_oContentAnchor)
{
std::stringstream aContentAnchor;
aContentAnchor << *m_oContentAnchor;
(void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_pContentAnchor"), BAD_CAST(aContentAnchor.str().c_str()));
}
else
(void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_pContentAnchor"), BAD_CAST("(nil)"));
(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, SfxItemType::SwFormatURLType ),
m_bIsServerMap( false )
{
}
SwFormatURL::SwFormatURL( const SwFormatURL &rURL) :
SfxPoolItem( RES_URL, SfxItemType::SwFormatURLType ),
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 );
}
void SwFormatEndAtTextEnd::dumpAsXml(xmlTextWriterPtr pWriter) const
{
(void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatEndAtTextEnd"));
(void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
(void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(OString::number(GetValue()).getStr()));
(void)xmlTextWriterEndElement(pWriter);
}
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, SfxItemType::SwFormatChainType )
{
setNonShareable();
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, SfxItemType::SwFormatLineNumberType )
{
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, SfxItemType::SwTextGridItemType )
, 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( 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 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 (SwNode* pAnchorNode = rAnchor.GetAnchorNode())
{
pAnchorNode->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::SetFormatName( const OUString& rNewName, bool bBroadcast )
{
if (m_ffList != nullptr) {
SAL_INFO_IF(m_aFormatName == rNewName, "sw.core", "SwFrmFmt not really renamed, as both names are equal");
sw::NameChanged aHint(m_aFormatName, rNewName);
m_ffList->Rename(*this, rNewName);
if (bBroadcast) {
GetNotifier().Broadcast(aHint);
}
// update accessibility sidebar object name if we modify the object name on the navigator bar
const bool bUpdateA11yName = !aHint.m_sOld.isEmpty() && aHint.m_sOld != aHint.m_sNew;
if (!bUpdateA11yName)
return;
SwFlyFrame* pSFly = SwIterator<SwFlyFrame, SwFormat>(*this).First();
if (!pSFly)
return;
SwFrame *pSFlyLower = pSFly->Lower();
if (!pSFlyLower)
return;
if (!pSFlyLower->IsNoTextFrame())
{
SwContentFrame* pContent = pSFly->ContainsContent();
if (SwTextNode* pSwTxtNode = pContent ? static_cast<SwTextFrame*>(pContent)->GetTextNodeFirst() : nullptr)
pSwTxtNode->resetAndQueueAccessibilityCheck(true);
}
else
{
if (SwNode* pSwNode = static_cast<SwNoTextFrame*>(pSFlyLower)->GetNode())
pSwNode->resetAndQueueAccessibilityCheck(true);
}
}
else
SwFormat::SetFormatName( 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;
SwNode* pNewAnchorNode = 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)
{
pNewAnchorNode = pAnchor->GetAnchorNode();
assert(pNewAnchorNode == 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:
pNewAnchorNode = static_cast<const SwFormatAnchor*>(pLegacy->m_pNew)->GetAnchorNode();
break;
}
const sal_uInt16 nOldWhich = pLegacy->m_pOld ? pLegacy->m_pOld->Which() : 0;
SwNode* pOldAnchorNode = 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)
{
pOldAnchorNode = pAnchor->GetAnchorNode();
assert(pOldAnchorNode == nullptr || // style's set must not contain position!
pOldAttrSetChg->GetTheChgdSet() == &m_aSet);
}
break;
}
case RES_ANCHOR:
pOldAnchorNode = static_cast<const SwFormatAnchor*>(pLegacy->m_pOld)->GetAnchorNode();
break;
case RES_REMOVE_UNO_OBJECT:
SetXObject(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(pOldAnchorNode != nullptr && (pNewAnchorNode == nullptr || pOldAnchorNode->GetIndex() != pNewAnchorNode->GetIndex()))
pOldAnchorNode->RemoveAnchoredFly(this);
if(pNewAnchorNode != nullptr && (pOldAnchorNode == nullptr || pOldAnchorNode->GetIndex() != pNewAnchorNode->GetIndex()))
pNewAnchorNode->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));
if( pFly )
return pFly->GetVirtDrawObj();
SwDoc* pDoc = GetDoc();
if (!pDoc)
return nullptr;
SwDocShell* pShell = pDoc->GetDocShell();
if (!pShell)
return nullptr;
if (pShell->GetCreateMode() != SfxObjectCreateMode::EMBEDDED )
return nullptr;
// tdf#126477 fix lost charts in embedded documents
}
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->GetAnchorNode())
{
const SwNode* pFlyNd = pAnchor->GetAnchorNode()->FindFlyStartNode();
while( pFlyNd )
{
// then we walk up using the anchor
for(const sw::SpzFrameFormat* pFormat: *GetDoc()->GetSpzFrameFormats())
{
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->GetAnchorNode() )
{
return false;
}
pFlyNd = pAnchor->GetAnchorNode()->FindFlyStartNode();
break;
}
}
}
}
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("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());
}
SwFormat::dumpAsXml(pWriter);
if (const SdrObject* pSdrObject = FindSdrObject())
pSdrObject->dumpAsXml(pWriter);
(void)xmlTextWriterEndElement(pWriter);
}
SwFlyFrameFormat::SwFlyFrameFormat(SwAttrPool& rPool, const OUString &rFormatName, SwFrameFormat* pDerivedFrame)
: sw::SpzFrameFormat(rPool, rFormatName, pDerivedFrame, 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& rDrawModel(GetDoc()->getIDocumentDrawModelAccess().GetOrCreateDrawModel());
m_pContact.reset(new SwFlyDrawContact(this, rDrawModel));
}
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.GetAnchorNode() )
{
pModify = aAnchorAttr.GetAnchorNode()->GetContentNode();
}
break;
case RndStdIds::FLY_AT_FLY:
if( aAnchorAttr.GetAnchorNode() )
{
//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.GetAnchorNode() );
SwContentNode* pCNd = SwNodes::GoNext(&aIdx);
// #i105535#
if ( pCNd == nullptr )
{
pCNd = aAnchorAttr.GetAnchorNode()->GetContentNode();
}
if ( pCNd )
{
if (SwIterator<SwFrame, SwContentNode, sw::IteratorMode::UnwrapMulti>(*pCNd).First())
{
pModify = pCNd;
}
}
// #i105535#
if ( pModify == nullptr )
{
const SwNode & rNd = *aAnchorAttr.GetAnchorNode();
for(sw::SpzFrameFormat* pFlyFormat: *GetDoc()->GetSpzFrameFormats())
{
if( pFlyFormat->GetContent().GetContentIdx() &&
rNd == pFlyFormat->GetContent().GetContentIdx()->GetNode() )
{
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.GetAnchorNode() )
{
SwContentNode *pCNd = aAnchorAttr.GetAnchorNode()->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;
}
}
// #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 sw::TitleChanged aHint(pMasterObject->GetTitle(), rTitle);
pMasterObject->SetTitle(rTitle);
if(bBroadcast)
{
GetNotifier().Broadcast(aHint);
}
}
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 sw::DescriptionChanged aHint;
pMasterObject->SetDescription(rDescription);
if(bBroadcast)
{
GetNotifier().Broadcast(aHint);
}
}
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;
}
bool SwFlyFrameFormat::IsDecorative() const
{
const SdrObject* pMasterObject = FindSdrObject();
OSL_ENSURE(pMasterObject, "<SwFlyFrameFormat::SetDescription(..)> - missing <SdrObject> instance");
if (!pMasterObject)
{
return false;
}
return pMasterObject->IsDecorative();
}
void SwFlyFrameFormat::SetObjDecorative(bool const isDecorative)
{
SdrObject* pMasterObject = FindSdrObject();
OSL_ENSURE( pMasterObject, "<SwFlyFrameFormat::SetDescription(..)> - missing <SdrObject> instance" );
if ( !pMasterObject )
{
return;
}
SetFormatAttr(SfxBoolItem(RES_DECORATIVE, isDecorative));
pMasterObject->SetDecorative(isDecorative);
// does anybody care about a broadcast?
}
/** 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.GetAnchorNode() &&
_rNewAnchorFormat.GetAnchorNode()->GetContentNode() )
{
if ( aOldAnchorFormat.GetAnchorId() == nNewAnchorType &&
aOldAnchorFormat.GetAnchorNode() &&
aOldAnchorFormat.GetAnchorNode()->GetContentNode() &&
aOldAnchorFormat.GetContentAnchor()->GetNode() !=
_rNewAnchorFormat.GetContentAnchor()->GetNode() )
{
// determine 'old' number of anchor frames
sal_uInt32 nOldNumOfAnchFrame( 0 );
SwIterator<SwFrame, SwContentNode, sw::IteratorMode::UnwrapMulti> aOldIter(
*(aOldAnchorFormat.GetAnchorNode()->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.GetAnchorNode()->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.GetAnchorNode()
&& aOldAnchorFormat.GetAnchorId() == RndStdIds::FLY_AT_CHAR)
{
moCommentAnchor.emplace(*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 (!moCommentAnchor)
{
return;
}
SwTextNode* pTextNode = moCommentAnchor->GetNode().GetTextNode();
if (!pTextNode)
{
return;
}
const SwTextField* pField = pTextNode->GetFieldTextAttrAt(moCommentAnchor->GetContentIndex());
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() = *moCommentAnchor;
rCursor.SetMark();
*rCursor.GetMark() = *moCommentAnchor;
rCursor.GetMark()->AdjustContent(+1);
}
// 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 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));
}
bool SwFrameFormat::IsVisible() const
{
return SwIterator<SwFrame, SwFrameFormat>(*this).First();
};
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.GetAnchorNode() == pNode);
}
}
if(!rDoc.GetSpzFrameFormats())
return;
for(sw::SpzFrameFormat* pSpz: *rDoc.GetSpzFrameFormats())
{
SwFormatAnchor const& rAnchor(pSpz->GetAnchor(false));
if (RndStdIds::FLY_AT_PAGE == rAnchor.GetAnchorId())
{
assert(!rAnchor.GetAnchorNode()
// for invalid documents that lack text:anchor-page-number
// it may have an anchor before MakeFrames() is called
|| (!SwIterator<SwFrame, SwFrameFormat>(*pSpz).First()));
}
else
{
SwNode & rNode(*rAnchor.GetAnchorNode());
std::vector<SwFrameFormat*> const& rFlys(rNode.GetAnchoredFlys());
assert(std::find(rFlys.begin(), rFlys.end(), pSpz) != 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: */
↑ V678 An object is used as an argument to its own method. Consider checking the first actual argument of the 'Copy' function.
↑ V1053 Calling the 'CallSwClientNotify' virtual function in the destructor may lead to unexpected result at runtime.
↑ V794 The assignment operator should be protected from the case of 'this == &rCpy'.