/* -*- 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 <libxml/xmlwriter.h>
#include <hintids.hxx>
#include <svl/itemiter.hxx>
#include <sfx2/app.hxx>
#include <editeng/tstpitem.hxx>
#include <editeng/eeitem.hxx>
#include <editeng/langitem.hxx>
#include <editeng/lrspitem.hxx>
#include <editeng/formatbreakitem.hxx>
#include <editeng/rsiditem.hxx>
#include <editeng/colritem.hxx>
#include <svl/whiter.hxx>
#include <svl/zforlist.hxx>
#include <comphelper/processfactory.hxx>
#include <unotools/configmgr.hxx>
#include <unotools/misccfg.hxx>
#include <sal/log.hxx>
#include <com/sun/star/i18n/WordType.hpp>
#include <com/sun/star/i18n/XBreakIterator.hpp>
#include <fmtpdsc.hxx>
#include <fmthdft.hxx>
#include <fmtcntnt.hxx>
#include <frmatr.hxx>
#include <doc.hxx>
#include <docfunc.hxx>
#include <drawdoc.hxx>
#include <MarkManager.hxx>
#include <IDocumentUndoRedo.hxx>
#include <DocumentContentOperationsManager.hxx>
#include <IDocumentFieldsAccess.hxx>
#include <IDocumentState.hxx>
#include <IDocumentLayoutAccess.hxx>
#include <IDocumentStylePoolAccess.hxx>
#include <rootfrm.hxx>
#include <pagefrm.hxx>
#include <hints.hxx>
#include <ndtxt.hxx>
#include <pam.hxx>
#include <UndoCore.hxx>
#include <UndoAttribute.hxx>
#include <UndoInsert.hxx>
#include <ndgrf.hxx>
#include <pagedesc.hxx>
#include <rolbck.hxx>
#include <mvsave.hxx>
#include <txatbase.hxx>
#include <swtable.hxx>
#include <swtblfmt.hxx>
#include <charfmt.hxx>
#include <docary.hxx>
#include <paratr.hxx>
#include <redline.hxx>
#include <reffld.hxx>
#include <txtinet.hxx>
#include <fmtinfmt.hxx>
#include <breakit.hxx>
#include <SwStyleNameMapper.hxx>
#include <fmtautofmt.hxx>
#include <istyleaccess.hxx>
#include <SwUndoFmt.hxx>
#include <UndoManager.hxx>
#include <docsh.hxx>
#include <swmodule.hxx>
#include <modcfg.hxx>
#include <memory>
using namespace ::com::sun::star::i18n;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::uno;
/*
* Internal functions
*/
static void SetTextFormatCollNext( SwTextFormatColl* pTextColl, const SwTextFormatColl* pDel )
{
if ( &pTextColl->GetNextTextFormatColl() == pDel )
{
pTextColl->SetNextTextFormatColl( *pTextColl );
}
}
static bool lcl_RstAttr( const SwNodePtr& rpNd, void* pArgs )
{
const sw::DocumentContentOperationsManager::ParaRstFormat* pPara = static_cast<sw::DocumentContentOperationsManager::ParaRstFormat*>(pArgs);
SwContentNode* pNode = rpNd->GetContentNode();
if( pNode && pNode->HasSwAttrSet() )
{
const bool bLocked = pNode->IsModifyLocked();
pNode->LockModify();
SwDoc* pDoc = pNode->GetDoc();
// remove unused attribute RES_LR_SPACE
// add list attributes
SfxItemSet aSavedAttrsSet(
pDoc->GetAttrPool(),
svl::Items<
RES_PARATR_NUMRULE, RES_PARATR_NUMRULE,
RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END - 1,
RES_PAGEDESC, RES_BREAK>{});
const SfxItemSet* pAttrSetOfNode = pNode->GetpSwAttrSet();
std::vector<sal_uInt16> aClearWhichIds;
// restoring all paragraph list attributes
{
SfxItemSet aListAttrSet( pDoc->GetAttrPool(), svl::Items<RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END - 1>{} );
aListAttrSet.Set(*pAttrSetOfNode);
if ( aListAttrSet.Count() )
{
aSavedAttrsSet.Put(aListAttrSet);
SfxItemIter aIter( aListAttrSet );
const SfxPoolItem* pItem = aIter.GetCurItem();
while( pItem )
{
aClearWhichIds.push_back( pItem->Which() );
pItem = aIter.NextItem();
}
}
}
const SfxPoolItem* pItem;
sal_uInt16 const aSavIds[3] = { RES_PAGEDESC, RES_BREAK, RES_PARATR_NUMRULE };
for (sal_uInt16 aSavId : aSavIds)
{
if (SfxItemState::SET == pAttrSetOfNode->GetItemState(aSavId, false, &pItem))
{
bool bSave = false;
switch( aSavId )
{
case RES_PAGEDESC:
bSave = nullptr != static_cast<const SwFormatPageDesc*>(pItem)->GetPageDesc();
break;
case RES_BREAK:
bSave = SvxBreak::NONE != static_cast<const SvxFormatBreakItem*>(pItem)->GetBreak();
break;
case RES_PARATR_NUMRULE:
bSave = !static_cast<const SwNumRuleItem*>(pItem)->GetValue().isEmpty();
break;
}
if( bSave )
{
aSavedAttrsSet.Put(*pItem);
aClearWhichIds.push_back(aSavId);
}
}
}
// do not clear items directly from item set and only clear to be kept
// attributes, if no deletion item set is found.
const bool bKeepAttributes =
!pPara || !pPara->pDelSet || pPara->pDelSet->Count() == 0;
if ( bKeepAttributes )
{
pNode->ResetAttr( aClearWhichIds );
}
if( !bLocked )
pNode->UnlockModify();
if( pPara )
{
SwRegHistory aRegH( pNode, *pNode, pPara->pHistory );
if( pPara->pDelSet && pPara->pDelSet->Count() )
{
OSL_ENSURE( !bKeepAttributes,
"<lcl_RstAttr(..)> - certain attributes are kept, but not needed." );
SfxItemIter aIter( *pPara->pDelSet );
pItem = aIter.FirstItem();
while(pItem)
{
if ( ( pItem->Which() != RES_PAGEDESC &&
pItem->Which() != RES_BREAK &&
pItem->Which() != RES_PARATR_NUMRULE ) ||
( aSavedAttrsSet.GetItemState( pItem->Which(), false ) != SfxItemState::SET ) )
{
pNode->ResetAttr( pItem->Which() );
}
if (aIter.IsAtEnd())
break;
pItem = aIter.NextItem();
}
}
else if( pPara->bResetAll )
pNode->ResetAllAttr();
else
pNode->ResetAttr( RES_PARATR_BEGIN, POOLATTR_END - 1 );
}
else
pNode->ResetAllAttr();
// only restore saved attributes, if needed
if (bKeepAttributes && aSavedAttrsSet.Count())
{
pNode->LockModify();
pNode->SetAttr(aSavedAttrsSet);
if( !bLocked )
pNode->UnlockModify();
}
}
return true;
}
void SwDoc::RstTextAttrs(const SwPaM &rRg, bool bInclRefToxMark, bool bExactRange )
{
SwHistory* pHst = nullptr;
SwDataChanged aTmp( rRg );
if (GetIDocumentUndoRedo().DoesUndo())
{
SwUndoResetAttr* pUndo = new SwUndoResetAttr( rRg, RES_CHRFMT );
pHst = &pUndo->GetHistory();
GetIDocumentUndoRedo().AppendUndo(pUndo);
}
const SwPosition *pStt = rRg.Start(), *pEnd = rRg.End();
sw::DocumentContentOperationsManager::ParaRstFormat aPara( pStt, pEnd, pHst );
aPara.bInclRefToxMark = bInclRefToxMark;
aPara.bExactRange = bExactRange;
GetNodes().ForEach( pStt->nNode.GetIndex(), pEnd->nNode.GetIndex()+1,
sw::DocumentContentOperationsManager::lcl_RstTextAttr, &aPara );
getIDocumentState().SetModified();
}
void SwDoc::ResetAttrs( const SwPaM &rRg,
bool bTextAttr,
const std::set<sal_uInt16> &rAttrs,
const bool bSendDataChangedEvents )
{
SwPaM* pPam = const_cast<SwPaM*>(&rRg);
if( !bTextAttr && !rAttrs.empty() && RES_TXTATR_END > *(rAttrs.begin()) )
bTextAttr = true;
if( !rRg.HasMark() )
{
SwTextNode* pTextNd = rRg.GetPoint()->nNode.GetNode().GetTextNode();
if( !pTextNd )
return ;
pPam = new SwPaM( *rRg.GetPoint() );
SwIndex& rSt = pPam->GetPoint()->nContent;
sal_Int32 nMkPos, nPtPos = rSt.GetIndex();
// Special case: if the Cursor is located within a URL attribute, we take over it's area
SwTextAttr const*const pURLAttr(
pTextNd->GetTextAttrAt(rSt.GetIndex(), RES_TXTATR_INETFMT));
if (pURLAttr && !pURLAttr->GetINetFormat().GetValue().isEmpty())
{
nMkPos = pURLAttr->GetStart();
nPtPos = *pURLAttr->End();
}
else
{
assert(g_pBreakIt && g_pBreakIt->GetBreakIter().is());
Boundary aBndry = g_pBreakIt->GetBreakIter()->getWordBoundary(
pTextNd->GetText(), nPtPos,
g_pBreakIt->GetLocale( pTextNd->GetLang( nPtPos ) ),
WordType::ANY_WORD /*ANYWORD_IGNOREWHITESPACES*/,
true);
if( aBndry.startPos < nPtPos && nPtPos < aBndry.endPos )
{
nMkPos = aBndry.startPos;
nPtPos = aBndry.endPos;
}
else
{
nPtPos = nMkPos = rSt.GetIndex();
if( bTextAttr )
pTextNd->DontExpandFormat( rSt );
}
}
rSt = nMkPos;
pPam->SetMark();
pPam->GetPoint()->nContent = nPtPos;
}
// #i96644#
std::unique_ptr< SwDataChanged > xDataChanged;
if ( bSendDataChangedEvents )
{
xDataChanged.reset( new SwDataChanged( *pPam ) );
}
SwHistory* pHst = nullptr;
if (GetIDocumentUndoRedo().DoesUndo())
{
SwUndoResetAttr* pUndo = new SwUndoResetAttr( rRg,
bTextAttr ? sal_uInt16(RES_CONDTXTFMTCOLL) : sal_uInt16(RES_TXTFMTCOLL) );
if( !rAttrs.empty() )
{
pUndo->SetAttrs( rAttrs );
}
pHst = &pUndo->GetHistory();
GetIDocumentUndoRedo().AppendUndo(pUndo);
}
const SwPosition *pStt = pPam->Start(), *pEnd = pPam->End();
sw::DocumentContentOperationsManager::ParaRstFormat aPara( pStt, pEnd, pHst );
// mst: not including META here; it seems attrs with CH_TXTATR are omitted
sal_uInt16 const aResetableSetRange[] {
RES_FRMATR_BEGIN, RES_FRMATR_END-1,
RES_CHRATR_BEGIN, RES_CHRATR_END-1,
RES_PARATR_BEGIN, RES_PARATR_END-1,
RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END-1,
RES_TXTATR_INETFMT, RES_TXTATR_INETFMT,
RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT,
RES_TXTATR_CJK_RUBY, RES_TXTATR_CJK_RUBY,
RES_TXTATR_UNKNOWN_CONTAINER, RES_TXTATR_UNKNOWN_CONTAINER,
RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1,
0
};
SfxItemSet aDelSet( GetAttrPool(), aResetableSetRange );
if( !rAttrs.empty() )
{
for( std::set<sal_uInt16>::const_reverse_iterator it = rAttrs.rbegin(); it != rAttrs.rend(); ++it )
{
if( POOLATTR_END > *it )
aDelSet.Put( *GetDfltAttr( *it ));
}
if( aDelSet.Count() )
aPara.pDelSet = &aDelSet;
}
bool bAdd = true;
SwNodeIndex aTmpStt( pStt->nNode );
SwNodeIndex aTmpEnd( pEnd->nNode );
if( pStt->nContent.GetIndex() ) // just one part
{
// set up a later, and all CharFormatAttr -> TextFormatAttr
SwTextNode* pTNd = aTmpStt.GetNode().GetTextNode();
if( pTNd && pTNd->HasSwAttrSet() && pTNd->GetpSwAttrSet()->Count() )
{
if (pHst)
{
SwRegHistory history(pTNd, *pTNd, pHst);
pTNd->FormatToTextAttr(pTNd);
}
else
{
pTNd->FormatToTextAttr(pTNd);
}
}
++aTmpStt;
}
if( pEnd->nContent.GetIndex() == pEnd->nNode.GetNode().GetContentNode()->Len() )
{
// set up a later, and all CharFormatAttr -> TextFormatAttr
++aTmpEnd;
bAdd = false;
}
else if( pStt->nNode != pEnd->nNode || !pStt->nContent.GetIndex() )
{
SwTextNode* pTNd = aTmpEnd.GetNode().GetTextNode();
if( pTNd && pTNd->HasSwAttrSet() && pTNd->GetpSwAttrSet()->Count() )
{
if (pHst)
{
SwRegHistory history(pTNd, *pTNd, pHst);
pTNd->FormatToTextAttr(pTNd);
}
else
{
pTNd->FormatToTextAttr(pTNd);
}
}
}
if( aTmpStt < aTmpEnd )
GetNodes().ForEach( pStt->nNode, aTmpEnd, lcl_RstAttr, &aPara );
else if( !rRg.HasMark() )
{
aPara.bResetAll = false ;
::lcl_RstAttr( &pStt->nNode.GetNode(), &aPara );
aPara.bResetAll = true ;
}
if( bTextAttr )
{
if( bAdd )
++aTmpEnd;
GetNodes().ForEach( pStt->nNode, aTmpEnd, sw::DocumentContentOperationsManager::lcl_RstTextAttr, &aPara );
}
getIDocumentState().SetModified();
xDataChanged.reset(); //before delete pPam
if( pPam != &rRg )
delete pPam;
}
/// Set the rsid of the next nLen symbols of rRg to the current session number
void SwDoc::UpdateRsid( const SwPaM &rRg, const sal_Int32 nLen )
{
if (!SW_MOD()->GetModuleConfig()->IsStoreRsid())
return;
SwTextNode *pTextNode = rRg.GetPoint()->nNode.GetNode().GetTextNode();
if (!pTextNode)
{
return;
}
const sal_Int32 nStart(rRg.GetPoint()->nContent.GetIndex() - nLen);
SvxRsidItem aRsid( mnRsid, RES_CHRATR_RSID );
SfxItemSet aSet(GetAttrPool(), svl::Items<RES_CHRATR_RSID, RES_CHRATR_RSID>{});
aSet.Put(aRsid);
bool const bRet(pTextNode->SetAttr(aSet, nStart,
rRg.GetPoint()->nContent.GetIndex()));
if (bRet && GetIDocumentUndoRedo().DoesUndo())
{
SwUndo *const pLastUndo = GetUndoManager().GetLastUndo();
SwUndoInsert *const pUndoInsert(dynamic_cast<SwUndoInsert*>(pLastUndo));
// this function is called after Insert so expects to find SwUndoInsert
assert(pUndoInsert);
if (pUndoInsert)
{
pUndoInsert->SetWithRsid();
}
}
}
bool SwDoc::UpdateParRsid( SwTextNode *pTextNode, sal_uInt32 nVal )
{
if (!SW_MOD()->GetModuleConfig()->IsStoreRsid())
return false;
if (!pTextNode)
{
return false;
}
SvxRsidItem aRsid( nVal ? nVal : mnRsid, RES_PARATR_RSID );
return pTextNode->SetAttr( aRsid );
}
/// Set the attribute according to the stated format.
/// If Undo is enabled, the old values is added to the Undo history.
void SwDoc::SetAttr( const SfxPoolItem& rAttr, SwFormat& rFormat )
{
SfxItemSet aSet( GetAttrPool(), {{rAttr.Which(), rAttr.Which()}} );
aSet.Put( rAttr );
SetAttr( aSet, rFormat );
}
/// Set the attribute according to the stated format.
/// If Undo is enabled, the old values is added to the Undo history.
void SwDoc::SetAttr( const SfxItemSet& rSet, SwFormat& rFormat )
{
if (GetIDocumentUndoRedo().DoesUndo())
{
SwUndoFormatAttrHelper aTmp( rFormat );
rFormat.SetFormatAttr( rSet );
if ( aTmp.GetUndo() )
{
GetIDocumentUndoRedo().AppendUndo( aTmp.ReleaseUndo() );
}
else
{
GetIDocumentUndoRedo().ClearRedo();
}
}
else
{
rFormat.SetFormatAttr( rSet );
}
getIDocumentState().SetModified();
}
void SwDoc::ResetAttrAtFormat( const sal_uInt16 nWhichId,
SwFormat& rChangedFormat )
{
SwUndo *const pUndo = (GetIDocumentUndoRedo().DoesUndo())
? new SwUndoFormatResetAttr( rChangedFormat, nWhichId )
: nullptr;
const bool bAttrReset = rChangedFormat.ResetFormatAttr( nWhichId );
if ( bAttrReset )
{
if ( pUndo )
{
GetIDocumentUndoRedo().AppendUndo( pUndo );
}
getIDocumentState().SetModified();
}
else
delete pUndo;
}
static bool lcl_SetNewDefTabStops( SwTwips nOldWidth, SwTwips nNewWidth,
SvxTabStopItem& rChgTabStop )
{
// Set the default values of all TabStops to the new value.
// Attention: we always work with the PoolAttribute here, so that
// we don't calculate the same value on the same TabStop (pooled!) for all sets.
// We send a FormatChg to modify.
sal_uInt16 nOldCnt = rChgTabStop.Count();
if( !nOldCnt || nOldWidth == nNewWidth )
return false;
// Find the default's beginning
sal_uInt16 n;
for( n = nOldCnt; n ; --n )
if( SvxTabAdjust::Default != rChgTabStop[n - 1].GetAdjustment() )
break;
++n;
if( n < nOldCnt ) // delete the DefTabStops
rChgTabStop.Remove( n, nOldCnt - n );
return true;
}
/// Set the attribute as new default attribute in this document.
/// If Undo is enabled, the old value is added to the Undo history.
void SwDoc::SetDefault( const SfxPoolItem& rAttr )
{
SfxItemSet aSet( GetAttrPool(), {{rAttr.Which(), rAttr.Which()}} );
aSet.Put( rAttr );
SetDefault( aSet );
}
void SwDoc::SetDefault( const SfxItemSet& rSet )
{
if( !rSet.Count() )
return;
SwModify aCallMod( nullptr );
SwAttrSet aOld( GetAttrPool(), rSet.GetRanges() ),
aNew( GetAttrPool(), rSet.GetRanges() );
SfxItemIter aIter( rSet );
const SfxPoolItem* pItem = aIter.GetCurItem();
SfxItemPool* pSdrPool = GetAttrPool().GetSecondaryPool();
while( true )
{
bool bCheckSdrDflt = false;
const sal_uInt16 nWhich = pItem->Which();
aOld.Put( GetAttrPool().GetDefaultItem( nWhich ) );
GetAttrPool().SetPoolDefaultItem( *pItem );
aNew.Put( GetAttrPool().GetDefaultItem( nWhich ) );
if (isCHRATR(nWhich) || isTXTATR(nWhich))
{
aCallMod.Add( mpDfltTextFormatColl.get() );
aCallMod.Add( mpDfltCharFormat.get() );
bCheckSdrDflt = nullptr != pSdrPool;
}
else if ( isPARATR(nWhich) ||
isPARATR_LIST(nWhich) )
{
aCallMod.Add( mpDfltTextFormatColl.get() );
bCheckSdrDflt = nullptr != pSdrPool;
}
else if (isGRFATR(nWhich))
{
aCallMod.Add( mpDfltGrfFormatColl.get() );
}
else if (isFRMATR(nWhich) || isDrawingLayerAttribute(nWhich) )
{
aCallMod.Add( mpDfltGrfFormatColl.get() );
aCallMod.Add( mpDfltTextFormatColl.get() );
aCallMod.Add( mpDfltFrameFormat.get() );
}
else if (isBOXATR(nWhich))
{
aCallMod.Add( mpDfltFrameFormat.get() );
}
// also copy the defaults
if( bCheckSdrDflt )
{
sal_uInt16 nEdtWhich, nSlotId;
if( 0 != (nSlotId = GetAttrPool().GetSlotId( nWhich ) ) &&
nSlotId != nWhich &&
0 != (nEdtWhich = pSdrPool->GetWhich( nSlotId )) &&
nSlotId != nEdtWhich )
{
SfxPoolItem* pCpy = pItem->Clone();
pCpy->SetWhich( nEdtWhich );
pSdrPool->SetPoolDefaultItem( *pCpy );
delete pCpy;
}
}
if( aIter.IsAtEnd() )
break;
pItem = aIter.NextItem();
}
if( aNew.Count() && aCallMod.HasWriterListeners() )
{
if (GetIDocumentUndoRedo().DoesUndo())
{
GetIDocumentUndoRedo().AppendUndo( new SwUndoDefaultAttr( aOld, this ) );
}
const SfxPoolItem* pTmpItem;
if( ( SfxItemState::SET ==
aNew.GetItemState( RES_PARATR_TABSTOP, false, &pTmpItem ) ) &&
static_cast<const SvxTabStopItem*>(pTmpItem)->Count() )
{
// Set the default values of all TabStops to the new value.
// Attention: we always work with the PoolAttribute here, so that
// we don't calculate the same value on the same TabStop (pooled!) for all sets.
// We send a FormatChg to modify.
SwTwips nNewWidth = (*static_cast<const SvxTabStopItem*>(pTmpItem))[ 0 ].GetTabPos(),
nOldWidth = aOld.Get(RES_PARATR_TABSTOP)[ 0 ].GetTabPos();
bool bChg = false;
sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2( RES_PARATR_TABSTOP );
for( sal_uInt32 n = 0; n < nMaxItems; ++n )
if( nullptr != (pTmpItem = GetAttrPool().GetItem2( RES_PARATR_TABSTOP, n ) ))
bChg |= lcl_SetNewDefTabStops( nOldWidth, nNewWidth,
*const_cast<SvxTabStopItem*>(static_cast<const SvxTabStopItem*>(pTmpItem)) );
aNew.ClearItem( RES_PARATR_TABSTOP );
aOld.ClearItem( RES_PARATR_TABSTOP );
if( bChg )
{
SwFormatChg aChgFormat( mpDfltCharFormat.get() );
// notify the frames
aCallMod.ModifyNotification( &aChgFormat, &aChgFormat );
}
}
}
if( aNew.Count() && aCallMod.HasWriterListeners() )
{
SwAttrSetChg aChgOld( aOld, aOld );
SwAttrSetChg aChgNew( aNew, aNew );
aCallMod.ModifyNotification( &aChgOld, &aChgNew ); // all changed are sent
}
// remove the default formats from the object again
SwIterator<SwClient, SwModify> aClientIter(aCallMod);
for(SwClient* pClient = aClientIter.First(); pClient; pClient = aClientIter.Next())
aCallMod.Remove( pClient );
getIDocumentState().SetModified();
}
/// Get the default attribute in this document
const SfxPoolItem& SwDoc::GetDefault( sal_uInt16 nFormatHint ) const
{
return GetAttrPool().GetDefaultItem( nFormatHint );
}
/// Delete the formats
void SwDoc::DelCharFormat(size_t nFormat, bool bBroadcast)
{
SwCharFormat * pDel = (*mpCharFormatTable)[nFormat];
if (bBroadcast)
BroadcastStyleOperation(pDel->GetName(), SfxStyleFamily::Char,
SfxHintId::StyleSheetErased);
if (GetIDocumentUndoRedo().DoesUndo())
{
SwUndo * pUndo =
new SwUndoCharFormatDelete(pDel, this);
GetIDocumentUndoRedo().AppendUndo(pUndo);
}
delete (*mpCharFormatTable)[nFormat];
mpCharFormatTable->erase(mpCharFormatTable->begin() + nFormat);
getIDocumentState().SetModified();
}
void SwDoc::DelCharFormat( SwCharFormat const *pFormat, bool bBroadcast )
{
size_t nFormat = mpCharFormatTable->GetPos( pFormat );
OSL_ENSURE( SIZE_MAX != nFormat, "Format not found," );
DelCharFormat( nFormat, bBroadcast );
}
void SwDoc::DelFrameFormat( SwFrameFormat *pFormat, bool bBroadcast )
{
if( dynamic_cast<const SwTableBoxFormat*>( pFormat) != nullptr || dynamic_cast<const SwTableLineFormat*>( pFormat) != nullptr )
{
OSL_ENSURE( false, "Format is not in the DocArray any more, "
"so it can be deleted with delete" );
delete pFormat;
}
else
{
// The format has to be in the one or the other, we'll see in which one.
if (mpFrameFormatTable->ContainsFormat(*pFormat))
{
if (bBroadcast)
BroadcastStyleOperation(pFormat->GetName(),
SfxStyleFamily::Frame,
SfxHintId::StyleSheetErased);
if (GetIDocumentUndoRedo().DoesUndo())
{
SwUndo * pUndo = new SwUndoFrameFormatDelete(pFormat, this);
GetIDocumentUndoRedo().AppendUndo(pUndo);
}
mpFrameFormatTable->erase( pFormat );
delete pFormat;
}
else
{
bool contains = GetSpzFrameFormats()->ContainsFormat(*pFormat);
OSL_ENSURE( contains, "FrameFormat not found." );
if( contains )
{
GetSpzFrameFormats()->erase( pFormat );
delete pFormat;
}
}
}
}
void SwDoc::DelTableFrameFormat( SwTableFormat *pFormat )
{
SwFrameFormats::const_iterator it = mpTableFrameFormatTable->find( pFormat );
OSL_ENSURE( it != mpTableFrameFormatTable->end(), "Format not found," );
mpTableFrameFormatTable->erase( it );
delete pFormat;
}
/// Create the formats
SwFlyFrameFormat *SwDoc::MakeFlyFrameFormat( const OUString &rFormatName,
SwFrameFormat *pDerivedFrom )
{
SwFlyFrameFormat *pFormat = new SwFlyFrameFormat( GetAttrPool(), rFormatName, pDerivedFrom );
GetSpzFrameFormats()->push_back(pFormat);
getIDocumentState().SetModified();
return pFormat;
}
SwDrawFrameFormat *SwDoc::MakeDrawFrameFormat( const OUString &rFormatName,
SwFrameFormat *pDerivedFrom )
{
SwDrawFrameFormat *pFormat = new SwDrawFrameFormat( GetAttrPool(), rFormatName, pDerivedFrom);
GetSpzFrameFormats()->push_back(pFormat);
getIDocumentState().SetModified();
return pFormat;
}
size_t SwDoc::GetTableFrameFormatCount(bool bUsed) const
{
if (!bUsed)
{
return mpTableFrameFormatTable->size();
}
SwAutoFormatGetDocNode aGetHt(&GetNodes());
size_t nCount = 0;
for (SwFrameFormat* const & pFormat : *mpTableFrameFormatTable)
{
if (!pFormat->GetInfo(aGetHt))
nCount++;
}
return nCount;
}
SwFrameFormat& SwDoc::GetTableFrameFormat(size_t nFormat, bool bUsed) const
{
if (!bUsed)
{
return *((*mpTableFrameFormatTable)[nFormat]);
}
SwAutoFormatGetDocNode aGetHt(&GetNodes());
size_t index = 0;
for (SwFrameFormat* const & pFormat : *mpTableFrameFormatTable)
{
if (!pFormat->GetInfo(aGetHt))
{
if (index == nFormat)
return *pFormat;
else
index++;
}
}
throw std::out_of_range("Format index out of range.");
}
SwTableFormat* SwDoc::MakeTableFrameFormat( const OUString &rFormatName,
SwFrameFormat *pDerivedFrom )
{
SwTableFormat* pFormat = new SwTableFormat( GetAttrPool(), rFormatName, pDerivedFrom );
mpTableFrameFormatTable->push_back( pFormat );
getIDocumentState().SetModified();
return pFormat;
}
SwFrameFormat *SwDoc::MakeFrameFormat(const OUString &rFormatName,
SwFrameFormat *pDerivedFrom,
bool bBroadcast, bool bAuto)
{
SwFrameFormat *pFormat = new SwFrameFormat( GetAttrPool(), rFormatName, pDerivedFrom );
pFormat->SetAuto(bAuto);
mpFrameFormatTable->push_back( pFormat );
getIDocumentState().SetModified();
if (GetIDocumentUndoRedo().DoesUndo())
{
SwUndo * pUndo = new SwUndoFrameFormatCreate(pFormat, pDerivedFrom, this);
GetIDocumentUndoRedo().AppendUndo(pUndo);
}
if (bBroadcast)
{
BroadcastStyleOperation(rFormatName, SfxStyleFamily::Frame,
SfxHintId::StyleSheetCreated);
}
return pFormat;
}
SwFormat *SwDoc::MakeFrameFormat_(const OUString &rFormatName,
SwFormat *pDerivedFrom,
bool bBroadcast, bool bAuto)
{
SwFrameFormat *pFrameFormat = dynamic_cast<SwFrameFormat*>(pDerivedFrom);
pFrameFormat = MakeFrameFormat( rFormatName, pFrameFormat, bBroadcast, bAuto );
return dynamic_cast<SwFormat*>(pFrameFormat);
}
SwCharFormat *SwDoc::MakeCharFormat( const OUString &rFormatName,
SwCharFormat *pDerivedFrom,
bool bBroadcast )
{
SwCharFormat *pFormat = new SwCharFormat( GetAttrPool(), rFormatName, pDerivedFrom );
mpCharFormatTable->push_back( pFormat );
pFormat->SetAuto(false);
getIDocumentState().SetModified();
if (GetIDocumentUndoRedo().DoesUndo())
{
SwUndo * pUndo = new SwUndoCharFormatCreate(pFormat, pDerivedFrom, this);
GetIDocumentUndoRedo().AppendUndo(pUndo);
}
if (bBroadcast)
{
BroadcastStyleOperation(rFormatName, SfxStyleFamily::Char,
SfxHintId::StyleSheetCreated);
}
return pFormat;
}
SwFormat *SwDoc::MakeCharFormat_(const OUString &rFormatName,
SwFormat *pDerivedFrom,
bool bBroadcast, bool /*bAuto*/)
{
SwCharFormat *pCharFormat = dynamic_cast<SwCharFormat*>(pDerivedFrom);
pCharFormat = MakeCharFormat( rFormatName, pCharFormat, bBroadcast );
return dynamic_cast<SwFormat*>(pCharFormat);
}
/// Create the FormatCollections
SwTextFormatColl* SwDoc::MakeTextFormatColl( const OUString &rFormatName,
SwTextFormatColl *pDerivedFrom,
bool bBroadcast)
{
SwTextFormatColl *pFormatColl = new SwTextFormatColl( GetAttrPool(), rFormatName,
pDerivedFrom );
mpTextFormatCollTable->push_back(pFormatColl);
pFormatColl->SetAuto(false);
getIDocumentState().SetModified();
if (GetIDocumentUndoRedo().DoesUndo())
{
SwUndo * pUndo = new SwUndoTextFormatCollCreate(pFormatColl, pDerivedFrom,
this);
GetIDocumentUndoRedo().AppendUndo(pUndo);
}
if (bBroadcast)
BroadcastStyleOperation(rFormatName, SfxStyleFamily::Para,
SfxHintId::StyleSheetCreated);
return pFormatColl;
}
SwFormat *SwDoc::MakeTextFormatColl_(const OUString &rFormatName,
SwFormat *pDerivedFrom,
bool bBroadcast, bool /*bAuto*/)
{
SwTextFormatColl *pTextFormatColl = dynamic_cast<SwTextFormatColl*>(pDerivedFrom);
pTextFormatColl = MakeTextFormatColl( rFormatName, pTextFormatColl, bBroadcast );
return dynamic_cast<SwFormat*>(pTextFormatColl);
}
//FEATURE::CONDCOLL
SwConditionTextFormatColl* SwDoc::MakeCondTextFormatColl( const OUString &rFormatName,
SwTextFormatColl *pDerivedFrom,
bool bBroadcast)
{
SwConditionTextFormatColl*pFormatColl = new SwConditionTextFormatColl( GetAttrPool(),
rFormatName, pDerivedFrom );
mpTextFormatCollTable->push_back(pFormatColl);
pFormatColl->SetAuto(false);
getIDocumentState().SetModified();
if (GetIDocumentUndoRedo().DoesUndo())
{
SwUndo * pUndo = new SwUndoCondTextFormatCollCreate(pFormatColl, pDerivedFrom,
this);
GetIDocumentUndoRedo().AppendUndo(pUndo);
}
if (bBroadcast)
BroadcastStyleOperation(rFormatName, SfxStyleFamily::Para,
SfxHintId::StyleSheetCreated);
return pFormatColl;
}
//FEATURE::CONDCOLL
// GRF
SwGrfFormatColl* SwDoc::MakeGrfFormatColl( const OUString &rFormatName,
SwGrfFormatColl *pDerivedFrom )
{
SwGrfFormatColl *pFormatColl = new SwGrfFormatColl( GetAttrPool(), rFormatName,
pDerivedFrom );
mpGrfFormatCollTable->push_back( pFormatColl );
pFormatColl->SetAuto(false);
getIDocumentState().SetModified();
return pFormatColl;
}
void SwDoc::DelTextFormatColl(size_t nFormatColl, bool bBroadcast)
{
OSL_ENSURE( nFormatColl, "Remove of Coll 0." );
// Who has the to-be-deleted as their Next?
SwTextFormatColl *pDel = (*mpTextFormatCollTable)[nFormatColl];
if( mpDfltTextFormatColl.get() == pDel )
return; // never delete default!
if (bBroadcast)
BroadcastStyleOperation(pDel->GetName(), SfxStyleFamily::Para,
SfxHintId::StyleSheetErased);
if (GetIDocumentUndoRedo().DoesUndo())
{
SwUndoTextFormatCollDelete * pUndo;
if (RES_CONDTXTFMTCOLL == pDel->Which())
{
pUndo = new SwUndoCondTextFormatCollDelete(pDel, this);
}
else
{
pUndo = new SwUndoTextFormatCollDelete(pDel, this);
}
GetIDocumentUndoRedo().AppendUndo(pUndo);
}
// Remove the FormatColl
mpTextFormatCollTable->erase(mpTextFormatCollTable->begin() + nFormatColl);
// Correct next
for( SwTextFormatColls::const_iterator it = mpTextFormatCollTable->begin() + 1; it != mpTextFormatCollTable->end(); ++it )
SetTextFormatCollNext( *it, pDel );
delete pDel;
getIDocumentState().SetModified();
}
void SwDoc::DelTextFormatColl( SwTextFormatColl const *pColl, bool bBroadcast )
{
size_t nFormat = mpTextFormatCollTable->GetPos( pColl );
OSL_ENSURE( SIZE_MAX != nFormat, "Collection not found," );
DelTextFormatColl( nFormat, bBroadcast );
}
static bool lcl_SetTextFormatColl( const SwNodePtr& rpNode, void* pArgs )
{
SwContentNode* pCNd = static_cast<SwContentNode*>(rpNode->GetTextNode());
if( pCNd == nullptr)
return true;
sw::DocumentContentOperationsManager::ParaRstFormat* pPara = static_cast<sw::DocumentContentOperationsManager::ParaRstFormat*>(pArgs);
SwTextFormatColl* pFormat = static_cast<SwTextFormatColl*>(pPara->pFormatColl);
if ( pPara->bReset )
{
lcl_RstAttr(pCNd, pPara);
// #i62675# check, if paragraph style has changed
if ( pPara->bResetListAttrs &&
pFormat != pCNd->GetFormatColl() &&
pFormat->GetItemState( RES_PARATR_NUMRULE ) == SfxItemState::SET )
{
// Check, if the list style of the paragraph will change.
bool bChangeOfListStyleAtParagraph( true );
SwTextNode& rTNd(dynamic_cast<SwTextNode&>(*pCNd));
{
SwNumRule* pNumRuleAtParagraph(rTNd.GetNumRule());
if ( pNumRuleAtParagraph )
{
const SwNumRuleItem& rNumRuleItemAtParagraphStyle =
pFormat->GetNumRule();
if ( rNumRuleItemAtParagraphStyle.GetValue() ==
pNumRuleAtParagraph->GetName() )
{
bChangeOfListStyleAtParagraph = false;
}
}
}
if ( bChangeOfListStyleAtParagraph )
{
std::unique_ptr< SwRegHistory > pRegH;
if ( pPara->pHistory )
{
pRegH.reset(new SwRegHistory(&rTNd, rTNd, pPara->pHistory));
}
pCNd->ResetAttr( RES_PARATR_NUMRULE );
// reset all list attributes
pCNd->ResetAttr( RES_PARATR_LIST_LEVEL );
pCNd->ResetAttr( RES_PARATR_LIST_ISRESTART );
pCNd->ResetAttr( RES_PARATR_LIST_RESTARTVALUE );
pCNd->ResetAttr( RES_PARATR_LIST_ISCOUNTED );
pCNd->ResetAttr( RES_PARATR_LIST_ID );
}
}
}
// add to History so that old data is saved, if necessary
if( pPara->pHistory )
pPara->pHistory->Add( pCNd->GetFormatColl(), pCNd->GetIndex(),
SwNodeType::Text );
pCNd->ChgFormatColl( pFormat );
pPara->nWhich++;
return true;
}
bool SwDoc::SetTextFormatColl(const SwPaM &rRg,
SwTextFormatColl *pFormat,
const bool bReset,
const bool bResetListAttrs)
{
SwDataChanged aTmp( rRg );
const SwPosition *pStt = rRg.Start(), *pEnd = rRg.End();
SwHistory* pHst = nullptr;
bool bRet = true;
if (GetIDocumentUndoRedo().DoesUndo())
{
SwUndoFormatColl* pUndo = new SwUndoFormatColl( rRg, pFormat,
bReset,
bResetListAttrs );
pHst = pUndo->GetHistory();
GetIDocumentUndoRedo().AppendUndo(pUndo);
}
sw::DocumentContentOperationsManager::ParaRstFormat aPara( pStt, pEnd, pHst );
aPara.pFormatColl = pFormat;
aPara.bReset = bReset;
// #i62675#
aPara.bResetListAttrs = bResetListAttrs;
GetNodes().ForEach( pStt->nNode.GetIndex(), pEnd->nNode.GetIndex()+1,
lcl_SetTextFormatColl, &aPara );
if( !aPara.nWhich )
bRet = false; // didn't find a valid Node
if (bRet)
{
getIDocumentState().SetModified();
}
return bRet;
}
/// Copy the formats to itself
SwFormat* SwDoc::CopyFormat( const SwFormat& rFormat,
const SwFormatsBase& rFormatArr,
FNCopyFormat fnCopyFormat, const SwFormat& rDfltFormat )
{
// It's no autoformat, default format or collection format,
// then search for it.
if( !rFormat.IsAuto() || !rFormat.GetRegisteredIn() )
for( size_t n = 0; n < rFormatArr.GetFormatCount(); ++n )
{
// Does the Doc already contain the template?
if( rFormatArr.GetFormat(n)->GetName()==rFormat.GetName() )
return rFormatArr.GetFormat(n);
}
// Search for the "parent" first
SwFormat* pParent = const_cast<SwFormat*>(&rDfltFormat);
if( rFormat.DerivedFrom() && pParent != rFormat.DerivedFrom() )
pParent = CopyFormat( *rFormat.DerivedFrom(), rFormatArr,
fnCopyFormat, rDfltFormat );
// Create the format and copy the attributes
// #i40550#
SwFormat* pNewFormat = (this->*fnCopyFormat)( rFormat.GetName(), pParent, false, true );
pNewFormat->SetAuto( rFormat.IsAuto() );
pNewFormat->CopyAttrs( rFormat ); // copy the attributes
pNewFormat->SetPoolFormatId( rFormat.GetPoolFormatId() );
pNewFormat->SetPoolHelpId( rFormat.GetPoolHelpId() );
// Always set the HelpFile Id to default!
pNewFormat->SetPoolHlpFileId( UCHAR_MAX );
return pNewFormat;
}
/// copy the frame format
SwFrameFormat* SwDoc::CopyFrameFormat( const SwFrameFormat& rFormat )
{
return static_cast<SwFrameFormat*>(CopyFormat( rFormat, *GetFrameFormats(), &SwDoc::MakeFrameFormat_,
*GetDfltFrameFormat() ));
}
/// copy the char format
SwCharFormat* SwDoc::CopyCharFormat( const SwCharFormat& rFormat )
{
return static_cast<SwCharFormat*>(CopyFormat( rFormat, *GetCharFormats(),
&SwDoc::MakeCharFormat_,
*GetDfltCharFormat() ));
}
/// copy TextNodes
SwTextFormatColl* SwDoc::CopyTextColl( const SwTextFormatColl& rColl )
{
SwTextFormatColl* pNewColl = FindTextFormatCollByName( rColl.GetName() );
if( pNewColl )
return pNewColl;
// search for the "parent" first
SwTextFormatColl* pParent = mpDfltTextFormatColl.get();
if( pParent != rColl.DerivedFrom() )
pParent = CopyTextColl( *static_cast<SwTextFormatColl*>(rColl.DerivedFrom()) );
//FEATURE::CONDCOLL
if( RES_CONDTXTFMTCOLL == rColl.Which() )
{
pNewColl = new SwConditionTextFormatColl( GetAttrPool(), rColl.GetName(),
pParent);
mpTextFormatCollTable->push_back( pNewColl );
pNewColl->SetAuto(false);
getIDocumentState().SetModified();
// copy the conditions
static_cast<SwConditionTextFormatColl*>(pNewColl)->SetConditions(
static_cast<const SwConditionTextFormatColl&>(rColl).GetCondColls() );
}
else
//FEATURE::CONDCOLL
pNewColl = MakeTextFormatColl( rColl.GetName(), pParent );
// copy the auto formats or the attributes
pNewColl->CopyAttrs( rColl );
if(rColl.IsAssignedToListLevelOfOutlineStyle())
pNewColl->AssignToListLevelOfOutlineStyle(rColl.GetAssignedOutlineStyleLevel());
pNewColl->SetPoolFormatId( rColl.GetPoolFormatId() );
pNewColl->SetPoolHelpId( rColl.GetPoolHelpId() );
// Always set the HelpFile Id to default!
pNewColl->SetPoolHlpFileId( UCHAR_MAX );
if( &rColl.GetNextTextFormatColl() != &rColl )
pNewColl->SetNextTextFormatColl( *CopyTextColl( rColl.GetNextTextFormatColl() ));
// create the NumRule if necessary
if( this != rColl.GetDoc() )
{
const SfxPoolItem* pItem;
if( SfxItemState::SET == pNewColl->GetItemState( RES_PARATR_NUMRULE,
false, &pItem ))
{
const SwNumRule* pRule;
const OUString& rName = static_cast<const SwNumRuleItem*>(pItem)->GetValue();
if( !rName.isEmpty() &&
nullptr != ( pRule = rColl.GetDoc()->FindNumRulePtr( rName )) &&
!pRule->IsAutoRule() )
{
SwNumRule* pDestRule = FindNumRulePtr( rName );
if( pDestRule )
pDestRule->SetInvalidRule( true );
else
MakeNumRule( rName, pRule );
}
}
}
return pNewColl;
}
/// copy the graphic nodes
SwGrfFormatColl* SwDoc::CopyGrfColl( const SwGrfFormatColl& rColl )
{
SwGrfFormatColl* pNewColl = static_cast<SwGrfFormatColl*>(FindFormatByName( static_cast<SwFormatsBase const &>(*mpGrfFormatCollTable), rColl.GetName() ));
if( pNewColl )
return pNewColl;
// Search for the "parent" first
SwGrfFormatColl* pParent = mpDfltGrfFormatColl.get();
if( pParent != rColl.DerivedFrom() )
pParent = CopyGrfColl( *static_cast<SwGrfFormatColl*>(rColl.DerivedFrom()) );
// if not, copy them
pNewColl = MakeGrfFormatColl( rColl.GetName(), pParent );
// copy the attributes
pNewColl->CopyAttrs( rColl );
pNewColl->SetPoolFormatId( rColl.GetPoolFormatId() );
pNewColl->SetPoolHelpId( rColl.GetPoolHelpId() );
// Always set the HelpFile Id to default!
pNewColl->SetPoolHlpFileId( UCHAR_MAX );
return pNewColl;
}
void SwDoc::CopyFormatArr( const SwFormatsBase& rSourceArr,
SwFormatsBase const & rDestArr,
FNCopyFormat fnCopyFormat,
SwFormat& rDfltFormat )
{
SwFormat* pSrc, *pDest;
// 1st step: Create all formats (skip the 0th - it's the default one)
for( size_t nSrc = rSourceArr.GetFormatCount(); nSrc > 1; )
{
pSrc = rSourceArr.GetFormat( --nSrc );
if( pSrc->IsDefault() || pSrc->IsAuto() )
continue;
if( nullptr == FindFormatByName( rDestArr, pSrc->GetName() ) )
{
if( RES_CONDTXTFMTCOLL == pSrc->Which() )
MakeCondTextFormatColl( pSrc->GetName(), static_cast<SwTextFormatColl*>(&rDfltFormat) );
else
// #i40550#
(this->*fnCopyFormat)( pSrc->GetName(), &rDfltFormat, false, true );
}
}
// 2nd step: Copy all attributes, set the right parents
for( size_t nSrc = rSourceArr.GetFormatCount(); nSrc > 1; )
{
pSrc = rSourceArr.GetFormat( --nSrc );
if( pSrc->IsDefault() || pSrc->IsAuto() )
continue;
pDest = FindFormatByName( rDestArr, pSrc->GetName() );
pDest->SetAuto(false);
pDest->DelDiffs( *pSrc );
// #i94285#: existing <SwFormatPageDesc> instance, before copying attributes
const SfxPoolItem* pItem;
if( &GetAttrPool() != pSrc->GetAttrSet().GetPool() &&
SfxItemState::SET == pSrc->GetAttrSet().GetItemState(
RES_PAGEDESC, false, &pItem ) &&
static_cast<const SwFormatPageDesc*>(pItem)->GetPageDesc() )
{
SwFormatPageDesc aPageDesc( *static_cast<const SwFormatPageDesc*>(pItem) );
const OUString& rNm = aPageDesc.GetPageDesc()->GetName();
SwPageDesc* pPageDesc = FindPageDesc( rNm );
if( !pPageDesc )
{
pPageDesc = MakePageDesc(rNm);
}
aPageDesc.RegisterToPageDesc( *pPageDesc );
SwAttrSet aTmpAttrSet( pSrc->GetAttrSet() );
aTmpAttrSet.Put( aPageDesc );
pDest->SetFormatAttr( aTmpAttrSet );
}
else
{
pDest->SetFormatAttr( pSrc->GetAttrSet() );
}
pDest->SetPoolFormatId( pSrc->GetPoolFormatId() );
pDest->SetPoolHelpId( pSrc->GetPoolHelpId() );
// Always set the HelpFile Id to default!
pDest->SetPoolHlpFileId( UCHAR_MAX );
if( pSrc->DerivedFrom() )
pDest->SetDerivedFrom( FindFormatByName( rDestArr,
pSrc->DerivedFrom()->GetName() ) );
if( RES_TXTFMTCOLL == pSrc->Which() ||
RES_CONDTXTFMTCOLL == pSrc->Which() )
{
SwTextFormatColl* pSrcColl = static_cast<SwTextFormatColl*>(pSrc),
* pDstColl = static_cast<SwTextFormatColl*>(pDest);
if( &pSrcColl->GetNextTextFormatColl() != pSrcColl )
pDstColl->SetNextTextFormatColl( *static_cast<SwTextFormatColl*>(FindFormatByName(
rDestArr, pSrcColl->GetNextTextFormatColl().GetName() ) ) );
if(pSrcColl->IsAssignedToListLevelOfOutlineStyle())
pDstColl->AssignToListLevelOfOutlineStyle(pSrcColl->GetAssignedOutlineStyleLevel());
//FEATURE::CONDCOLL
if( RES_CONDTXTFMTCOLL == pSrc->Which() )
// Copy the conditions, but delete the old ones first!
static_cast<SwConditionTextFormatColl*>(pDstColl)->SetConditions(
static_cast<SwConditionTextFormatColl*>(pSrc)->GetCondColls() );
//FEATURE::CONDCOLL
}
}
}
void SwDoc::CopyPageDescHeaderFooterImpl( bool bCpyHeader,
const SwFrameFormat& rSrcFormat, SwFrameFormat& rDestFormat )
{
// Treat the header and footer attributes in the right way:
// Copy content nodes across documents!
sal_uInt16 nAttr = bCpyHeader ? sal_uInt16(RES_HEADER) : sal_uInt16(RES_FOOTER);
const SfxPoolItem* pItem;
if( SfxItemState::SET != rSrcFormat.GetAttrSet().GetItemState( nAttr, false, &pItem ))
return ;
// The header only contains the reference to the format from the other document!
SfxPoolItem* pNewItem = pItem->Clone();
SwFrameFormat* pOldFormat;
if( bCpyHeader )
pOldFormat = static_cast<SwFormatHeader*>(pNewItem)->GetHeaderFormat();
else
pOldFormat = static_cast<SwFormatFooter*>(pNewItem)->GetFooterFormat();
if( pOldFormat )
{
SwFrameFormat* pNewFormat = new SwFrameFormat( GetAttrPool(), "CpyDesc",
GetDfltFrameFormat() );
pNewFormat->CopyAttrs( *pOldFormat );
if( SfxItemState::SET == pNewFormat->GetAttrSet().GetItemState(
RES_CNTNT, false, &pItem ))
{
const SwFormatContent* pContent = static_cast<const SwFormatContent*>(pItem);
if( pContent->GetContentIdx() )
{
SwNodeIndex aTmpIdx( GetNodes().GetEndOfAutotext() );
const SwNodes& rSrcNds = rSrcFormat.GetDoc()->GetNodes();
SwStartNode* pSttNd = SwNodes::MakeEmptySection( aTmpIdx,
bCpyHeader
? SwHeaderStartNode
: SwFooterStartNode );
const SwNode& rCSttNd = pContent->GetContentIdx()->GetNode();
SwNodeRange aRg( rCSttNd, 0, *rCSttNd.EndOfSectionNode() );
aTmpIdx = *pSttNd->EndOfSectionNode();
rSrcNds.Copy_( aRg, aTmpIdx );
aTmpIdx = *pSttNd;
rSrcFormat.GetDoc()->GetDocumentContentOperationsManager().CopyFlyInFlyImpl( aRg, 0, aTmpIdx );
pNewFormat->SetFormatAttr( SwFormatContent( pSttNd ));
}
else
pNewFormat->ResetFormatAttr( RES_CNTNT );
}
if( bCpyHeader )
static_cast<SwFormatHeader*>(pNewItem)->RegisterToFormat(*pNewFormat);
else
static_cast<SwFormatFooter*>(pNewItem)->RegisterToFormat(*pNewFormat);
rDestFormat.SetFormatAttr( *pNewItem );
}
delete pNewItem;
}
void SwDoc::CopyPageDesc( const SwPageDesc& rSrcDesc, SwPageDesc& rDstDesc,
bool bCopyPoolIds )
{
bool bNotifyLayout = false;
SwRootFrame* pTmpRoot = getIDocumentLayoutAccess().GetCurrentLayout();
rDstDesc.SetLandscape( rSrcDesc.GetLandscape() );
rDstDesc.SetNumType( rSrcDesc.GetNumType() );
if( rDstDesc.ReadUseOn() != rSrcDesc.ReadUseOn() )
{
rDstDesc.WriteUseOn( rSrcDesc.ReadUseOn() );
bNotifyLayout = true;
}
if( bCopyPoolIds )
{
rDstDesc.SetPoolFormatId( rSrcDesc.GetPoolFormatId() );
rDstDesc.SetPoolHelpId( rSrcDesc.GetPoolHelpId() );
// Always set the HelpFile Id to default!
rDstDesc.SetPoolHlpFileId( UCHAR_MAX );
}
if( rSrcDesc.GetFollow() != &rSrcDesc )
{
const SwPageDesc* pSrcFollow = rSrcDesc.GetFollow();
SwPageDesc* pFollow = FindPageDesc( pSrcFollow->GetName() );
if( !pFollow )
{
// copy
pFollow = MakePageDesc( pSrcFollow->GetName() );
CopyPageDesc( *pSrcFollow, *pFollow );
}
rDstDesc.SetFollow( pFollow );
bNotifyLayout = true;
}
// the header and footer attributes are copied separately
// the content sections have to be copied in their entirety
{
SfxItemSet aAttrSet( rSrcDesc.GetMaster().GetAttrSet() );
aAttrSet.ClearItem( RES_HEADER );
aAttrSet.ClearItem( RES_FOOTER );
rDstDesc.GetMaster().DelDiffs( aAttrSet );
rDstDesc.GetMaster().SetFormatAttr( aAttrSet );
aAttrSet.ClearItem();
aAttrSet.Put( rSrcDesc.GetLeft().GetAttrSet() );
aAttrSet.ClearItem( RES_HEADER );
aAttrSet.ClearItem( RES_FOOTER );
rDstDesc.GetLeft().DelDiffs( aAttrSet );
rDstDesc.GetLeft().SetFormatAttr( aAttrSet );
aAttrSet.ClearItem();
aAttrSet.Put( rSrcDesc.GetFirstMaster().GetAttrSet() );
aAttrSet.ClearItem( RES_HEADER );
aAttrSet.ClearItem( RES_FOOTER );
rDstDesc.GetFirstMaster().DelDiffs( aAttrSet );
rDstDesc.GetFirstMaster().SetFormatAttr( aAttrSet );
aAttrSet.ClearItem();
aAttrSet.Put( rSrcDesc.GetFirstLeft().GetAttrSet() );
aAttrSet.ClearItem( RES_HEADER );
aAttrSet.ClearItem( RES_FOOTER );
rDstDesc.GetFirstLeft().DelDiffs( aAttrSet );
rDstDesc.GetFirstLeft().SetFormatAttr( aAttrSet );
}
CopyHeader( rSrcDesc.GetMaster(), rDstDesc.GetMaster() );
CopyFooter( rSrcDesc.GetMaster(), rDstDesc.GetMaster() );
if( !rDstDesc.IsHeaderShared() )
CopyHeader( rSrcDesc.GetLeft(), rDstDesc.GetLeft() );
else
rDstDesc.GetLeft().SetFormatAttr( rDstDesc.GetMaster().GetHeader() );
if( !rDstDesc.IsFirstShared() )
{
CopyHeader( rSrcDesc.GetFirstMaster(), rDstDesc.GetFirstMaster() );
rDstDesc.GetFirstLeft().SetFormatAttr(rDstDesc.GetFirstMaster().GetHeader());
}
else
{
rDstDesc.GetFirstMaster().SetFormatAttr( rDstDesc.GetMaster().GetHeader() );
rDstDesc.GetFirstLeft().SetFormatAttr(rDstDesc.GetLeft().GetHeader());
}
if( !rDstDesc.IsFooterShared() )
CopyFooter( rSrcDesc.GetLeft(), rDstDesc.GetLeft() );
else
rDstDesc.GetLeft().SetFormatAttr( rDstDesc.GetMaster().GetFooter() );
if( !rDstDesc.IsFirstShared() )
{
CopyFooter( rSrcDesc.GetFirstMaster(), rDstDesc.GetFirstMaster() );
rDstDesc.GetFirstLeft().SetFormatAttr(rDstDesc.GetFirstMaster().GetFooter());
}
else
{
rDstDesc.GetFirstMaster().SetFormatAttr( rDstDesc.GetMaster().GetFooter() );
rDstDesc.GetFirstLeft().SetFormatAttr(rDstDesc.GetLeft().GetFooter());
}
if( bNotifyLayout && pTmpRoot )
{
for( auto aLayout : GetAllLayouts() )
aLayout->AllCheckPageDescs();
}
// If foot notes change the pages have to be triggered
if( !(rDstDesc.GetFootnoteInfo() == rSrcDesc.GetFootnoteInfo()) )
{
sw::PageFootnoteHint aHint;
rDstDesc.SetFootnoteInfo( rSrcDesc.GetFootnoteInfo() );
rDstDesc.GetMaster().CallSwClientNotify(aHint);
rDstDesc.GetLeft().CallSwClientNotify(aHint);
rDstDesc.GetFirstMaster().CallSwClientNotify(aHint);
rDstDesc.GetFirstLeft().CallSwClientNotify(aHint);
}
}
void SwDoc::ReplaceStyles( const SwDoc& rSource, bool bIncludePageStyles )
{
::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo());
CopyFormatArr( *rSource.mpCharFormatTable, *mpCharFormatTable,
&SwDoc::MakeCharFormat_, *mpDfltCharFormat );
CopyFormatArr( *rSource.mpFrameFormatTable, *mpFrameFormatTable,
&SwDoc::MakeFrameFormat_, *mpDfltFrameFormat );
CopyFormatArr( *rSource.mpTextFormatCollTable, *mpTextFormatCollTable,
&SwDoc::MakeTextFormatColl_, *mpDfltTextFormatColl );
//To-Do:
// a) in rtf export don't export our hideous pgdsctbl
// extension to rtf anymore
// b) in sd rtf import (View::InsertData) don't use
// a super-fragile test for mere presence of \trowd to
// indicate import of rtf into a table
// c) then drop use of bIncludePageStyles
if (bIncludePageStyles)
{
// and now the page templates
SwPageDescs::size_type nCnt = rSource.m_PageDescs.size();
if( nCnt )
{
// a different Doc -> Number formatter needs to be merged
SwTableNumFormatMerge aTNFM( rSource, *this );
// 1st step: Create all formats (skip the 0th - it's the default!)
while( nCnt )
{
const SwPageDesc &rSrc = *rSource.m_PageDescs[ --nCnt ];
if( nullptr == FindPageDesc( rSrc.GetName() ) )
MakePageDesc( rSrc.GetName() );
}
// 2nd step: Copy all attributes, set the right parents
for (SwPageDescs::size_type i = rSource.m_PageDescs.size(); i; )
{
const SwPageDesc &rSrc = *rSource.m_PageDescs[ --i ];
SwPageDesc* pDesc = FindPageDesc( rSrc.GetName() );
CopyPageDesc( rSrc, *pDesc);
}
}
}
// then there are the numbering templates
const SwNumRuleTable::size_type nCnt = rSource.GetNumRuleTable().size();
if( nCnt )
{
const SwNumRuleTable& rArr = rSource.GetNumRuleTable();
for( SwNumRuleTable::size_type n = 0; n < nCnt; ++n )
{
const SwNumRule& rR = *rArr[ n ];
SwNumRule* pNew = FindNumRulePtr( rR.GetName());
if( pNew )
pNew->CopyNumRule( this, rR );
else
{
if( !rR.IsAutoRule() )
MakeNumRule( rR.GetName(), &rR );
else
{
// as we reset all styles, there shouldn't be any unknown
// automatic SwNumRules, because all should have been
// created by the style copying!
// So just warn and ignore.
SAL_WARN( "sw.core", "Found unknown auto SwNumRule during reset!" );
}
}
}
}
if (undoGuard.UndoWasEnabled())
{
// nodes array was modified!
GetIDocumentUndoRedo().DelAllUndoObj();
}
getIDocumentState().SetModified();
}
SwFormat* SwDoc::FindFormatByName( const SwFormatsBase& rFormatArr,
const OUString& rName )
{
SwFormat* pFnd = nullptr;
for( size_t n = 0; n < rFormatArr.GetFormatCount(); ++n )
{
// Does the Doc already contain the template?
if( rFormatArr.GetFormat(n)->HasName( rName ) )
{
pFnd = rFormatArr.GetFormat(n);
break;
}
}
return pFnd;
}
void SwDoc::MoveLeftMargin( const SwPaM& rPam, bool bRight, bool bModulus )
{
SwHistory* pHistory = nullptr;
if (GetIDocumentUndoRedo().DoesUndo())
{
SwUndoMoveLeftMargin* pUndo = new SwUndoMoveLeftMargin( rPam, bRight,
bModulus );
pHistory = &pUndo->GetHistory();
GetIDocumentUndoRedo().AppendUndo( pUndo );
}
const SvxTabStopItem& rTabItem = GetDefault( RES_PARATR_TABSTOP );
const sal_Int32 nDefDist = rTabItem.Count() ? rTabItem[0].GetTabPos() : 1134;
const SwPosition &rStt = *rPam.Start(), &rEnd = *rPam.End();
SwNodeIndex aIdx( rStt.nNode );
while( aIdx <= rEnd.nNode )
{
SwTextNode* pTNd = aIdx.GetNode().GetTextNode();
if( pTNd )
{
SvxLRSpaceItem aLS( static_cast<const SvxLRSpaceItem&>(pTNd->SwContentNode::GetAttr( RES_LR_SPACE )) );
// #i93873# See also lcl_MergeListLevelIndentAsLRSpaceItem in thints.cxx
if ( pTNd->AreListLevelIndentsApplicable() )
{
const SwNumRule* pRule = pTNd->GetNumRule();
if ( pRule )
{
const int nListLevel = pTNd->GetActualListLevel();
if ( nListLevel >= 0 )
{
const SwNumFormat& rFormat = pRule->Get(static_cast<sal_uInt16>(nListLevel));
if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
{
aLS.SetTextLeft( rFormat.GetIndentAt() );
aLS.SetTextFirstLineOfst( static_cast<short>(rFormat.GetFirstLineIndent()) );
}
}
}
}
long nNext = aLS.GetTextLeft();
if( bModulus )
nNext = ( nNext / nDefDist ) * nDefDist;
if( bRight )
nNext += nDefDist;
else
if(nNext >0) // fdo#75936 set limit for decreasing indent
nNext -= nDefDist;
aLS.SetTextLeft( nNext );
SwRegHistory aRegH( pTNd, *pTNd, pHistory );
pTNd->SetAttr( aLS );
}
++aIdx;
}
getIDocumentState().SetModified();
}
bool SwDoc::DontExpandFormat( const SwPosition& rPos, bool bFlag )
{
bool bRet = false;
SwTextNode* pTextNd = rPos.nNode.GetNode().GetTextNode();
if( pTextNd )
{
bRet = pTextNd->DontExpandFormat( rPos.nContent, bFlag );
if( bRet && GetIDocumentUndoRedo().DoesUndo() )
{
GetIDocumentUndoRedo().AppendUndo( new SwUndoDontExpandFormat(rPos) );
}
}
return bRet;
}
SwTableBoxFormat* SwDoc::MakeTableBoxFormat()
{
SwTableBoxFormat* pFormat = new SwTableBoxFormat( GetAttrPool(), mpDfltFrameFormat.get() );
getIDocumentState().SetModified();
return pFormat;
}
SwTableLineFormat* SwDoc::MakeTableLineFormat()
{
SwTableLineFormat* pFormat = new SwTableLineFormat( GetAttrPool(), mpDfltFrameFormat.get() );
getIDocumentState().SetModified();
return pFormat;
}
void SwDoc::CreateNumberFormatter()
{
OSL_ENSURE( !mpNumberFormatter, "is already there" );
LanguageType eLang = LANGUAGE_SYSTEM;
mpNumberFormatter.reset( new SvNumberFormatter( comphelper::getProcessComponentContext(), eLang ) );
mpNumberFormatter->SetEvalDateFormat( NF_EVALDATEFORMAT_FORMAT_INTL );
if (!utl::ConfigManager::IsFuzzing())
mpNumberFormatter->SetYear2000(static_cast<sal_uInt16>(::utl::MiscCfg().GetYear2000()));
}
SwTableNumFormatMerge::SwTableNumFormatMerge( const SwDoc& rSrc, SwDoc& rDest )
: pNFormat( nullptr )
{
// a different Doc -> Number formatter needs to be merged
SvNumberFormatter* pN;
if( &rSrc != &rDest && nullptr != ( pN = const_cast<SwDoc&>(rSrc).GetNumberFormatter( false ) ))
( pNFormat = rDest.GetNumberFormatter())->MergeFormatter( *pN );
if( &rSrc != &rDest )
static_cast<SwGetRefFieldType*>(rSrc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::GetRef ))->
MergeWithOtherDoc( rDest );
}
SwTableNumFormatMerge::~SwTableNumFormatMerge()
{
if( pNFormat )
pNFormat->ClearMergeTable();
}
void SwDoc::SetTextFormatCollByAutoFormat( const SwPosition& rPos, sal_uInt16 nPoolId,
const SfxItemSet* pSet )
{
SwPaM aPam( rPos );
SwTextNode* pTNd = rPos.nNode.GetNode().GetTextNode();
assert(pTNd);
if (mbIsAutoFormatRedline)
{
// create the redline object
const SwTextFormatColl& rColl = *pTNd->GetTextColl();
SwRangeRedline* pRedl = new SwRangeRedline( nsRedlineType_t::REDLINE_FMTCOLL, aPam );
pRedl->SetMark();
// Only those items that are not set by the Set again in the Node
// are of interest. Thus, we take the difference.
SwRedlineExtraData_FormatColl aExtraData( rColl.GetName(),
rColl.GetPoolFormatId() );
if( pSet && pTNd->HasSwAttrSet() )
{
SfxItemSet aTmp( *pTNd->GetpSwAttrSet() );
aTmp.Differentiate( *pSet );
// we handle the adjust item separately
const SfxPoolItem* pItem;
if( SfxItemState::SET == pTNd->GetpSwAttrSet()->GetItemState(
RES_PARATR_ADJUST, false, &pItem ))
aTmp.Put( *pItem );
aExtraData.SetItemSet( aTmp );
}
pRedl->SetExtraData( &aExtraData );
//TODO: Undo is still missing!
getIDocumentRedlineAccess().AppendRedline( pRedl, true );
}
SetTextFormatColl( aPam, getIDocumentStylePoolAccess().GetTextCollFromPool( nPoolId ) );
if (pSet && pSet->Count())
{
aPam.SetMark();
aPam.GetMark()->nContent.Assign(pTNd, pTNd->GetText().getLength());
getIDocumentContentOperations().InsertItemSet( aPam, *pSet );
}
}
void SwDoc::SetFormatItemByAutoFormat( const SwPaM& rPam, const SfxItemSet& rSet )
{
SwTextNode* pTNd = rPam.GetPoint()->nNode.GetNode().GetTextNode();
assert(pTNd);
RedlineFlags eOld = getIDocumentRedlineAccess().GetRedlineFlags();
if (mbIsAutoFormatRedline)
{
// create the redline object
SwRangeRedline* pRedl = new SwRangeRedline( nsRedlineType_t::REDLINE_FORMAT, rPam );
if( !pRedl->HasMark() )
pRedl->SetMark();
// Only those items that are not set by the Set again in the Node
// are of interest. Thus, we take the difference.
SwRedlineExtraData_Format aExtraData( rSet );
pRedl->SetExtraData( &aExtraData );
//TODO: Undo is still missing!
getIDocumentRedlineAccess().AppendRedline( pRedl, true );
getIDocumentRedlineAccess().SetRedlineFlags_intern( eOld | RedlineFlags::Ignore );
}
const sal_Int32 nEnd(rPam.End()->nContent.GetIndex());
std::vector<sal_uInt16> whichIds;
SfxItemIter iter(rSet);
for (SfxPoolItem const* pItem = iter.FirstItem();
pItem; pItem = iter.NextItem())
{
whichIds.push_back(pItem->Which());
whichIds.push_back(pItem->Which());
}
whichIds.push_back(0);
SfxItemSet currentSet(GetAttrPool(), &whichIds[0]);
pTNd->GetAttr(currentSet, nEnd, nEnd);
for (size_t i = 0; whichIds[i]; i += 2)
{ // yuk - want to explicitly set the pool defaults too :-/
currentSet.Put(currentSet.Get(whichIds[i]));
}
getIDocumentContentOperations().InsertItemSet( rPam, rSet, SetAttrMode::DONTEXPAND );
// fdo#62536: DONTEXPAND does not work when there is already an AUTOFMT
// here, so insert the old attributes as an empty hint to stop expand
SwPaM endPam(*pTNd, nEnd);
endPam.SetMark();
getIDocumentContentOperations().InsertItemSet(endPam, currentSet);
getIDocumentRedlineAccess().SetRedlineFlags_intern( eOld );
}
void SwDoc::ChgFormat(SwFormat & rFormat, const SfxItemSet & rSet)
{
if (GetIDocumentUndoRedo().DoesUndo())
{
// copying <rSet> to <aSet>
SfxItemSet aSet(rSet);
// remove from <aSet> all items, which are already set at the format
aSet.Differentiate(rFormat.GetAttrSet());
// <aSet> contains now all *new* items for the format
// copying current format item set to <aOldSet>
SfxItemSet aOldSet(rFormat.GetAttrSet());
// insert new items into <aOldSet>
aOldSet.Put(aSet);
// invalidate all new items in <aOldSet> in order to clear these items,
// if the undo action is triggered.
{
SfxItemIter aIter(aSet);
const SfxPoolItem * pItem = aIter.FirstItem();
while (pItem != nullptr)
{
aOldSet.InvalidateItem(pItem->Which());
pItem = aIter.NextItem();
}
}
SwUndo * pUndo = new SwUndoFormatAttr(aOldSet, rFormat, /*bSaveDrawPt*/true);
GetIDocumentUndoRedo().AppendUndo(pUndo);
}
rFormat.SetFormatAttr(rSet);
}
void SwDoc::RenameFormat(SwFormat & rFormat, const OUString & sNewName,
bool bBroadcast)
{
SfxStyleFamily eFamily = SfxStyleFamily::All;
if (GetIDocumentUndoRedo().DoesUndo())
{
SwUndo * pUndo = nullptr;
switch (rFormat.Which())
{
case RES_CHRFMT:
pUndo = new SwUndoRenameCharFormat(rFormat.GetName(), sNewName, this);
eFamily = SfxStyleFamily::Char;
break;
case RES_TXTFMTCOLL:
pUndo = new SwUndoRenameFormatColl(rFormat.GetName(), sNewName, this);
eFamily = SfxStyleFamily::Para;
break;
case RES_FRMFMT:
pUndo = new SwUndoRenameFrameFormat(rFormat.GetName(), sNewName, this);
eFamily = SfxStyleFamily::Frame;
break;
default:
break;
}
if (pUndo)
{
GetIDocumentUndoRedo().AppendUndo(pUndo);
}
}
rFormat.SetName(sNewName);
if (bBroadcast)
BroadcastStyleOperation(sNewName, eFamily, SfxHintId::StyleSheetModified);
}
void SwDoc::dumpAsXml(xmlTextWriterPtr pWriter) const
{
bool bOwns = false;
if (!pWriter)
{
pWriter = xmlNewTextWriterFilename("nodes.xml", 0);
xmlTextWriterSetIndent(pWriter,1);
xmlTextWriterSetIndentString(pWriter, BAD_CAST(" "));
xmlTextWriterStartDocument(pWriter, nullptr, nullptr, nullptr);
bOwns = true;
}
xmlTextWriterStartElement(pWriter, BAD_CAST("SwDoc"));
xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
m_pNodes->dumpAsXml(pWriter);
maDBData.dumpAsXml(pWriter);
mpMarkManager->dumpAsXml(pWriter);
m_pUndoManager->dumpAsXml(pWriter);
getIDocumentFieldsAccess().GetFieldTypes()->dumpAsXml(pWriter);
mpTextFormatCollTable->dumpAsXml(pWriter);
mpCharFormatTable->dumpAsXml(pWriter);
mpFrameFormatTable->dumpAsXml(pWriter, "frmFormatTable");
mpSpzFrameFormatTable->dumpAsXml(pWriter, "spzFrameFormatTable");
mpSectionFormatTable->dumpAsXml(pWriter);
mpNumRuleTable->dumpAsXml(pWriter);
getIDocumentRedlineAccess().GetRedlineTable().dumpAsXml(pWriter);
getIDocumentRedlineAccess().GetExtraRedlineTable().dumpAsXml(pWriter);
if (const SdrModel* pModel = getIDocumentDrawModelAccess().GetDrawModel())
pModel->dumpAsXml(pWriter);
xmlTextWriterStartElement(pWriter, BAD_CAST("mbModified"));
xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(OString::boolean(getIDocumentState().IsModified()).getStr()));
xmlTextWriterEndElement(pWriter);
xmlTextWriterEndElement(pWriter);
if (bOwns)
{
xmlTextWriterEndDocument(pWriter);
xmlFreeTextWriter(pWriter);
}
}
void SwDBData::dumpAsXml(xmlTextWriterPtr pWriter) const
{
xmlTextWriterStartElement(pWriter, BAD_CAST("SwDBData"));
xmlTextWriterWriteAttribute(pWriter, BAD_CAST("sDataSource"), BAD_CAST(sDataSource.toUtf8().getStr()));
xmlTextWriterWriteAttribute(pWriter, BAD_CAST("sCommand"), BAD_CAST(sCommand.toUtf8().getStr()));
xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nCommandType"), BAD_CAST(OString::number(nCommandType).getStr()));
xmlTextWriterEndElement(pWriter);
}
std::set<Color> SwDoc::GetDocColors()
{
std::set<Color> aDocColors;
SwAttrPool& rPool = GetAttrPool();
const sal_uInt16 pAttribs[] = {RES_CHRATR_COLOR, RES_CHRATR_HIGHLIGHT, RES_BACKGROUND};
for (sal_uInt16 nAttrib : pAttribs)
{
const sal_uInt32 nCount = rPool.GetItemCount2(nAttrib);
for (sal_uInt32 j=0; j<nCount; j++)
{
const SvxColorItem *pItem = static_cast<const SvxColorItem*>(rPool.GetItem2(nAttrib, j));
if (pItem == nullptr)
continue;
Color aColor( pItem->GetValue() );
if (COL_AUTO != aColor)
aDocColors.insert(aColor);
}
}
return aDocColors;
}
// #i69627#
namespace docfunc
{
bool HasOutlineStyleToBeWrittenAsNormalListStyle( SwDoc& rDoc )
{
// If a parent paragraph style of one of the paragraph styles, which
// are assigned to the list levels of the outline style, has a list style
// set or inherits a list style from its parent style, the outline style
// has to be written as a normal list style to the OpenDocument file
// format or the OpenOffice.org file format.
bool bRet( false );
const SwTextFormatColls* pTextFormatColls( rDoc.GetTextFormatColls() );
if ( pTextFormatColls )
{
for ( auto pTextFormatColl : *pTextFormatColls )
{
if ( pTextFormatColl->IsDefault() ||
! pTextFormatColl->IsAssignedToListLevelOfOutlineStyle() )
{
continue;
}
const SwTextFormatColl* pParentTextFormatColl =
dynamic_cast<const SwTextFormatColl*>( pTextFormatColl->DerivedFrom());
if ( !pParentTextFormatColl )
continue;
if ( SfxItemState::SET == pParentTextFormatColl->GetItemState( RES_PARATR_NUMRULE ) )
{
// #i106218# consider that the outline style is set
const SwNumRuleItem& rDirectItem = pParentTextFormatColl->GetNumRule();
if ( rDirectItem.GetValue() != rDoc.GetOutlineNumRule()->GetName() )
{
bRet = true;
break;
}
}
}
}
return bRet;
}
}
SwFrameFormats::SwFrameFormats()
: m_PosIndex( m_Array.get<0>() )
, m_TypeAndNameIndex( m_Array.get<1>() )
{
}
SwFrameFormats::~SwFrameFormats()
{
DeleteAndDestroyAll();
}
SwFrameFormats::iterator SwFrameFormats::find( const value_type& x ) const
{
ByTypeAndName::iterator it = m_TypeAndNameIndex.find(
boost::make_tuple(x->Which(), x->GetName(), x) );
return m_Array.project<0>( it );
}
std::pair<SwFrameFormats::const_range_iterator,SwFrameFormats::const_range_iterator>
SwFrameFormats::rangeFind( sal_uInt16 type, const OUString& name ) const
{
return m_TypeAndNameIndex.equal_range( boost::make_tuple(type, name) );
}
std::pair<SwFrameFormats::const_range_iterator,SwFrameFormats::const_range_iterator>
SwFrameFormats::rangeFind( const value_type& x ) const
{
return rangeFind( x->Which(), x->GetName() );
}
void SwFrameFormats::DeleteAndDestroyAll( bool keepDefault )
{
if ( empty() )
return;
const int _offset = keepDefault ? 1 : 0;
for( const_iterator it = begin() + _offset; it != end(); ++it )
delete *it;
if ( _offset )
m_PosIndex.erase( begin() + _offset, end() );
else
m_Array.clear();
}
std::pair<SwFrameFormats::const_iterator,bool> SwFrameFormats::push_back( const value_type& x )
{
SAL_WARN_IF(x->m_ffList != nullptr, "sw.core", "Inserting already assigned item");
assert(x->m_ffList == nullptr);
x->m_ffList = this;
return m_PosIndex.push_back( x );
}
bool SwFrameFormats::erase( const value_type& x )
{
const_iterator const ret = find( x );
SAL_WARN_IF(x->m_ffList != this, "sw.core", "Removing invalid / unassigned item");
if (ret != end()) {
assert( x == *ret );
m_PosIndex.erase( ret );
x->m_ffList = nullptr;
return true;
}
return false;
}
void SwFrameFormats::erase( size_type index_ )
{
erase( begin() + index_ );
}
void SwFrameFormats::erase( const_iterator const& position )
{
(*position)->m_ffList = nullptr;
m_PosIndex.erase( begin() + (position - begin()) );
}
bool SwFrameFormats::ContainsFormat(const SwFrameFormat& x) const
{
return (x.m_ffList == this);
}
bool SwFrameFormats::IsAlive(SwFrameFormat const*const p) const
{
return find(const_cast<SwFrameFormat*>(p)) != end();
}
bool SwFrameFormats::newDefault( const value_type& x )
{
std::pair<iterator,bool> res = m_PosIndex.push_front( x );
if( ! res.second )
newDefault( res.first );
return res.second;
}
void SwFrameFormats::newDefault( const_iterator const& position )
{
if (position == begin())
return;
m_PosIndex.relocate( begin(), position );
}
/* 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 'SetNextTextFormatColl' function.
↑ V678 An object is used as an argument to its own method. Consider checking the first actual argument of the 'FormatToTextAttr' function.
↑ V678 An object is used as an argument to its own method. Consider checking the first actual argument of the 'FormatToTextAttr' function.
↑ V678 An object is used as an argument to its own method. Consider checking the first actual argument of the 'FormatToTextAttr' function.
↑ V678 An object is used as an argument to its own method. Consider checking the first actual argument of the 'FormatToTextAttr' function.