2113 lines
75 KiB
C++
2113 lines
75 KiB
C++
/* -*- 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 <svl/numformat.hxx>
|
|
#include <editeng/tstpitem.hxx>
|
|
#include <editeng/lrspitem.hxx>
|
|
#include <editeng/formatbreakitem.hxx>
|
|
#include <editeng/rsiditem.hxx>
|
|
#include <officecfg/Office/Common.hxx>
|
|
#include <osl/diagnose.h>
|
|
#include <svl/zforlist.hxx>
|
|
#include <svx/DocumentColorHelper.hxx>
|
|
#include <comphelper/processfactory.hxx>
|
|
#include <unotools/configmgr.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 <doc.hxx>
|
|
#include <docfunc.hxx>
|
|
#include <drawdoc.hxx>
|
|
#include <MarkManager.hxx>
|
|
#include <IDocumentDrawModelAccess.hxx>
|
|
#include <IDocumentUndoRedo.hxx>
|
|
#include <DocumentContentOperationsManager.hxx>
|
|
#include <DocumentSettingManager.hxx>
|
|
#include <IDocumentFieldsAccess.hxx>
|
|
#include <IDocumentState.hxx>
|
|
#include <IDocumentLayoutAccess.hxx>
|
|
#include <IDocumentRedlineAccess.hxx>
|
|
#include <IDocumentStylePoolAccess.hxx>
|
|
#include <rootfrm.hxx>
|
|
#include <txtfrm.hxx>
|
|
#include <hints.hxx>
|
|
#include <ndtxt.hxx>
|
|
#include <pam.hxx>
|
|
#include <UndoCore.hxx>
|
|
#include <UndoAttribute.hxx>
|
|
#include <UndoInsert.hxx>
|
|
#include <pagedesc.hxx>
|
|
#include <rolbck.hxx>
|
|
#include <mvsave.hxx>
|
|
#include <txatbase.hxx>
|
|
#include <swtblfmt.hxx>
|
|
#include <charfmt.hxx>
|
|
#include <docary.hxx>
|
|
#include <paratr.hxx>
|
|
#include <redline.hxx>
|
|
#include <reffld.hxx>
|
|
#include <fmtinfmt.hxx>
|
|
#include <breakit.hxx>
|
|
#include <SwUndoFmt.hxx>
|
|
#include <UndoManager.hxx>
|
|
#include <swmodule.hxx>
|
|
#include <modcfg.hxx>
|
|
#include <frameformats.hxx>
|
|
#include <textboxhelper.hxx>
|
|
#include <textcontentcontrol.hxx>
|
|
#include <memory>
|
|
#include <algorithm>
|
|
#include <functional>
|
|
|
|
using namespace ::com::sun::star::i18n;
|
|
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( SwNode* pNd, void* pArgs )
|
|
{
|
|
const sw::DocumentContentOperationsManager::ParaRstFormat* pPara = static_cast<sw::DocumentContentOperationsManager::ParaRstFormat*>(pArgs);
|
|
SwContentNode* pNode = pNd->GetContentNode();
|
|
if (pPara && pPara->pLayout && pPara->pLayout->HasMergedParas()
|
|
&& pNode && pNode->GetRedlineMergeFlag() == SwNode::Merge::Hidden)
|
|
{
|
|
return true;
|
|
}
|
|
if( pNode && pNode->HasSwAttrSet() )
|
|
{
|
|
const bool bLocked = pNode->IsModifyLocked();
|
|
pNode->LockModify();
|
|
|
|
SwDoc& rDoc = pNode->GetDoc();
|
|
|
|
// remove unused attribute RES_LR_SPACE
|
|
// add list attributes, except RES_PARATR_LIST_AUTOFMT
|
|
SfxItemSetFixed<
|
|
RES_PARATR_NUMRULE, RES_PARATR_NUMRULE,
|
|
RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_AUTOFMT - 1,
|
|
RES_PAGEDESC, RES_BREAK,
|
|
RES_FRMATR_STYLE_NAME, RES_FRMATR_CONDITIONAL_STYLE_NAME> aSavedAttrsSet(rDoc.GetAttrPool());
|
|
const SfxItemSet* pAttrSetOfNode = pNode->GetpSwAttrSet();
|
|
|
|
std::vector<sal_uInt16> aClearWhichIds;
|
|
// restoring all paragraph list attributes
|
|
{
|
|
SfxItemSetFixed<RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_AUTOFMT - 1> aListAttrSet( rDoc.GetAttrPool() );
|
|
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();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (auto pItem = pAttrSetOfNode->GetItemIfSet(RES_PARATR_NUMRULE, false);
|
|
pItem && !pItem->GetValue().isEmpty())
|
|
{
|
|
aSavedAttrsSet.Put(*pItem);
|
|
aClearWhichIds.push_back(RES_PARATR_NUMRULE);
|
|
}
|
|
if (auto pItem = pAttrSetOfNode->GetItemIfSet(RES_PAGEDESC, false);
|
|
pItem && pItem->GetPageDesc())
|
|
{
|
|
aSavedAttrsSet.Put(*pItem);
|
|
aClearWhichIds.push_back(RES_PAGEDESC);
|
|
}
|
|
if (auto pItem = pAttrSetOfNode->GetItemIfSet(RES_BREAK, false);
|
|
pItem && pItem->GetBreak() != SvxBreak::NONE)
|
|
{
|
|
aSavedAttrsSet.Put(*pItem);
|
|
aClearWhichIds.push_back(RES_BREAK);
|
|
}
|
|
if (auto pItem = pAttrSetOfNode->GetItemIfSet(RES_FRMATR_STYLE_NAME, false);
|
|
pItem && !pItem->GetValue().isEmpty())
|
|
{
|
|
aSavedAttrsSet.Put(*pItem);
|
|
aClearWhichIds.push_back(RES_FRMATR_STYLE_NAME);
|
|
}
|
|
if (auto pItem = pAttrSetOfNode->GetItemIfSet(RES_FRMATR_CONDITIONAL_STYLE_NAME, false);
|
|
pItem && !pItem->GetValue().isEmpty())
|
|
{
|
|
aSavedAttrsSet.Put(*pItem);
|
|
aClearWhichIds.push_back(RES_FRMATR_CONDITIONAL_STYLE_NAME);
|
|
}
|
|
|
|
// 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 );
|
|
for (const SfxPoolItem* pItem = aIter.GetCurItem(); pItem; pItem = aIter.NextItem())
|
|
{
|
|
if ( ( pItem->Which() != RES_PAGEDESC &&
|
|
pItem->Which() != RES_BREAK &&
|
|
pItem->Which() != RES_FRMATR_STYLE_NAME &&
|
|
pItem->Which() != RES_FRMATR_CONDITIONAL_STYLE_NAME &&
|
|
pItem->Which() != RES_PARATR_NUMRULE ) ||
|
|
( aSavedAttrsSet.GetItemState( pItem->Which(), false ) != SfxItemState::SET ) )
|
|
{
|
|
pNode->ResetAttr( pItem->Which() );
|
|
}
|
|
}
|
|
}
|
|
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, SwRootFrame const*const pLayout)
|
|
{
|
|
SwHistory* pHst = nullptr;
|
|
SwDataChanged aTmp( rRg );
|
|
if (GetIDocumentUndoRedo().DoesUndo())
|
|
{
|
|
std::unique_ptr<SwUndoResetAttr> pUndo(new SwUndoResetAttr( rRg, RES_CHRFMT ));
|
|
pHst = &pUndo->GetHistory();
|
|
GetIDocumentUndoRedo().AppendUndo(std::move(pUndo));
|
|
}
|
|
auto [pStt, pEnd] = rRg.StartEnd(); // SwPosition*
|
|
sw::DocumentContentOperationsManager::ParaRstFormat aPara(
|
|
pStt, pEnd, pHst, nullptr, pLayout );
|
|
aPara.bInclRefToxMark = bInclRefToxMark;
|
|
aPara.bExactRange = bExactRange;
|
|
GetNodes().ForEach( pStt->GetNodeIndex(), pEnd->GetNodeIndex()+1,
|
|
sw::DocumentContentOperationsManager::lcl_RstTextAttr, &aPara );
|
|
getIDocumentState().SetModified();
|
|
}
|
|
|
|
void SwDoc::ResetAttrs( const SwPaM &rRg,
|
|
bool bTextAttr,
|
|
const o3tl::sorted_vector<sal_uInt16> &rAttrs,
|
|
const bool bSendDataChangedEvents,
|
|
SwRootFrame const*const pLayout)
|
|
{
|
|
SwPaM* pPam = const_cast<SwPaM*>(&rRg);
|
|
std::optional<SwPaM> oExtraPaM;
|
|
if( !bTextAttr && !rAttrs.empty() && RES_TXTATR_END > *(rAttrs.begin()) )
|
|
bTextAttr = true;
|
|
|
|
if( !rRg.HasMark() )
|
|
{
|
|
SwTextNode* pTextNd = rRg.GetPoint()->GetNode().GetTextNode();
|
|
if( !pTextNd )
|
|
return ;
|
|
|
|
oExtraPaM.emplace( *rRg.GetPoint() );
|
|
pPam = &*oExtraPaM;
|
|
|
|
SwPosition& rSt = *pPam->GetPoint();
|
|
sal_Int32 nMkPos, nPtPos = rSt.GetContentIndex();
|
|
|
|
// Special case: if the Cursor is located within a URL attribute, we take over it's area
|
|
SwTextAttr const*const pURLAttr(
|
|
pTextNd->GetTextAttrAt(rSt.GetContentIndex(), 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.GetContentIndex();
|
|
if( bTextAttr )
|
|
pTextNd->DontExpandFormat( nPtPos );
|
|
}
|
|
}
|
|
|
|
rSt.SetContent(nMkPos);
|
|
pPam->SetMark();
|
|
pPam->GetPoint()->SetContent(nPtPos);
|
|
}
|
|
|
|
// #i96644#
|
|
std::optional< SwDataChanged > oDataChanged;
|
|
if ( bSendDataChangedEvents )
|
|
{
|
|
oDataChanged.emplace( *pPam );
|
|
}
|
|
SwHistory* pHst = nullptr;
|
|
if (GetIDocumentUndoRedo().DoesUndo())
|
|
{
|
|
std::unique_ptr<SwUndoResetAttr> pUndo(new SwUndoResetAttr( rRg,
|
|
bTextAttr ? sal_uInt16(RES_CONDTXTFMTCOLL) : sal_uInt16(RES_TXTFMTCOLL) ));
|
|
if( !rAttrs.empty() )
|
|
{
|
|
pUndo->SetAttrs( o3tl::sorted_vector(rAttrs) );
|
|
}
|
|
pHst = &pUndo->GetHistory();
|
|
GetIDocumentUndoRedo().AppendUndo(std::move(pUndo));
|
|
}
|
|
|
|
auto [pStt, pEnd] = pPam->StartEnd(); // SwPosition*
|
|
sw::DocumentContentOperationsManager::ParaRstFormat aPara(
|
|
pStt, pEnd, pHst, nullptr, pLayout);
|
|
|
|
// mst: not including META here; it seems attrs with CH_TXTATR are omitted
|
|
SfxItemSetFixed<RES_CHRATR_BEGIN, RES_CHRATR_END - 1,
|
|
RES_TXTATR_INETFMT, RES_TXTATR_UNKNOWN_CONTAINER,
|
|
RES_PARATR_BEGIN, RES_FRMATR_END - 1,
|
|
RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END - 1>
|
|
aDelSet(GetAttrPool());
|
|
for( auto 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->GetNode() );
|
|
SwNodeIndex aTmpEnd( pEnd->GetNode() );
|
|
if( pStt->GetContentIndex() ) // 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->GetNode().IsContentNode()
|
|
|| pEnd->GetContentIndex() == pEnd->GetNode().GetContentNode()->Len())
|
|
{
|
|
// set up a later, and all CharFormatAttr -> TextFormatAttr
|
|
++aTmpEnd;
|
|
bAdd = false;
|
|
}
|
|
else if( pStt->GetNode() != pEnd->GetNode() || !pStt->GetContentIndex() )
|
|
{
|
|
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->GetNode(), aTmpEnd.GetNode(), lcl_RstAttr, &aPara );
|
|
else if( !rRg.HasMark() )
|
|
{
|
|
aPara.bResetAll = false ;
|
|
::lcl_RstAttr( &pStt->GetNode(), &aPara );
|
|
aPara.bResetAll = true ;
|
|
}
|
|
|
|
if( bTextAttr )
|
|
{
|
|
if( bAdd )
|
|
++aTmpEnd;
|
|
GetNodes().ForEach( pStt->GetNode(), aTmpEnd.GetNode(), sw::DocumentContentOperationsManager::lcl_RstTextAttr, &aPara );
|
|
}
|
|
|
|
getIDocumentState().SetModified();
|
|
|
|
oDataChanged.reset(); //before 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 (!SwModule::get()->GetModuleConfig()->IsStoreRsid())
|
|
return;
|
|
|
|
SwTextNode *pTextNode = rRg.GetPoint()->GetNode().GetTextNode();
|
|
if (!pTextNode)
|
|
{
|
|
return;
|
|
}
|
|
const sal_Int32 nStart(rRg.GetPoint()->GetContentIndex() - nLen);
|
|
SvxRsidItem aRsid( mnRsid, RES_CHRATR_RSID );
|
|
|
|
SfxItemSetFixed<RES_CHRATR_RSID, RES_CHRATR_RSID> aSet(GetAttrPool());
|
|
aSet.Put(aRsid);
|
|
bool const bRet(pTextNode->SetAttr(aSet, nStart,
|
|
rRg.GetPoint()->GetContentIndex()));
|
|
|
|
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 (!SwModule::get()->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 );
|
|
}
|
|
|
|
// If the format is a shape, and it has a textbox, sync.
|
|
auto pShapeFormat = dynamic_cast<SwFrameFormat*>(&rFormat);
|
|
if (pShapeFormat && SwTextBoxHelper::isTextBox(pShapeFormat, RES_DRAWFRMFMT))
|
|
{
|
|
if (auto pObj = pShapeFormat->FindRealSdrObject())
|
|
{
|
|
SwTextBoxHelper::syncFlyFrameAttr(*pShapeFormat, rSet, pObj);
|
|
SwTextBoxHelper::changeAnchor(pShapeFormat, pObj);
|
|
}
|
|
}
|
|
|
|
getIDocumentState().SetModified();
|
|
}
|
|
|
|
void SwDoc::ResetAttrAtFormat( const std::vector<sal_uInt16>& rIds,
|
|
SwFormat& rChangedFormat )
|
|
{
|
|
std::unique_ptr<SwUndo> pUndo;
|
|
if (GetIDocumentUndoRedo().DoesUndo())
|
|
pUndo.reset(new SwUndoFormatResetAttr( rChangedFormat, rIds ));
|
|
|
|
bool bAttrReset = false;
|
|
for (const auto& nWhichId : rIds)
|
|
bAttrReset = rChangedFormat.ResetFormatAttr(nWhichId) || bAttrReset;
|
|
|
|
if ( bAttrReset )
|
|
{
|
|
if ( pUndo )
|
|
{
|
|
GetIDocumentUndoRedo().AppendUndo( std::move(pUndo) );
|
|
}
|
|
|
|
getIDocumentState().SetModified();
|
|
}
|
|
}
|
|
|
|
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;
|
|
|
|
sw::BroadcastingModify aCallMod;
|
|
SwAttrSet aOld( GetAttrPool(), rSet.GetRanges() ),
|
|
aNew( GetAttrPool(), rSet.GetRanges() );
|
|
SfxItemIter aIter( rSet );
|
|
const SfxPoolItem* pItem = aIter.GetCurItem();
|
|
SfxItemPool* pSdrPool = GetAttrPool().GetSecondaryPool();
|
|
do
|
|
{
|
|
bool bCheckSdrDflt = false;
|
|
const sal_uInt16 nWhich = pItem->Which();
|
|
aOld.Put( GetAttrPool().GetUserOrPoolDefaultItem( nWhich ) );
|
|
GetAttrPool().SetUserDefaultItem( *pItem );
|
|
aNew.Put( GetAttrPool().GetUserOrPoolDefaultItem( nWhich ) );
|
|
|
|
if (isCHRATR(nWhich) || isTXTATR(nWhich))
|
|
{
|
|
aCallMod.Add(*mpDfltTextFormatColl);
|
|
aCallMod.Add(*mpDfltCharFormat);
|
|
bCheckSdrDflt = nullptr != pSdrPool;
|
|
}
|
|
else if ( isPARATR(nWhich) ||
|
|
isPARATR_LIST(nWhich) )
|
|
{
|
|
aCallMod.Add(*mpDfltTextFormatColl);
|
|
bCheckSdrDflt = nullptr != pSdrPool;
|
|
}
|
|
else if (isGRFATR(nWhich))
|
|
{
|
|
aCallMod.Add(*mpDfltGrfFormatColl);
|
|
}
|
|
else if (isFRMATR(nWhich) || isDrawingLayerAttribute(nWhich) )
|
|
{
|
|
aCallMod.Add(*mpDfltGrfFormatColl);
|
|
aCallMod.Add(*mpDfltTextFormatColl);
|
|
aCallMod.Add(*mpDfltFrameFormat);
|
|
}
|
|
else if (isBOXATR(nWhich))
|
|
{
|
|
aCallMod.Add(*mpDfltFrameFormat);
|
|
}
|
|
|
|
// also copy the defaults
|
|
if( bCheckSdrDflt )
|
|
{
|
|
sal_uInt16 nSlotId = GetAttrPool().GetSlotId( nWhich );
|
|
if( 0 != nSlotId && nSlotId != nWhich )
|
|
{
|
|
sal_uInt16 nEdtWhich = pSdrPool->GetWhichIDFromSlotID( nSlotId );
|
|
if( 0 != nEdtWhich && nSlotId != nEdtWhich )
|
|
{
|
|
std::unique_ptr<SfxPoolItem> pCpy(pItem->Clone());
|
|
pCpy->SetWhich( nEdtWhich );
|
|
pSdrPool->SetUserDefaultItem( *pCpy );
|
|
}
|
|
}
|
|
}
|
|
|
|
pItem = aIter.NextItem();
|
|
} while (pItem);
|
|
|
|
if( aNew.Count() && aCallMod.HasWriterListeners() )
|
|
{
|
|
if (GetIDocumentUndoRedo().DoesUndo())
|
|
{
|
|
GetIDocumentUndoRedo().AppendUndo( std::make_unique<SwUndoDefaultAttr>( aOld, *this ) );
|
|
}
|
|
|
|
const SvxTabStopItem* pTmpItem = aNew.GetItemIfSet( RES_PARATR_TABSTOP, false );
|
|
if( pTmpItem && 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 = (*pTmpItem)[ 0 ].GetTabPos(),
|
|
nOldWidth = aOld.Get(RES_PARATR_TABSTOP)[ 0 ].GetTabPos();
|
|
|
|
bool bChg = false;
|
|
ForEachParaAtrTabStopItem([&bChg, &nOldWidth, &nNewWidth](const SvxTabStopItem& rTabStopItem) -> bool {
|
|
// pItem2 and thus pTabStopItem is a evtl. shared & RefCounted
|
|
// Item and *should* not be changed that way. lcl_SetNewDefTabStops
|
|
// seems to change pTabStopItem (!). This may need to be changed
|
|
// to use iterateItemSurrogates and a defined write cycle.
|
|
bChg |= lcl_SetNewDefTabStops( nOldWidth, nNewWidth,
|
|
const_cast<SvxTabStopItem&>(rTabStopItem) );
|
|
return true;
|
|
});
|
|
|
|
aNew.ClearItem( RES_PARATR_TABSTOP );
|
|
aOld.ClearItem( RES_PARATR_TABSTOP );
|
|
if( bChg )
|
|
{
|
|
SwFormatChangeHint aChgFormat( mpDfltCharFormat.get(), mpDfltCharFormat.get() );
|
|
// notify the frames
|
|
aCallMod.CallSwClientNotify(aChgFormat);
|
|
}
|
|
}
|
|
}
|
|
|
|
if( aNew.Count() && aCallMod.HasWriterListeners() )
|
|
{
|
|
SwAttrSetChg aChgOld( aOld, aOld );
|
|
SwAttrSetChg aChgNew( aNew, aNew );
|
|
aCallMod.CallSwClientNotify(sw::LegacyModifyHint( &aChgOld, &aChgNew )); // all changed are sent
|
|
}
|
|
|
|
// remove the default formats from the object again
|
|
SwIterator<SwClient, sw::BroadcastingModify> 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().GetUserOrPoolDefaultItem( 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())
|
|
{
|
|
GetIDocumentUndoRedo().AppendUndo(
|
|
std::make_unique<SwUndoCharFormatDelete>(pDel, *this));
|
|
}
|
|
|
|
// tdf#140061 keep SwCharFormat instances alive while SwDoc is alive
|
|
mpCharFormatDeletionTable->insert(pDel);
|
|
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 )
|
|
{
|
|
assert(pFormat && "ContainsFormat will always deref pFormat");
|
|
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())
|
|
{
|
|
GetIDocumentUndoRedo().AppendUndo(
|
|
std::make_unique<SwUndoFrameFormatDelete>(pFormat, *this));
|
|
}
|
|
|
|
mpFrameFormatTable->erase( pFormat );
|
|
delete pFormat;
|
|
}
|
|
else
|
|
{
|
|
auto pSpz = static_cast<sw::SpzFrameFormat*>(pFormat);
|
|
if(GetSpzFrameFormats()->ContainsFormat(pSpz))
|
|
{
|
|
GetSpzFrameFormats()->erase(pSpz);
|
|
delete pSpz;
|
|
}
|
|
else
|
|
SAL_WARN("sw", "FrameFormat not found.");
|
|
}
|
|
}
|
|
}
|
|
|
|
void SwDoc::DelTableFrameFormat( SwTableFormat *pFormat )
|
|
{
|
|
auto it = mpTableFrameFormatTable->find( pFormat );
|
|
OSL_ENSURE( it != mpTableFrameFormatTable->end(), "Format not found," );
|
|
mpTableFrameFormatTable->erase( it );
|
|
delete pFormat;
|
|
}
|
|
|
|
SwFrameFormat* SwDoc::FindFrameFormatByName( const OUString& rName ) const
|
|
{
|
|
return static_cast<SwFrameFormat*>(mpFrameFormatTable->FindFormatByName(rName));
|
|
}
|
|
|
|
/// 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();
|
|
return std::count_if(mpTableFrameFormatTable->begin(), mpTableFrameFormatTable->end(),
|
|
std::mem_fn(&SwFormat::IsUsed));
|
|
}
|
|
|
|
SwTableFormat& SwDoc::GetTableFrameFormat(size_t nFormat, bool bUsed) const
|
|
{
|
|
if (!bUsed)
|
|
return *const_cast<SwTableFormat*>((*mpTableFrameFormatTable)[nFormat]);
|
|
for(SwTableFormat* pFormat: *mpTableFrameFormatTable)
|
|
{
|
|
if(!pFormat->IsUsed())
|
|
continue;
|
|
if(nFormat)
|
|
--nFormat;
|
|
else
|
|
return *pFormat;
|
|
}
|
|
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 bAuto)
|
|
{
|
|
SwFrameFormat *pFormat = new SwFrameFormat( GetAttrPool(), rFormatName, pDerivedFrom );
|
|
|
|
pFormat->SetAuto(bAuto);
|
|
mpFrameFormatTable->push_back( pFormat );
|
|
getIDocumentState().SetModified();
|
|
|
|
if (GetIDocumentUndoRedo().DoesUndo())
|
|
{
|
|
GetIDocumentUndoRedo().AppendUndo(
|
|
std::make_unique<SwUndoFrameFormatCreate>(pFormat, pDerivedFrom, *this));
|
|
}
|
|
|
|
return pFormat;
|
|
}
|
|
|
|
SwFormat *SwDoc::MakeFrameFormat_(const OUString &rFormatName,
|
|
SwFormat *pDerivedFrom,
|
|
bool bAuto)
|
|
{
|
|
SwFrameFormat *pFrameFormat = dynamic_cast<SwFrameFormat*>(pDerivedFrom);
|
|
pFrameFormat = MakeFrameFormat( rFormatName, pFrameFormat, bAuto );
|
|
return pFrameFormat;
|
|
}
|
|
|
|
SwCharFormat *SwDoc::MakeCharFormat( const OUString &rFormatName,
|
|
SwCharFormat *pDerivedFrom )
|
|
{
|
|
SwCharFormat *pFormat = new SwCharFormat( GetAttrPool(), rFormatName, pDerivedFrom );
|
|
mpCharFormatTable->insert( pFormat );
|
|
pFormat->SetAuto(false);
|
|
getIDocumentState().SetModified();
|
|
|
|
if (GetIDocumentUndoRedo().DoesUndo())
|
|
{
|
|
GetIDocumentUndoRedo().AppendUndo(
|
|
std::make_unique<SwUndoCharFormatCreate>(pFormat, pDerivedFrom, *this));
|
|
}
|
|
|
|
return pFormat;
|
|
}
|
|
|
|
SwFormat *SwDoc::MakeCharFormat_(const OUString &rFormatName,
|
|
SwFormat *pDerivedFrom,
|
|
bool /*bAuto*/)
|
|
{
|
|
SwCharFormat *pCharFormat = dynamic_cast<SwCharFormat*>(pDerivedFrom);
|
|
pCharFormat = MakeCharFormat( rFormatName, pCharFormat );
|
|
return pCharFormat;
|
|
}
|
|
|
|
/// Create the FormatCollections
|
|
SwTextFormatColl* SwDoc::MakeTextFormatColl( const OUString &rFormatName,
|
|
SwTextFormatColl *pDerivedFrom)
|
|
{
|
|
SwTextFormatColl *pFormatColl = new SwTextFormatColl( GetAttrPool(), rFormatName,
|
|
pDerivedFrom );
|
|
mpTextFormatCollTable->push_back(pFormatColl);
|
|
pFormatColl->SetAuto(false);
|
|
getIDocumentState().SetModified();
|
|
|
|
if (GetIDocumentUndoRedo().DoesUndo())
|
|
{
|
|
GetIDocumentUndoRedo().AppendUndo(
|
|
std::make_unique<SwUndoTextFormatCollCreate>(pFormatColl, pDerivedFrom,
|
|
*this));
|
|
}
|
|
|
|
return pFormatColl;
|
|
}
|
|
|
|
SwFormat *SwDoc::MakeTextFormatColl_(const OUString &rFormatName,
|
|
SwFormat *pDerivedFrom,
|
|
bool /*bAuto*/)
|
|
{
|
|
SwTextFormatColl *pTextFormatColl = dynamic_cast<SwTextFormatColl*>(pDerivedFrom);
|
|
pTextFormatColl = MakeTextFormatColl( rFormatName, pTextFormatColl );
|
|
return pTextFormatColl;
|
|
}
|
|
|
|
SwConditionTextFormatColl* SwDoc::MakeCondTextFormatColl( const OUString &rFormatName,
|
|
SwTextFormatColl *pDerivedFrom)
|
|
{
|
|
SwConditionTextFormatColl*pFormatColl = new SwConditionTextFormatColl( GetAttrPool(),
|
|
rFormatName, pDerivedFrom );
|
|
mpTextFormatCollTable->push_back(pFormatColl);
|
|
pFormatColl->SetAuto(false);
|
|
getIDocumentState().SetModified();
|
|
|
|
if (GetIDocumentUndoRedo().DoesUndo())
|
|
{
|
|
GetIDocumentUndoRedo().AppendUndo(
|
|
std::make_unique<SwUndoCondTextFormatCollCreate>(pFormatColl, pDerivedFrom,
|
|
*this));
|
|
}
|
|
|
|
return pFormatColl;
|
|
}
|
|
|
|
// 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())
|
|
{
|
|
std::unique_ptr<SwUndoTextFormatCollDelete> pUndo;
|
|
if (RES_CONDTXTFMTCOLL == pDel->Which())
|
|
{
|
|
pUndo.reset(new SwUndoCondTextFormatCollDelete(pDel, *this));
|
|
}
|
|
else
|
|
{
|
|
pUndo.reset(new SwUndoTextFormatCollDelete(pDel, *this));
|
|
}
|
|
|
|
GetIDocumentUndoRedo().AppendUndo(std::move(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( SwNode* pNode, void* pArgs )
|
|
{
|
|
SwContentNode* pCNd = pNode->GetTextNode();
|
|
|
|
if( pCNd == nullptr)
|
|
return true;
|
|
|
|
sw::DocumentContentOperationsManager::ParaRstFormat* pPara = static_cast<sw::DocumentContentOperationsManager::ParaRstFormat*>(pArgs);
|
|
|
|
if (pPara->pLayout && pPara->pLayout->HasMergedParas())
|
|
{
|
|
if (pCNd->GetRedlineMergeFlag() == SwNode::Merge::Hidden)
|
|
{
|
|
return true;
|
|
}
|
|
if (pCNd->IsTextNode())
|
|
{
|
|
pCNd = sw::GetParaPropsNode(*pPara->pLayout, *pCNd);
|
|
}
|
|
}
|
|
|
|
SwTextFormatColl* pFormat = pPara->pFormatColl;
|
|
if ( pPara->bReset )
|
|
{
|
|
if (pCNd->IsTextNode() && pPara->bResetAllCharAttrs && pPara->pDelSet && pPara->pDelSet->Count())
|
|
{
|
|
//TODO: copy to select the text node completely
|
|
SwPosition aStart(*pCNd, 0);
|
|
SwPosition aEnd(*pCNd, pCNd->GetTextNode()->GetText().getLength());
|
|
sw::DocumentContentOperationsManager::ParaRstFormat aPara(
|
|
&aStart, &aEnd, pPara->pHistory, nullptr, pPara->pLayout);
|
|
aPara.pFormatColl = pPara->pFormatColl;
|
|
aPara.bReset = pPara->bReset;
|
|
// #i62675#
|
|
aPara.bResetListAttrs = pPara->bResetListAttrs;
|
|
aPara.bResetAllCharAttrs = pPara->bResetAllCharAttrs;
|
|
aPara.pDelSet = pPara->pDelSet;
|
|
sw::DocumentContentOperationsManager::lcl_RstTextAttr(pCNd, &aPara);
|
|
}
|
|
|
|
lcl_RstAttr(pCNd, pPara);
|
|
|
|
// #i62675# check, if paragraph style has changed
|
|
if ( pPara->bResetListAttrs &&
|
|
(pPara->bResetAllCharAttrs || pFormat != pCNd->GetFormatColl())
|
|
&& pCNd->GetTextNode()->IsInList() )
|
|
{
|
|
// Check, if the list style of the paragraph will change.
|
|
bool bChangeOfListStyleAtParagraph( true );
|
|
SwTextNode& rTNd(*pCNd->GetTextNode());
|
|
{
|
|
SwNumRule* pNumRuleAtParagraph(rTNd.GetNumRule());
|
|
if ( pNumRuleAtParagraph )
|
|
{
|
|
const SwNumRuleItem& rNumRuleItemAtParagraphStyle = pFormat->GetNumRule();
|
|
if ( rNumRuleItemAtParagraphStyle.GetValue() ==
|
|
pNumRuleAtParagraph->GetName() )
|
|
{
|
|
bChangeOfListStyleAtParagraph = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
std::optional<SwRegHistory> oRegH;
|
|
if (pPara->pHistory)
|
|
oRegH.emplace(&rTNd, rTNd, pPara->pHistory);
|
|
|
|
if ( bChangeOfListStyleAtParagraph )
|
|
{
|
|
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 );
|
|
}
|
|
else
|
|
{
|
|
// The List Level must be applied as direct formatting. The spec says:
|
|
// 19.495 The style:list-level attribute specifies the list level value
|
|
// of a list style that may be applied to any paragraph style.
|
|
// It does not directly specify the paragraph's list level value,
|
|
// but consumers can change the paragraph's list level value to the specified value
|
|
// when the paragraph style is applied.
|
|
pCNd->SetAttr(pFormat->GetFormatAttr(RES_PARATR_LIST_LEVEL));
|
|
}
|
|
}
|
|
}
|
|
|
|
// add to History so that old data is saved, if necessary
|
|
if( pPara->pHistory )
|
|
pPara->pHistory->AddColl(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,
|
|
const bool bResetAllCharAttrs,
|
|
SwRootFrame const*const pLayout)
|
|
{
|
|
SwDataChanged aTmp( rRg );
|
|
auto [pStt, pEnd] = rRg.StartEnd(); // SwPosition*
|
|
SwHistory* pHst = nullptr;
|
|
bool bRet = true;
|
|
|
|
if (GetIDocumentUndoRedo().DoesUndo())
|
|
{
|
|
std::unique_ptr<SwUndoFormatColl> pUndo(new SwUndoFormatColl( rRg, pFormat,
|
|
bReset,
|
|
bResetListAttrs ));
|
|
pHst = pUndo->GetHistory();
|
|
GetIDocumentUndoRedo().AppendUndo(std::move(pUndo));
|
|
}
|
|
|
|
std::shared_ptr<SfxItemSet> pDelSet;
|
|
sw::DocumentContentOperationsManager::ParaRstFormat aPara(
|
|
pStt, pEnd, pHst, nullptr, pLayout);
|
|
aPara.pFormatColl = pFormat;
|
|
aPara.bReset = bReset;
|
|
// #i62675#
|
|
aPara.bResetListAttrs = bResetListAttrs;
|
|
aPara.bResetAllCharAttrs = bResetAllCharAttrs;
|
|
if (bResetAllCharAttrs)
|
|
{
|
|
o3tl::sorted_vector<sal_uInt16> aAttribs;
|
|
pDelSet = sw::DocumentContentOperationsManager::lcl_createDelSet(*this);
|
|
aPara.pDelSet = pDelSet.get();
|
|
}
|
|
|
|
GetNodes().ForEach( pStt->GetNodeIndex(), pEnd->GetNodeIndex()+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, 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()) );
|
|
|
|
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
|
|
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 SwNumRuleItem* pItem = pNewColl->GetItemIfSet( RES_PARATR_NUMRULE,
|
|
false );
|
|
if( pItem )
|
|
{
|
|
const OUString& rName = pItem->GetValue();
|
|
if( !rName.isEmpty() )
|
|
{
|
|
const SwNumRule* pRule = rColl.GetDoc()->FindNumRulePtr( rName );
|
|
if( pRule && !pRule->IsAutoRule() )
|
|
{
|
|
SwNumRule* pDestRule = FindNumRulePtr( rName );
|
|
if( pDestRule )
|
|
pDestRule->Invalidate();
|
|
else
|
|
MakeNumRule( rName, pRule );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return pNewColl;
|
|
}
|
|
|
|
/// copy the graphic nodes
|
|
SwGrfFormatColl* SwDoc::CopyGrfColl( const SwGrfFormatColl& rColl )
|
|
{
|
|
SwGrfFormatColl* pNewColl = mpGrfFormatCollTable->FindFormatByName( 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 == rDestArr.FindFormatByName( pSrc->GetName() ) )
|
|
{
|
|
if( RES_CONDTXTFMTCOLL == pSrc->Which() )
|
|
MakeCondTextFormatColl( pSrc->GetName(), static_cast<SwTextFormatColl*>(&rDfltFormat) );
|
|
else
|
|
// #i40550#
|
|
(this->*fnCopyFormat)( pSrc->GetName(), &rDfltFormat, 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 = rDestArr.FindFormatByName( pSrc->GetName() );
|
|
pDest->SetAuto(false);
|
|
pDest->DelDiffs( *pSrc );
|
|
|
|
// #i94285#: existing <SwFormatPageDesc> instance, before copying attributes
|
|
const SwFormatPageDesc* pItem;
|
|
if( &GetAttrPool() != pSrc->GetAttrSet().GetPool()
|
|
&& (pItem = pSrc->GetAttrSet().GetItemIfSet( RES_PAGEDESC, false ))
|
|
&& pItem->GetPageDesc() )
|
|
{
|
|
SwFormatPageDesc aPageDesc( *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( rDestArr.FindFormatByName(
|
|
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*>(rDestArr.FindFormatByName( pSrcColl->GetNextTextFormatColl().GetName() )) );
|
|
|
|
if(pSrcColl->IsAssignedToListLevelOfOutlineStyle())
|
|
pDstColl->AssignToListLevelOfOutlineStyle(pSrcColl->GetAssignedOutlineStyleLevel());
|
|
|
|
if( RES_CONDTXTFMTCOLL == pSrc->Which() )
|
|
{
|
|
if (pDstColl->Which() != RES_CONDTXTFMTCOLL)
|
|
{
|
|
// Target already had a style with a matching name, but it's not a conditional
|
|
// style, then don't copy the conditions.
|
|
continue;
|
|
}
|
|
|
|
// Copy the conditions, but delete the old ones first!
|
|
static_cast<SwConditionTextFormatColl*>(pDstColl)->SetConditions(
|
|
static_cast<SwConditionTextFormatColl*>(pSrc)->GetCondColls() );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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!
|
|
std::unique_ptr<SfxPoolItem> pNewItem(pItem->Clone());
|
|
|
|
SwFrameFormat* pOldFormat;
|
|
if( bCpyHeader )
|
|
pOldFormat = pNewItem->StaticWhichCast(RES_HEADER).GetHeaderFormat();
|
|
else
|
|
pOldFormat = pNewItem->StaticWhichCast(RES_FOOTER).GetFooterFormat();
|
|
|
|
if( !pOldFormat )
|
|
return;
|
|
|
|
SwFrameFormat* pNewFormat = new SwFrameFormat( GetAttrPool(), u"CpyDesc"_ustr,
|
|
GetDfltFrameFormat() );
|
|
pNewFormat->CopyAttrs( *pOldFormat );
|
|
|
|
if( const SwFormatContent* pContent = pNewFormat->GetAttrSet().GetItemIfSet(
|
|
RES_CNTNT, false ) )
|
|
{
|
|
if( pContent->GetContentIdx() )
|
|
{
|
|
const SwNodes& rSrcNds = rSrcFormat.GetDoc()->GetNodes();
|
|
SwStartNode* pSttNd = SwNodes::MakeEmptySection( GetNodes().GetEndOfAutotext(),
|
|
bCpyHeader
|
|
? SwHeaderStartNode
|
|
: SwFooterStartNode );
|
|
const SwNode& rCSttNd = pContent->GetContentIdx()->GetNode();
|
|
SwNodeRange aRg( rCSttNd, SwNodeOffset(0), *rCSttNd.EndOfSectionNode() );
|
|
rSrcNds.Copy_( aRg, *pSttNd->EndOfSectionNode() );
|
|
rSrcFormat.GetDoc()->GetDocumentContentOperationsManager().CopyFlyInFlyImpl(aRg, nullptr, *pSttNd);
|
|
// TODO: investigate calling CopyWithFlyInFly?
|
|
SwPaM const source(aRg.aStart, aRg.aEnd);
|
|
SwPosition dest(*pSttNd);
|
|
sw::CopyBookmarks(source, dest);
|
|
pNewFormat->SetFormatAttr( SwFormatContent( pSttNd ));
|
|
}
|
|
else
|
|
pNewFormat->ResetFormatAttr( RES_CNTNT );
|
|
}
|
|
if( bCpyHeader )
|
|
pNewItem->StaticWhichCast(RES_HEADER).RegisterToFormat(*pNewFormat);
|
|
else
|
|
pNewItem->StaticWhichCast(RES_FOOTER).RegisterToFormat(*pNewFormat);
|
|
rDestFormat.SetFormatAttr( *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);
|
|
}
|
|
|
|
// Copy the stashed formats as well between the page descriptors...
|
|
for (bool bFirst : { true, false })
|
|
{
|
|
for (bool bLeft : { true, false })
|
|
{
|
|
for (bool bHeader : { true, false })
|
|
{
|
|
if (!bLeft && !bFirst)
|
|
continue;
|
|
|
|
// Copy format only if it exists
|
|
if (auto pStashedFormatSrc = rSrcDesc.GetStashedFrameFormat(bHeader, bLeft, bFirst))
|
|
{
|
|
if (pStashedFormatSrc->GetDoc() != this)
|
|
{
|
|
SwFrameFormat newFormat(GetAttrPool(), u"CopyDesc"_ustr, GetDfltFrameFormat());
|
|
|
|
SfxItemSet aAttrSet(pStashedFormatSrc->GetAttrSet());
|
|
aAttrSet.ClearItem(RES_HEADER);
|
|
aAttrSet.ClearItem(RES_FOOTER);
|
|
|
|
newFormat.DelDiffs(aAttrSet);
|
|
newFormat.SetFormatAttr(aAttrSet);
|
|
|
|
if (bHeader)
|
|
CopyHeader(*pStashedFormatSrc, newFormat);
|
|
else
|
|
CopyFooter(*pStashedFormatSrc, newFormat);
|
|
|
|
rDstDesc.StashFrameFormat(newFormat, bHeader, bLeft, bFirst);
|
|
}
|
|
else
|
|
{
|
|
rDstDesc.StashFrameFormat(*pStashedFormatSrc, bHeader, bLeft, bFirst);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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 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
|
|
// b) 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();
|
|
}
|
|
|
|
void SwDoc::MoveLeftMargin(const SwPaM& rPam, bool bRight, bool bModulus,
|
|
SwRootFrame const*const pLayout)
|
|
{
|
|
SwHistory* pHistory = nullptr;
|
|
if (GetIDocumentUndoRedo().DoesUndo())
|
|
{
|
|
std::unique_ptr<SwUndoMoveLeftMargin> pUndo(new SwUndoMoveLeftMargin( rPam, bRight,
|
|
bModulus ));
|
|
pHistory = &pUndo->GetHistory();
|
|
GetIDocumentUndoRedo().AppendUndo( std::move(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.GetNode() );
|
|
while( aIdx <= rEnd.GetNode() )
|
|
{
|
|
SwTextNode* pTNd = aIdx.GetNode().GetTextNode();
|
|
if( pTNd )
|
|
{
|
|
pTNd = sw::GetParaPropsNode(*pLayout, aIdx.GetNode());
|
|
SvxFirstLineIndentItem firstLine(pTNd->SwContentNode::GetAttr(RES_MARGIN_FIRSTLINE));
|
|
SvxTextLeftMarginItem leftMargin(pTNd->SwContentNode::GetAttr(RES_MARGIN_TEXTLEFT));
|
|
|
|
// #i93873# See also lcl_MergeListLevelIndentAsLRSpaceItem in thints.cxx
|
|
::sw::ListLevelIndents const indents(pTNd->AreListLevelIndentsApplicable());
|
|
if (indents != ::sw::ListLevelIndents::No)
|
|
{
|
|
const SwNumRule* pRule = pTNd->GetNumRule();
|
|
if ( pRule )
|
|
{
|
|
const int nListLevel = pTNd->GetActualListLevel();
|
|
if ( nListLevel >= 0 )
|
|
{
|
|
const SwNumFormat& rFormat = pRule->Get(o3tl::narrowing<sal_uInt16>(nListLevel));
|
|
if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
|
|
{
|
|
if (indents & ::sw::ListLevelIndents::LeftMargin)
|
|
{
|
|
leftMargin.SetTextLeft(
|
|
SvxIndentValue::twips(rFormat.GetIndentAt()));
|
|
}
|
|
if (indents & ::sw::ListLevelIndents::FirstLine)
|
|
{
|
|
firstLine.SetTextFirstLineOffset(SvxIndentValue{
|
|
static_cast<double>(rFormat.GetFirstLineIndent()),
|
|
rFormat.GetFirstLineIndentUnit() });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
tools::Long nNext = leftMargin.ResolveTextLeft({});
|
|
if( bModulus )
|
|
nNext = ( nNext / nDefDist ) * nDefDist;
|
|
|
|
if( bRight )
|
|
nNext += nDefDist;
|
|
else
|
|
if(nNext >0) // fdo#75936 set limit for decreasing indent
|
|
nNext -= nDefDist;
|
|
|
|
leftMargin.SetTextLeft(SvxIndentValue::twips(nNext));
|
|
|
|
SwRegHistory aRegH( pTNd, *pTNd, pHistory );
|
|
pTNd->SetAttr(firstLine);
|
|
pTNd->SetAttr(leftMargin);
|
|
aIdx = *sw::GetFirstAndLastNode(*pLayout, aIdx.GetNode()).second;
|
|
}
|
|
++aIdx;
|
|
}
|
|
getIDocumentState().SetModified();
|
|
}
|
|
|
|
bool SwDoc::DontExpandFormat( const SwPosition& rPos, bool bFlag )
|
|
{
|
|
bool bRet = false;
|
|
SwTextNode* pTextNd = rPos.GetNode().GetTextNode();
|
|
if( pTextNd )
|
|
{
|
|
bRet = pTextNd->DontExpandFormat( rPos.GetContentIndex(), bFlag );
|
|
if( bRet && GetIDocumentUndoRedo().DoesUndo() )
|
|
{
|
|
GetIDocumentUndoRedo().AppendUndo( std::make_unique<SwUndoDontExpandFormat>(rPos) );
|
|
}
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
SwTableBoxFormat* SwDoc::MakeTableBoxFormat()
|
|
{
|
|
SwTableBoxFormat* pFormat = new SwTableBoxFormat( GetAttrPool(), mpDfltFrameFormat.get() );
|
|
pFormat->SetFormatName("TableBox" + OUString::number(reinterpret_cast<sal_IntPtr>(pFormat)));
|
|
getIDocumentState().SetModified();
|
|
return pFormat;
|
|
}
|
|
|
|
SwTableLineFormat* SwDoc::MakeTableLineFormat()
|
|
{
|
|
SwTableLineFormat* pFormat = new SwTableLineFormat( GetAttrPool(), mpDfltFrameFormat.get() );
|
|
pFormat->SetFormatName("TableLine" + OUString::number(reinterpret_cast<sal_IntPtr>(pFormat)));
|
|
getIDocumentState().SetModified();
|
|
return pFormat;
|
|
}
|
|
|
|
void SwDoc::EnsureNumberFormatter()
|
|
{
|
|
if (mpNumberFormatter == nullptr)
|
|
{
|
|
LanguageType eLang = LANGUAGE_SYSTEM;
|
|
mpNumberFormatter = new SvNumberFormatter(comphelper::getProcessComponentContext(), eLang);
|
|
mpNumberFormatter->SetEvalDateFormat( NF_EVALDATEFORMAT_FORMAT_INTL );
|
|
if (!comphelper::IsFuzzing())
|
|
mpNumberFormatter->SetYear2000(
|
|
officecfg::Office::Common::DateFormat::TwoDigitYear::get());
|
|
};
|
|
}
|
|
|
|
SwTableNumFormatMerge::SwTableNumFormatMerge( const SwDoc& rSrc, SwDoc& rDest )
|
|
: pNFormat( nullptr )
|
|
{
|
|
// a different Doc -> Number formatter needs to be merged
|
|
if( &rSrc != &rDest )
|
|
{
|
|
SvNumberFormatter* pN = const_cast<SwDoc&>(rSrc).GetNumberFormatter( false );
|
|
if( pN )
|
|
{
|
|
pNFormat = rDest.GetNumberFormatter();
|
|
pNFormat->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.GetNode().GetTextNode();
|
|
assert(pTNd);
|
|
|
|
if (mbIsAutoFormatRedline)
|
|
{
|
|
// create the redline object
|
|
const SwTextFormatColl& rColl = *pTNd->GetTextColl();
|
|
SwRangeRedline* pRedl = new SwRangeRedline( RedlineType::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()->SetContent(pTNd->GetText().getLength());
|
|
// sw_redlinehide: don't need layout currently because the only caller
|
|
// passes in the properties node
|
|
assert(static_cast<SwTextFrame const*>(pTNd->getLayoutFrame(nullptr))->GetTextNodeForParaProps() == pTNd);
|
|
getIDocumentContentOperations().InsertItemSet( aPam, *pSet );
|
|
}
|
|
}
|
|
|
|
void SwDoc::SetFormatItemByAutoFormat( const SwPaM& rPam, const SfxItemSet& rSet )
|
|
{
|
|
SwTextNode* pTNd = rPam.GetPoint()->GetNode().GetTextNode();
|
|
assert(pTNd);
|
|
|
|
RedlineFlags eOld = getIDocumentRedlineAccess().GetRedlineFlags();
|
|
|
|
if (mbIsAutoFormatRedline)
|
|
{
|
|
// create the redline object
|
|
SwRangeRedline* pRedl = new SwRangeRedline( RedlineType::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()->GetContentIndex());
|
|
std::vector<WhichPair> whichIds;
|
|
SfxItemIter iter(rSet);
|
|
for (SfxPoolItem const* pItem = iter.GetCurItem(); pItem; pItem = iter.NextItem())
|
|
{
|
|
if (RES_CHRATR_BEGIN <= pItem->Which() && pItem->Which() < RES_CHRATR_END)
|
|
{ // tdf#162911 don't add items with static default like INETFMT
|
|
whichIds.push_back({pItem->Which(), pItem->Which()});
|
|
}
|
|
}
|
|
|
|
::std::optional<SfxItemSet> oCurrentSet;
|
|
if (!whichIds.empty())
|
|
{
|
|
// ITEM: Need to sort these due to ItemSet using unordered_set and
|
|
// WhichRangesContainer expect these sorted ascending
|
|
std::sort(whichIds.begin(), whichIds.end(), [](WhichPair& a, WhichPair& b) {return a.first < b.first;});
|
|
|
|
oCurrentSet.emplace(GetAttrPool(), WhichRangesContainer(whichIds.data(), whichIds.size()));
|
|
pTNd->GetParaAttr(*oCurrentSet, nEnd, nEnd);
|
|
for (const WhichPair& rPair : whichIds)
|
|
{ // yuk - want to explicitly set the pool defaults too :-/
|
|
oCurrentSet->Put(oCurrentSet->Get(rPair.first));
|
|
}
|
|
}
|
|
|
|
getIDocumentContentOperations().InsertItemSet( rPam, rSet, SetAttrMode::DONTEXPAND );
|
|
|
|
if (!whichIds.empty())
|
|
{
|
|
// 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, *oCurrentSet);
|
|
}
|
|
|
|
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);
|
|
|
|
for (const SfxPoolItem* pItem = aIter.GetCurItem(); pItem; pItem = aIter.NextItem())
|
|
{
|
|
aOldSet.InvalidateItem(pItem->Which());
|
|
}
|
|
}
|
|
|
|
GetIDocumentUndoRedo().AppendUndo(
|
|
std::make_unique<SwUndoFormatAttr>(std::move(aOldSet), rFormat, /*bSaveDrawPt*/true));
|
|
}
|
|
|
|
rFormat.SetFormatAttr(rSet);
|
|
}
|
|
|
|
void SwDoc::RenameFormat(SwFormat & rFormat, const OUString & sNewName,
|
|
bool bBroadcast)
|
|
{
|
|
SfxStyleFamily eFamily = SfxStyleFamily::All;
|
|
|
|
if (GetIDocumentUndoRedo().DoesUndo())
|
|
{
|
|
std::unique_ptr<SwUndo> pUndo;
|
|
|
|
switch (rFormat.Which())
|
|
{
|
|
case RES_CHRFMT:
|
|
pUndo.reset(new SwUndoRenameCharFormat(rFormat.GetName(), sNewName, *this));
|
|
eFamily = SfxStyleFamily::Char;
|
|
break;
|
|
case RES_TXTFMTCOLL:
|
|
pUndo.reset(new SwUndoRenameFormatColl(rFormat.GetName(), sNewName, *this));
|
|
eFamily = SfxStyleFamily::Para;
|
|
break;
|
|
case RES_FRMFMT:
|
|
pUndo.reset(new SwUndoRenameFrameFormat(rFormat.GetName(), sNewName, *this));
|
|
eFamily = SfxStyleFamily::Frame;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (pUndo)
|
|
{
|
|
GetIDocumentUndoRedo().AppendUndo(std::move(pUndo));
|
|
}
|
|
}
|
|
|
|
// name change means the o3tl::sorted_array is not property sorted
|
|
if (rFormat.Which() == RES_CHRFMT)
|
|
mpCharFormatTable->SetFormatNameAndReindex(static_cast<SwCharFormat*>(&rFormat), sNewName);
|
|
else
|
|
rFormat.SetFormatName(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);
|
|
(void)xmlTextWriterSetIndentString(pWriter, BAD_CAST(" "));
|
|
(void)xmlTextWriterStartDocument(pWriter, nullptr, nullptr, nullptr);
|
|
bOwns = true;
|
|
}
|
|
(void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwDoc"));
|
|
(void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
|
|
|
|
m_pNodes->dumpAsXml(pWriter);
|
|
m_PageDescs.dumpAsXml(pWriter);
|
|
maDBData.dumpAsXml(pWriter);
|
|
mpMarkManager->dumpAsXml(pWriter);
|
|
m_pContentControlManager->dumpAsXml(pWriter);
|
|
m_pUndoManager->dumpAsXml(pWriter);
|
|
m_pDocumentSettingManager->dumpAsXml(pWriter);
|
|
getIDocumentFieldsAccess().GetFieldTypes()->dumpAsXml(pWriter);
|
|
mpTextFormatCollTable->dumpAsXml(pWriter);
|
|
mpCharFormatTable->dumpAsXml(pWriter);
|
|
mpFrameFormatTable->dumpAsXml(pWriter, "frmFormatTable");
|
|
mpSpzFrameFormatTable->dumpAsXml(pWriter, "spzFrameFormatTable");
|
|
mpSectionFormatTable->dumpAsXml(pWriter);
|
|
mpTableFrameFormatTable->dumpAsXml(pWriter, "tableFrameFormatTable");
|
|
mpNumRuleTable->dumpAsXml(pWriter);
|
|
getIDocumentRedlineAccess().GetRedlineTable().dumpAsXml(pWriter);
|
|
getIDocumentRedlineAccess().GetExtraRedlineTable().dumpAsXml(pWriter);
|
|
if (const SdrModel* pModel = getIDocumentDrawModelAccess().GetDrawModel())
|
|
pModel->dumpAsXml(pWriter);
|
|
|
|
(void)xmlTextWriterStartElement(pWriter, BAD_CAST("mbModified"));
|
|
(void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(OString::boolean(getIDocumentState().IsModified()).getStr()));
|
|
(void)xmlTextWriterEndElement(pWriter);
|
|
|
|
(void)xmlTextWriterEndElement(pWriter);
|
|
if (bOwns)
|
|
{
|
|
(void)xmlTextWriterEndDocument(pWriter);
|
|
xmlFreeTextWriter(pWriter);
|
|
}
|
|
}
|
|
|
|
void SwDBData::dumpAsXml(xmlTextWriterPtr pWriter) const
|
|
{
|
|
(void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwDBData"));
|
|
|
|
(void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("sDataSource"), BAD_CAST(sDataSource.toUtf8().getStr()));
|
|
(void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("sCommand"), BAD_CAST(sCommand.toUtf8().getStr()));
|
|
(void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nCommandType"), BAD_CAST(OString::number(nCommandType).getStr()));
|
|
|
|
(void)xmlTextWriterEndElement(pWriter);
|
|
}
|
|
|
|
std::set<Color> SwDoc::GetDocColors()
|
|
{
|
|
std::set<Color> aDocColors;
|
|
SwAttrPool& rPool = GetAttrPool();
|
|
|
|
svx::DocumentColorHelper::queryColors<SvxColorItem>(RES_CHRATR_COLOR, &rPool, aDocColors);
|
|
svx::DocumentColorHelper::queryColors<SvxBrushItem>(RES_CHRATR_HIGHLIGHT, &rPool, aDocColors);
|
|
svx::DocumentColorHelper::queryColors<SvxBrushItem>(RES_CHRATR_BACKGROUND, &rPool, aDocColors);
|
|
|
|
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;
|
|
}
|
|
}
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|