/* -*- 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>
#include <names.hxx>
using namespace ::com::sun::star;
namespace sw {
bool GetAtPageRelOrientation(sal_Int16 & rOrientation,
bool const isIgnorePrintAre
a)
{
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( sw::FrameFormatClient *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& rDoc = pFormat->GetDoc();
pFormat->Remove(*pToRemove);
if ( rDoc.IsInDtor() )
{
delete pFormat;
return ;
}
// Anything other than frames registered?
if (!pFormat->HasOnlySpecificWriterListeners<SwFrame>())
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(rDoc.GetIDocumentUndoRedo());
OSL_ENSURE( pNode, "A big problem." );
rDoc.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} ),
m_eFrameHeightType( eSize ),
m_eFrameWidthType( SwFrameSize::Fixed )
{
m_nWidthPercent = m_eWidthPercentRelation = m_nHeightPercent = m_eHeightPercentRelation = 0;
}
bool SwFormatFrameSize::operator ==( const SfxPoolItem& rAttr ) const
{
assert(SfxPoolItem::operator ==(rAttr));
return ( m_eFrameHeightType == static_cast <const SwFormatFrameSize&>(rAttr).m_eFrameHeightType &&
m_eFrameWidthType == static_cast <const SwFormatFrameSize&>(rAttr).m_eFrameWidthType &&
SvxSizeItem::operator ==(rAttr)&&
m_nWidthPercent == static_cast <const SwFormatFrameSize&>(rAttr).GetWidthPercent() &&
m_eWidthPercentRelation == static_cast <const SwFormatFrameSize&>(rAttr).GetWidthPercentRelation() &&
m_nHeightPercent == static_cast <const SwFormatFrameSize&>(rAttr).GetHeightPercent() &&
m_eHeightPercentRelation == static_cast <const SwFormatFrameSize&>(rAttr).GetHeightPercentRelation() );
}
SwFormatFrameSize* SwFormatFrameSize::Clone( SfxItemPool* ) const
{
return new SwFormatFrameSize( *this );
}
bool SwFormatFrameSize::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
{
// here we convert always!
nMemberId &= ~CONVERT_TWIPS;
switch ( nMemberId )
{
case MID_FRMSIZE_SIZE:
{
awt::Size aTmp;
aTmp.Height = convertTwipToMm100(GetHeight());
aTmp.Width = convertTwipToMm100(GetWidth());
rVal <<= aTmp;
}
break ;
case MID_FRMSIZE_REL_HEIGHT:
rVal <<= static_cast <sal_Int16>(GetHeightPercent() != SwFormatFrameSize::SYNCED ? GetHeightPercent() : 0);
break ;
case MID_FRMSIZE_REL_HEIGHT_RELATION:
rVal <<= GetHeightPercentRelation();
break ;
case MID_FRMSIZE_REL_WIDTH:
rVal <<= static_cast <sal_Int16>(GetWidthPercent() != SwFormatFrameSize::SYNCED ? GetWidthPercent() : 0);
break ;
case MID_FRMSIZE_REL_WIDTH_RELATION:
rVal <<= GetWidthPercentRelation();
break ;
case MID_FRMSIZE_IS_SYNC_HEIGHT_TO_WIDTH:
rVal <<= SwFormatFrameSize::SYNCED == GetHeightPercent();
break ;
case MID_FRMSIZE_IS_SYNC_WIDTH_TO_HEIGHT:
rVal <<= SwFormatFrameSize::SYNCED == GetWidthPercent();
break ;
case MID_FRMSIZE_WIDTH :
rVal <<= static_cast <sal_Int32>(convertTwipToMm100(GetWidth()));
break ;
case MID_FRMSIZE_HEIGHT:
// #95848# returned size should never be zero.
// (there was a bug that allowed for setting height to 0.
// Thus there some documents existing with that not allowed
// attribute value which may cause problems on import.)
rVal <<= static_cast <sal_Int32>(convertTwipToMm100(GetHeight() < MINLAY ? MINLAY : GetHeight() ));
break ;
case MID_FRMSIZE_SIZE_TYPE:
rVal <<= static_cast <sal_Int16>(GetHeightSizeType());
break ;
case MID_FRMSIZE_IS_AUTO_HEIGHT:
rVal <<= SwFrameSize::Fixed != GetHeightSizeType();
break ;
case MID_FRMSIZE_WIDTH_TYPE:
rVal <<= static_cast <sal_Int16>(GetWidthSizeType());
break ;
}
return true ;
}
bool SwFormatFrameSize::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
{
bool bConvert = 0 != (nMemberId&CONVERT_TWIPS);
nMemberId &= ~CONVERT_TWIPS;
bool bRet = true ;
switch ( nMemberId )
{
case MID_FRMSIZE_SIZE:
{
awt::Size aVal;
if (!(rVal >>= aVal))
bRet = false ;
else
{
Size aTmp(aVal.Width, aVal.Height);
if (bConvert)
{
aTmp.setHeight(o3tl::toTwips(aTmp.Height(), o3tl::Length::mm100));
aTmp.setWidth(o3tl::toTwips(aTmp.Width(), o3tl::Length::mm100));
}
SetSize(aTmp);
}
}
break ;
case MID_FRMSIZE_REL_HEIGHT:
{
sal_Int16 nSet = 0;
rVal >>= nSet;
if (nSet >= 0 && nSet < SwFormatFrameSize::SYNCED)
SetHeightPercent(static_cast <sal_uInt8>(nSet));
else
bRet = false ;
}
break ;
case MID_FRMSIZE_REL_HEIGHT_RELATION:
{
sal_Int16 eSet = 0;
rVal >>= eSet;
SetHeightPercentRelation(eSet);
}
break ;
case MID_FRMSIZE_REL_WIDTH:
{
sal_Int16 nSet = 0;
rVal >>= nSet;
if (nSet >= 0 && nSet < SwFormatFrameSize::SYNCED)
SetWidthPercent(static_cast <sal_uInt8>(nSet));
else
bRet = false ;
}
break ;
case MID_FRMSIZE_REL_WIDTH_RELATION:
{
sal_Int16 eSet = 0;
rVal >>= eSet;
SetWidthPercentRelation(eSet);
}
break ;
case MID_FRMSIZE_IS_SYNC_HEIGHT_TO_WIDTH:
{
bool bSet = *o3tl::doAccess<bool >(rVal);
if (bSet)
SetHeightPercent(SwFormatFrameSize::SYNCED);
else if ( SwFormatFrameSize::SYNCED == GetHeightPercent() )
SetHeightPercent( 0 );
}
break ;
case MID_FRMSIZE_IS_SYNC_WIDTH_TO_HEIGHT:
{
bool bSet = *o3tl::doAccess<bool >(rVal);
if (bSet)
SetWidthPercent(SwFormatFrameSize::SYNCED);
else if ( SwFormatFrameSize::SYNCED == GetWidthPercent() )
SetWidthPercent(0);
}
break ;
case MID_FRMSIZE_WIDTH :
{
sal_Int32 nWd = 0;
if (rVal >>= nWd)
{
if (bConvert)
nWd = o3tl::toTwips(nWd, o3tl::Length::mm100);
if (nWd < MINLAY)
nWd = MINLAY;
SetWidth(nWd);
}
else
bRet = false ;
}
break ;
case MID_FRMSIZE_HEIGHT:
{
sal_Int32 nHg = 0;
if (rVal >>= nHg)
{
if (bConvert)
nHg = o3tl::toTwips(nHg, o3tl::Length::mm100);
if (nHg < MINLAY)
nHg = MINLAY;
SetHeight(nHg);
}
else
bRet = false ;
}
break ;
case MID_FRMSIZE_SIZE_TYPE:
{
sal_Int16 nType = 0;
if ((rVal >>= nType) && nType >= 0 && nType <= static_cast <int >(SwFrameSize::Minimum) )
{
SetHeightSizeType(static_cast <SwFrameSize>(nType));
}
else
bRet = false ;
}
break ;
case MID_FRMSIZE_IS_AUTO_HEIGHT:
{
bool bSet = *o3tl::doAccess<bool >(rVal);
SetHeightSizeType(bSet ? SwFrameSize::Variable : SwFrameSize::Fixed);
}
break ;
case MID_FRMSIZE_WIDTH_TYPE:
{
sal_Int16 nType = 0;
if ((rVal >>= nType) && nType >= 0 && nType <= static_cast <int >(SwFrameSize::Minimum) )
{
SetWidthSizeType(static_cast <SwFrameSize>(nType));
}
else
bRet = false ;
}
break ;
default :
bRet = false ;
}
return bRet;
}
void SwFormatFrameSize::dumpAsXml(xmlTextWriterPtr pWriter) const
{
(void )xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatFrameSize" ));
(void )xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId" ), BAD_CAST(OString::number(Which()).getStr()));
std::stringstream aSize;
aSize << GetSize();
(void )xmlTextWriterWriteAttribute(pWriter, BAD_CAST("size" ), BAD_CAST(aSize.str().c_str()));
(void )xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eFrameHeightType" ), BAD_CAST(OString::number(static_cast <int >(m_eFrameHeightType)).getStr()));
(void )xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eFrameWidthType" ), BAD_CAST(OString::number(static_cast <int >(m_eFrameWidthType)).getStr()));
(void )xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nWidthPercent" ), BAD_CAST(OString::number(m_nWidthPercent).getStr()));
(void )xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eWidthPercentRelation" ), BAD_CAST(OString::number(m_eWidthPercentRelation).getStr()));
(void )xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nHeightPercent" ), BAD_CAST(OString::number(m_nHeightPercent).getStr()));
(void )xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eHeightPercentRelation" ), BAD_CAST(OString::number(m_eHeightPercentRelation).getStr()));
(void )xmlTextWriterEndElement(pWriter);
}
// Partially implemented inline in hxx
SwFormatFillOrder::SwFormatFillOrder( SwFillOrder nFO )
: SfxEnumItem( RES_FILL_ORDER, nFO )
{}
SwFormatFillOrder* SwFormatFillOrder::Clone( SfxItemPool* ) const
{
return new SwFormatFillOrder( GetValue() );
}
// Partially implemented inline in hxx
SwFormatHeader::SwFormatHeader( SwFrameFormat *pHeaderFormat )
: SfxPoolItem( RES_HEADER ),
sw::FrameFormatClient( pHeaderFormat ),
m_bActive( pHeaderFormat )
{
}
SwFormatHeader::SwFormatHeader( const SwFormatHeader &rCpy )
: SfxPoolItem( RES_HEADER ),
sw::FrameFormatClient( const_cast <SwFrameFormat*>(rCpy.GetRegisteredIn()) ),
m_bActive( rCpy.IsActive() )
{
}
SwFormatHeader::SwFormatHeader( bool bOn )
: SfxPoolItem( RES_HEADER ),
sw::FrameFormatClient( 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( SwFrameFormat& 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 ),
sw::FrameFormatClient( pFooterFormat ),
m_bActive( pFooterFormat )
{
}
SwFormatFooter::SwFormatFooter( const SwFormatFooter &rCpy )
: SfxPoolItem( RES_FOOTER ),
sw::FrameFormatClient( const_cast <SwFrameFormat*>(rCpy.GetRegisteredIn()) ),
m_bActive( rCpy.IsActive() )
{
}
SwFormatFooter::SwFormatFooter( bool bOn )
: SfxPoolItem( RES_FOOTER ),
sw::FrameFormatClient( 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 )
, m_oStartNode( rCpy.m_oStartNode )
{
setNonShareable();
}
SwFormatContent::SwFormatContent( const SwStartNode *pStartNd )
: SfxPoolItem( RES_CNTNT )
{
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 ),
SwClient( const_cast <SwPageDesc*>(rCpy.GetPageDesc()) ),
m_oNumOffset( rCpy.m_oNumOffset ),
m_pDefinedIn( nullptr )
{
setNonShareable();
}
SwFormatPageDesc::SwFormatPageDesc( const SwPageDesc *pDesc )
: SfxPoolItem( RES_PAGEDESC ),
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::SwObjectDying)
{
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 )
{
ProgName aString;
SwStyleNameMapper::FillProgName(pDesc->GetName(), aString, SwGetPoolIdFromName::PageDesc);
rVal <<= aString.toString();
}
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().toString().toUtf8().getStr()));
(void )xmlTextWriterEndElement(pWriter);
}
// class SwFormatCol
// Partially implemented inline in hxx
SwColumn::SwColumn() :
m_nWish ( 0 ),
m_nLeft ( 0 ),
m_nRight( 0 )
{
}
bool SwColumn::operator ==( const SwColumn &rCmp ) const
{
return m_nWish == rCmp.GetWishWidth() &&
GetLeft() == rCmp.GetLeft() &&
GetRight() == rCmp.GetRight();
}
void SwColumn::dumpAsXml(xmlTextWriterPtr pWriter) const
{
(void )xmlTextWriterStartElement(pWriter, BAD_CAST("SwColumn" ));
(void )xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nWish" ), BAD_CAST(OString::number(m_nWish).getStr()));
(void )xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nUpper" ), BAD_CAST(OString::number(0).getStr()));
(void )xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nLower" ), BAD_CAST(OString::number(0).getStr()));
(void )xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nLeft" ), BAD_CAST(OString::number(m_nLeft).getStr()));
(void )xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nRight" ), BAD_CAST(OString::number(m_nRight).getStr()));
(void )xmlTextWriterEndElement(pWriter);
}
SwFormatCol::SwFormatCol( const SwFormatCol& rCpy )
: SfxPoolItem( RES_COL ),
m_eLineStyle( rCpy.m_eLineStyle ),
m_nLineWidth( rCpy.m_nLineWidth),
m_aLineColor( rCpy.m_aLineColor),
m_nLineHeight( rCpy.GetLineHeight() ),
m_eAdj( rCpy.GetLineAdj() ),
m_nWidth( rCpy.GetWishWidth() ),
m_aWidthAdjustValue( rCpy.m_aWidthAdjustValue ),
m_bOrtho( rCpy.IsOrtho() )
{
m_aColumns.reserve(rCpy.GetNumCols());
for ( sal_uInt16 i = 0; i < rCpy.GetNumCols(); ++i )
{
m_aColumns.emplace_back(rCpy.GetColumns()[i] );
}
}
SwFormatCol::~SwFormatCol() {}
SwFormatCol& SwFormatCol::operator =( const SwFormatCol& rCpy )
{
if (!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 )
, m_eLineStyle( SvxBorderLineStyle::NONE)
,
m_nLineWidth(0),
m_nLineHeight( 100 ),
m_eAdj( COLADJ_NONE ),
m_nWidth( USHRT_MAX ),
m_aWidthAdjustValue( 0 ),
m_bOrtho( true )
{
}
bool SwFormatCol::operator ==( const SfxPoolItem& rAttr ) const
{
assert(SfxPoolItem::operator ==(rAttr));
const SwFormatCol &rCmp = static_cast <const SwFormatCol&>(rAttr);
if ( !(m_eLineStyle == rCmp.m_eLineStyle &&
m_nLineWidth == rCmp.m_nLineWidth &&
m_aLineColor == rCmp.m_aLineColor &&
m_nLineHeight == rCmp.GetLineHeight() &&
m_eAdj == rCmp.GetLineAdj() &&
m_nWidth == rCmp.GetWishWidth() &&
m_bOrtho == rCmp.IsOrtho() &&
m_aColumns.size() == rCmp.GetNumCols() &&
m_aWidthAdjustValue == rCmp.GetAdjustValue()
) )
return false ;
for ( size_t i = 0; i < m_aColumns.size(); ++i )
if ( !(m_aColumns[i] == rCmp.GetColumns()[i]) )
return false ;
return true ;
}
SwFormatCol* SwFormatCol::Clone( SfxItemPool* ) const
{
return new SwFormatCol( *this );
}
sal_uInt16 SwFormatCol::GetGutterWidth( bool bMin ) const
{
sal_uInt16 nRet = 0;
if ( m_aColumns.size() == 2 )
nRet = m_aColumns[0].GetRight() + m_aColumns[1].GetLeft();
else if ( m_aColumns.size() > 2 )
{
bool bSet = false ;
for ( size_t i = 1; i+1 < m_aColumns.size(); ++i )
{
const sal_uInt16 nTmp = m_aColumns[i].GetRight() + m_aColumns[i+1].GetLeft();
if ( bSet )
{
if ( nTmp != nRet )
{
if ( !bMin )
return USHRT_MAX;
if ( nRet > nTmp )
nRet = nTmp;
}
}
else
{
bSet = true ;
nRet = nTmp;
}
}
}
return nRet;
}
void SwFormatCol::SetGutterWidth( sal_uInt16 nNew, sal_uInt16 nAct )
{
if ( m_bOrtho )
Calc( nNew, nAct );
else
{
sal_uInt16 nHalf = nNew / 2;
for (size_t i = 0; i < m_aColumns.size(); ++i)
{
SwColumn &rCol = m_aColumns[i];
rCol.SetLeft(nHalf);
rCol.SetRight(nHalf);
if ( i == 0 )
rCol.SetLeft(0);
else if ( i+1 == m_aColumns.size() )
rCol.SetRight(0);
}
}
}
void SwFormatCol::Init( sal_uInt16 nNumCols, sal_uInt16 nGutterWidth, sal_uInt16 nAct )
{
// Deleting seems to be a bit radical on the first sight; but otherwise we
// have to initialize all values of the remaining SwColumns.
m_aColumns.clear();
for ( sal_uInt16 i = 0; i < nNumCols; ++i )
{
m_aColumns.emplace_back( );
}
m_bOrtho = true ;
m_nWidth = USHRT_MAX;
if ( nNumCols )
Calc( nGutterWidth, nAct );
}
void SwFormatCol::SetOrtho( bool bNew, sal_uInt16 nGutterWidth, sal_uInt16 nAct )
{
m_bOrtho = bNew;
if ( bNew && !m_aColumns.empty() )
Calc( nGutterWidth, nAct );
}
sal_uInt16 SwFormatCol::CalcColWidth( sal_uInt16 nCol, sal_uInt16 nAct ) const
{
assert(nCol < m_aColumns.size());
if ( m_nWidth != nAct )
{
tools::Long nW = m_aColumns[nCol].GetWishWidth();
nW *= nAct;
nW /= m_nWidth;
return sal_uInt16(nW);
}
else
return m_aColumns[nCol].GetWishWidth();
}
sal_uInt16 SwFormatCol::CalcPrtColWidth( sal_uInt16 nCol, sal_uInt16 nAct ) const
{
assert(nCol < m_aColumns.size());
sal_uInt16 nRet = CalcColWidth( nCol, nAct );
const SwColumn *pCol = &m_aColumns[nCol];
nRet = nRet - pCol->GetLeft();
nRet = nRet - pCol->GetRight();
return nRet;
}
void SwFormatCol::Calc( sal_uInt16 nGutterWidth, sal_uInt16 nAct )
{
if (!GetNumCols())
return ;
//First set the column widths with the current width, then calculate the
//column's requested width using the requested total width.
const sal_uInt16 nGutterHalf = nGutterWidth ? nGutterWidth / 2 : 0;
//Width of PrtAreas is totalwidth - spacings / count
sal_uInt16 nSpacings;
bool bFail = o3tl::checked_multiply<sal_uInt16>(GetNumCols() - 1, nGutterWidth, nSpacings);
if (bFail)
{
SAL_WARN("sw.core" , "SwFormatVertOrient::Calc: overflow" );
return ;
}
const sal_uInt16 nPrtWidth = (nAct - nSpacings) / GetNumCols();
sal_uInt16 nAvail = nAct;
//The first column is PrtWidth + (gap width / 2)
const sal_uInt16 nLeftWidth = nPrtWidth + nGutterHalf;
SwColumn &rFirstCol = m_aColumns.front();
rFirstCol.SetWishWidth(nLeftWidth);
rFirstCol.SetRight(nGutterHalf);
rFirstCol.SetLeft(0);
nAvail = nAvail - nLeftWidth;
//Column 2 to n-1 is PrtWidth + gap width
const sal_uInt16 nMidWidth = nPrtWidth + nGutterWidth;
for (sal_uInt16 i = 1; i < GetNumCols()-1; ++i)
{
SwColumn &rCol = m_aColumns[i];
rCol.SetWishWidth(nMidWidth);
rCol.SetLeft(nGutterHalf);
rCol.SetRight(nGutterHalf);
nAvail = nAvail - nMidWidth;
}
//The last column is equivalent to the first one - to compensate rounding
//errors we add the remaining space of the other columns to the last one.
SwColumn &rLastCol = m_aColumns.back();
rLastCol.SetWishWidth(nAvail);
rLastCol.SetLeft(nGutterHalf);
rLastCol.SetRight(0);
assert(nAct != 0);
//Convert the current width to the requested width.
for (SwColumn &rCol: m_aColumns)
{
tools::Long nTmp = rCol.GetWishWidth();
nTmp *= GetWishWidth();
nTmp = nAct == 0 ? nTmp : nTmp / nAct;
rCol.SetWishWidth(sal_uInt16(nTmp));
}
}
bool SwFormatCol::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
{
// here we convert always!
nMemberId &= ~CONVERT_TWIPS;
if (MID_COLUMN_SEPARATOR_LINE == nMemberId)
{
OSL_FAIL("not implemented" );
}
else
{
uno::Reference<text::XTextColumns> xCols(SvxXTextColumns_createInstance(),
css::uno::UNO_QUERY_THROW);
uno::Reference<beans::XPropertySet> xProps(xCols, css::uno::UNO_QUERY_THROW);
if (GetNumCols() > 0)
{
xCols->setColumnCount(GetNumCols());
const sal_uInt16 nItemGutterWidth = GetGutterWidth();
sal_Int32 nAutoDistance = IsOrtho() ? USHRT_MAX == nItemGutterWidth
? DEF_GUTTER_WIDTH
: static_cast <sal_Int32>(nItemGutterWidth)
: 0;
nAutoDistance = convertTwipToMm100(nAutoDistance);
xProps->setPropertyValue(UNO_NAME_AUTOMATIC_DISTANCE, uno::Any(nAutoDistance));
if (!IsOrtho())
{
auto aTextColumns = xCols->getColumns();
text::TextColumn* pColumns = aTextColumns.getArray();
const SwColumns& rCols = GetColumns();
for (sal_Int32 i = 0; i < aTextColumns.getLength(); ++i)
{
const SwColumn* pCol = &rCols[i];
pColumns[i].Width = pCol->GetWishWidth();
pColumns[i].LeftMargin = convertTwipToMm100(pCol->GetLeft());
pColumns[i].RightMargin = convertTwipToMm100(pCol->GetRight());
}
xCols->setColumns(aTextColumns); // sets "IsAutomatic" property to false
}
}
uno::Any aVal;
aVal <<= o3tl::narrowing<sal_Int32>(
o3tl::convert(GetLineWidth(), o3tl::Length::twip, o3tl::Length::mm100));
xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_WIDTH, aVal);
aVal <<= GetLineColor();
xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_COLOR, aVal);
aVal <<= static_cast <sal_Int32>(GetLineHeight());
xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_RELATIVE_HEIGHT, aVal);
aVal <<= GetLineAdj() != COLADJ_NONE;
xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_IS_ON, aVal);
sal_Int16 nStyle;
switch (GetLineStyle())
{
case SvxBorderLineStyle::SOLID:
nStyle = css::text::ColumnSeparatorStyle::SOLID;
break ;
case SvxBorderLineStyle::DOTTED:
nStyle = css::text::ColumnSeparatorStyle::DOTTED;
break ;
case SvxBorderLineStyle::DASHED:
nStyle = css::text::ColumnSeparatorStyle::DASHED;
break ;
case SvxBorderLineStyle::NONE:
default :
nStyle = css::text::ColumnSeparatorStyle::NONE;
break ;
}
aVal <<= nStyle;
xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_STYLE, aVal);
style::VerticalAlignment eAlignment;
switch (GetLineAdj())
{
case COLADJ_TOP:
eAlignment = style::VerticalAlignment_TOP;
break ;
case COLADJ_BOTTOM:
eAlignment = style::VerticalAlignment_BOTTOM;
break ;
case COLADJ_CENTER:
case COLADJ_NONE:
default :
eAlignment = style::VerticalAlignment_MIDDLE;
}
aVal <<= eAlignment;
xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_VERTIVAL_ALIGNMENT, aVal);
rVal <<= xCols;
}
return true ;
}
bool SwFormatCol::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
{
// here we convert always!
nMemberId &= ~CONVERT_TWIPS;
bool bRet = false ;
if (MID_COLUMN_SEPARATOR_LINE == nMemberId)
{
OSL_FAIL("not implemented" );
}
else
{
uno::Reference< text::XTextColumns > xCols;
rVal >>= xCols;
if (xCols.is())
{
uno::Sequence<text::TextColumn> aSetColumns = xCols->getColumns();
const text::TextColumn* pArray = aSetColumns.getConstArray();
m_aColumns.clear();
//max count is 64k here - this is something the array can't do
sal_uInt16 nCount = std::min( o3tl::narrowing<sal_uInt16>(aSetColumns.getLength()),
sal_uInt16(0x3fff) );
sal_uInt16 nWidthSum = 0;
// #101224# one column is no column
if (nCount > 1)
for (sal_uInt16 i = 0; i < nCount; i++)
{
SwColumn aCol;
aCol.SetWishWidth(pArray[i].Width );
nWidthSum = nWidthSum + pArray[i].Width;
aCol.SetLeft (o3tl::toTwips(pArray[i].LeftMargin, o3tl::Length::mm100));
aCol.SetRight(o3tl::toTwips(pArray[i].RightMargin, o3tl::Length::mm100));
m_aColumns.insert(m_aColumns.begin() + i, aCol);
}
bRet = true ;
m_nWidth = nWidthSum;
m_bOrtho = false ;
if (uno::Reference<beans::XPropertySet> xProps{ xCols, css::uno::UNO_QUERY })
{
xProps->getPropertyValue(UNO_NAME_IS_AUTOMATIC) >>= m_bOrtho;
xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_WIDTH) >>= m_nLineWidth;
m_nLineWidth = o3tl::toTwips(m_nLineWidth, o3tl::Length::mm100);
xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_COLOR) >>= m_aLineColor;
if (sal_Int32 nHeight;
xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_RELATIVE_HEIGHT) >>= nHeight)
m_nLineHeight = nHeight;
switch (xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_STYLE).get<sal_Int16>())
{
default :
case css::text::ColumnSeparatorStyle::NONE:
m_eLineStyle = SvxBorderLineStyle::NONE;
break ;
case css::text::ColumnSeparatorStyle::SOLID:
m_eLineStyle = SvxBorderLineStyle::SOLID;
break ;
case css::text::ColumnSeparatorStyle::DOTTED:
m_eLineStyle = SvxBorderLineStyle::DOTTED;
break ;
case css::text::ColumnSeparatorStyle::DASHED:
m_eLineStyle = SvxBorderLineStyle::DASHED;
break ;
}
if (!xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_IS_ON).get<bool >())
m_eAdj = COLADJ_NONE;
else switch (xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_VERTIVAL_ALIGNMENT).get<style::VerticalAlignment>())
{
case style::VerticalAlignment_TOP: m_eAdj = COLADJ_TOP; break ;
case style::VerticalAlignment_MIDDLE: m_eAdj = COLADJ_CENTER; break ;
case style::VerticalAlignment_BOTTOM: m_eAdj = COLADJ_BOTTOM; break ;
default : OSL_ENSURE( false , "unknown alignment" ); break ;
}
}
}
}
return bRet;
}
void SwFormatCol::dumpAsXml(xmlTextWriterPtr pWriter) const
{
(void )xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatCol" ));
(void )xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId" ), BAD_CAST(OString::number(Which()).getStr()));
(void )xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eLineStyle" ), BAD_CAST(OString::number(static_cast <sal_Int16>(m_eLineStyle)).getStr()));
(void )xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nLineWidth" ), BAD_CAST(OString::number(m_nLineWidth).getStr()));
(void )xmlTextWriterWriteAttribute(pWriter, BAD_CAST("aLineColor" ), BAD_CAST(m_aLineColor.AsRGBHexString().toUtf8().getStr()));
(void )xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nLineHeight" ), BAD_CAST(OString::number(m_nLineHeight).getStr()));
(void )xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eAdj" ), BAD_CAST(OString::number(m_eAdj).getStr()));
(void )xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nWidth" ), BAD_CAST(OString::number(m_nWidth).getStr()));
(void )xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nWidthAdjustValue" ), BAD_CAST(OString::number(m_aWidthAdjustValue).getStr()));
(void )xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bOrtho" ), BAD_CAST(OString::boolean(m_bOrtho).getStr()));
(void )xmlTextWriterStartElement(pWriter, BAD_CAST("aColumns" ));
for (const SwColumn& rColumn : m_aColumns)
rColumn.dumpAsXml(pWriter);
(void )xmlTextWriterEndElement(pWriter);
(void )xmlTextWriterEndElement(pWriter);
}
// Partially implemented inline in hxx
SwFormatSurround::SwFormatSurround( css::text::WrapTextMode eFly ) :
SfxEnumItem( RES_SURROUND, eFly )
{
m_bAnchorOnly = m_bContour = m_bOutside = false ;
}
bool SwFormatSurround::operator ==( const SfxPoolItem& rAttr ) const
{
assert(SfxPoolItem::operator ==(rAttr));
return ( GetValue() == static_cast <const SwFormatSurround&>(rAttr).GetValue() &&
m_bAnchorOnly== static_cast <const SwFormatSurround&>(rAttr).m_bAnchorOnly &&
m_bContour== static_cast <const SwFormatSurround&>(rAttr).m_bContour &&
m_bOutside== static_cast <const SwFormatSurround&>(rAttr).m_bOutside );
}
SwFormatSurround* SwFormatSurround::Clone( SfxItemPool* ) const
{
return new SwFormatSurround( *this );
}
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 ),
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 ),
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 ),
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 )
, 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)
{
rtl::Reference<SwXTextFrame> const xRet(
SwXTextFrame::CreateXTextFrame(pFormat->GetDoc(), pFormat));
rVal <<= uno::Reference<text::XTextFrame>(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
--> --------------------
--> maximum size reached
--> --------------------
Messung V0.5 C=95 H=99 G=96
¤ Dauer der Verarbeitung: 0.19 Sekunden
¤
*© Formatika GbR, Deutschland