1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <libxml/xmlwriter.h>
21 #include <hintids.hxx>
22 #include <svl/itemiter.hxx>
23 #include <svl/numformat.hxx>
24 #include <editeng/tstpitem.hxx>
25 #include <editeng/lrspitem.hxx>
26 #include <editeng/formatbreakitem.hxx>
27 #include <editeng/rsiditem.hxx>
28 #include <officecfg/Office/Common.hxx>
29 #include <osl/diagnose.h>
30 #include <svl/zforlist.hxx>
31 #include <svx/DocumentColorHelper.hxx>
32 #include <comphelper/processfactory.hxx>
33 #include <unotools/configmgr.hxx>
34 #include <sal/log.hxx>
35 #include <com/sun/star/i18n/WordType.hpp>
36 #include <com/sun/star/i18n/XBreakIterator.hpp>
37 #include <fmtpdsc.hxx>
38 #include <fmthdft.hxx>
39 #include <fmtcntnt.hxx>
41 #include <docfunc.hxx>
42 #include <drawdoc.hxx>
43 #include <MarkManager.hxx>
44 #include <IDocumentDrawModelAccess.hxx>
45 #include <IDocumentUndoRedo.hxx>
46 #include <DocumentContentOperationsManager.hxx>
47 #include <DocumentSettingManager.hxx>
48 #include <IDocumentFieldsAccess.hxx>
49 #include <IDocumentState.hxx>
50 #include <IDocumentLayoutAccess.hxx>
51 #include <IDocumentRedlineAccess.hxx>
52 #include <IDocumentStylePoolAccess.hxx>
53 #include <rootfrm.hxx>
58 #include <UndoCore.hxx>
59 #include <UndoAttribute.hxx>
60 #include <UndoInsert.hxx>
61 #include <pagedesc.hxx>
64 #include <txatbase.hxx>
65 #include <swtblfmt.hxx>
66 #include <charfmt.hxx>
69 #include <redline.hxx>
71 #include <fmtinfmt.hxx>
72 #include <breakit.hxx>
73 #include <SwUndoFmt.hxx>
74 #include <UndoManager.hxx>
75 #include <swmodule.hxx>
77 #include <frameformats.hxx>
78 #include <textboxhelper.hxx>
79 #include <textcontentcontrol.hxx>
84 using namespace ::com::sun::star::i18n
;
85 using namespace ::com::sun::star::uno
;
91 static void SetTextFormatCollNext( SwTextFormatColl
* pTextColl
, const SwTextFormatColl
* pDel
)
93 if ( &pTextColl
->GetNextTextFormatColl() == pDel
)
95 pTextColl
->SetNextTextFormatColl( *pTextColl
);
99 static bool lcl_RstAttr( SwNode
* pNd
, void* pArgs
)
101 const sw::DocumentContentOperationsManager::ParaRstFormat
* pPara
= static_cast<sw::DocumentContentOperationsManager::ParaRstFormat
*>(pArgs
);
102 SwContentNode
* pNode
= pNd
->GetContentNode();
103 if (pPara
&& pPara
->pLayout
&& pPara
->pLayout
->HasMergedParas()
104 && pNode
&& pNode
->GetRedlineMergeFlag() == SwNode::Merge::Hidden
)
108 if( pNode
&& pNode
->HasSwAttrSet() )
110 const bool bLocked
= pNode
->IsModifyLocked();
113 SwDoc
& rDoc
= pNode
->GetDoc();
115 // remove unused attribute RES_LR_SPACE
116 // add list attributes, except RES_PARATR_LIST_AUTOFMT
118 RES_PARATR_NUMRULE
, RES_PARATR_NUMRULE
,
119 RES_PARATR_LIST_BEGIN
, RES_PARATR_LIST_AUTOFMT
- 1,
120 RES_PAGEDESC
, RES_BREAK
,
121 RES_FRMATR_STYLE_NAME
, RES_FRMATR_CONDITIONAL_STYLE_NAME
> aSavedAttrsSet(rDoc
.GetAttrPool());
122 const SfxItemSet
* pAttrSetOfNode
= pNode
->GetpSwAttrSet();
124 std::vector
<sal_uInt16
> aClearWhichIds
;
125 // restoring all paragraph list attributes
127 SfxItemSetFixed
<RES_PARATR_LIST_BEGIN
, RES_PARATR_LIST_AUTOFMT
- 1> aListAttrSet( rDoc
.GetAttrPool() );
128 aListAttrSet
.Set(*pAttrSetOfNode
);
129 if ( aListAttrSet
.Count() )
131 aSavedAttrsSet
.Put(aListAttrSet
);
132 SfxItemIter
aIter( aListAttrSet
);
133 const SfxPoolItem
* pItem
= aIter
.GetCurItem();
136 aClearWhichIds
.push_back( pItem
->Which() );
137 pItem
= aIter
.NextItem();
142 if (auto pItem
= pAttrSetOfNode
->GetItemIfSet(RES_PARATR_NUMRULE
, false);
143 pItem
&& !pItem
->GetValue().isEmpty())
145 aSavedAttrsSet
.Put(*pItem
);
146 aClearWhichIds
.push_back(RES_PARATR_NUMRULE
);
148 if (auto pItem
= pAttrSetOfNode
->GetItemIfSet(RES_PAGEDESC
, false);
149 pItem
&& pItem
->GetPageDesc())
151 aSavedAttrsSet
.Put(*pItem
);
152 aClearWhichIds
.push_back(RES_PAGEDESC
);
154 if (auto pItem
= pAttrSetOfNode
->GetItemIfSet(RES_BREAK
, false);
155 pItem
&& pItem
->GetBreak() != SvxBreak::NONE
)
157 aSavedAttrsSet
.Put(*pItem
);
158 aClearWhichIds
.push_back(RES_BREAK
);
160 if (auto pItem
= pAttrSetOfNode
->GetItemIfSet(RES_FRMATR_STYLE_NAME
, false);
161 pItem
&& !pItem
->GetValue().isEmpty())
163 aSavedAttrsSet
.Put(*pItem
);
164 aClearWhichIds
.push_back(RES_FRMATR_STYLE_NAME
);
166 if (auto pItem
= pAttrSetOfNode
->GetItemIfSet(RES_FRMATR_CONDITIONAL_STYLE_NAME
, false);
167 pItem
&& !pItem
->GetValue().isEmpty())
169 aSavedAttrsSet
.Put(*pItem
);
170 aClearWhichIds
.push_back(RES_FRMATR_CONDITIONAL_STYLE_NAME
);
173 // do not clear items directly from item set and only clear to be kept
174 // attributes, if no deletion item set is found.
175 const bool bKeepAttributes
=
176 !pPara
|| !pPara
->pDelSet
|| pPara
->pDelSet
->Count() == 0;
177 if ( bKeepAttributes
)
179 pNode
->ResetAttr( aClearWhichIds
);
183 pNode
->UnlockModify();
187 SwRegHistory
aRegH( pNode
, *pNode
, pPara
->pHistory
);
189 if( pPara
->pDelSet
&& pPara
->pDelSet
->Count() )
191 OSL_ENSURE( !bKeepAttributes
,
192 "<lcl_RstAttr(..)> - certain attributes are kept, but not needed." );
193 SfxItemIter
aIter( *pPara
->pDelSet
);
194 for (const SfxPoolItem
* pItem
= aIter
.GetCurItem(); pItem
; pItem
= aIter
.NextItem())
196 if ( ( pItem
->Which() != RES_PAGEDESC
&&
197 pItem
->Which() != RES_BREAK
&&
198 pItem
->Which() != RES_FRMATR_STYLE_NAME
&&
199 pItem
->Which() != RES_FRMATR_CONDITIONAL_STYLE_NAME
&&
200 pItem
->Which() != RES_PARATR_NUMRULE
) ||
201 ( aSavedAttrsSet
.GetItemState( pItem
->Which(), false ) != SfxItemState::SET
) )
203 pNode
->ResetAttr( pItem
->Which() );
207 else if( pPara
->bResetAll
)
208 pNode
->ResetAllAttr();
210 pNode
->ResetAttr( RES_PARATR_BEGIN
, POOLATTR_END
- 1 );
213 pNode
->ResetAllAttr();
215 // only restore saved attributes, if needed
216 if (bKeepAttributes
&& aSavedAttrsSet
.Count())
220 pNode
->SetAttr(aSavedAttrsSet
);
223 pNode
->UnlockModify();
229 void SwDoc::RstTextAttrs(const SwPaM
&rRg
, bool bInclRefToxMark
,
230 bool bExactRange
, SwRootFrame
const*const pLayout
)
232 SwHistory
* pHst
= nullptr;
233 SwDataChanged
aTmp( rRg
);
234 if (GetIDocumentUndoRedo().DoesUndo())
236 std::unique_ptr
<SwUndoResetAttr
> pUndo(new SwUndoResetAttr( rRg
, RES_CHRFMT
));
237 pHst
= &pUndo
->GetHistory();
238 GetIDocumentUndoRedo().AppendUndo(std::move(pUndo
));
240 auto [pStart
, pEnd
] = rRg
.StartEnd(); // SwPosition*
241 sw::DocumentContentOperationsManager::ParaRstFormat
aPara(
242 pStart
, pEnd
, pHst
, nullptr, pLayout
);
243 aPara
.bInclRefToxMark
= bInclRefToxMark
;
244 aPara
.bExactRange
= bExactRange
;
245 GetNodes().ForEach( pStart
->GetNodeIndex(), pEnd
->GetNodeIndex()+1,
246 sw::DocumentContentOperationsManager::lcl_RstTextAttr
, &aPara
);
247 getIDocumentState().SetModified();
250 void SwDoc::ResetAttrs( const SwPaM
&rRg
,
252 const o3tl::sorted_vector
<sal_uInt16
> &rAttrs
,
253 const bool bSendDataChangedEvents
,
254 SwRootFrame
const*const pLayout
)
256 SwPaM
* pPam
= const_cast<SwPaM
*>(&rRg
);
257 std::optional
<SwPaM
> oExtraPaM
;
258 if( !bTextAttr
&& !rAttrs
.empty() && RES_TXTATR_END
> *(rAttrs
.begin()) )
263 SwTextNode
* pTextNd
= rRg
.GetPoint()->GetNode().GetTextNode();
267 oExtraPaM
.emplace( *rRg
.GetPoint() );
270 SwPosition
& rSt
= *pPam
->GetPoint();
271 sal_Int32 nMkPos
, nPtPos
= rSt
.GetContentIndex();
273 // Special case: if the Cursor is located within a URL attribute, we take over it's area
274 SwTextAttr
const*const pURLAttr(
275 pTextNd
->GetTextAttrAt(rSt
.GetContentIndex(), RES_TXTATR_INETFMT
));
276 if (pURLAttr
&& !pURLAttr
->GetINetFormat().GetValue().isEmpty())
278 nMkPos
= pURLAttr
->GetStart();
279 nPtPos
= *pURLAttr
->End();
283 assert(g_pBreakIt
&& g_pBreakIt
->GetBreakIter().is());
284 Boundary aBndry
= g_pBreakIt
->GetBreakIter()->getWordBoundary(
285 pTextNd
->GetText(), nPtPos
,
286 g_pBreakIt
->GetLocale( pTextNd
->GetLang( nPtPos
) ),
287 WordType::ANY_WORD
/*ANYWORD_IGNOREWHITESPACES*/,
290 if( aBndry
.startPos
< nPtPos
&& nPtPos
< aBndry
.endPos
)
292 nMkPos
= aBndry
.startPos
;
293 nPtPos
= aBndry
.endPos
;
297 nPtPos
= nMkPos
= rSt
.GetContentIndex();
299 pTextNd
->DontExpandFormat( nPtPos
);
303 rSt
.SetContent(nMkPos
);
305 pPam
->GetPoint()->SetContent(nPtPos
);
309 std::optional
< SwDataChanged
> oDataChanged
;
310 if ( bSendDataChangedEvents
)
312 oDataChanged
.emplace( *pPam
);
314 SwHistory
* pHst
= nullptr;
315 if (GetIDocumentUndoRedo().DoesUndo())
317 std::unique_ptr
<SwUndoResetAttr
> pUndo(new SwUndoResetAttr( rRg
,
318 bTextAttr
? sal_uInt16(RES_CONDTXTFMTCOLL
) : sal_uInt16(RES_TXTFMTCOLL
) ));
319 if( !rAttrs
.empty() )
321 pUndo
->SetAttrs( o3tl::sorted_vector(rAttrs
) );
323 pHst
= &pUndo
->GetHistory();
324 GetIDocumentUndoRedo().AppendUndo(std::move(pUndo
));
327 auto [pStart
, pEnd
] = pPam
->StartEnd(); // SwPosition*
328 sw::DocumentContentOperationsManager::ParaRstFormat
aPara(
329 pStart
, pEnd
, pHst
, nullptr, pLayout
);
331 // mst: not including META here; it seems attrs with CH_TXTATR are omitted
332 SfxItemSetFixed
<RES_CHRATR_BEGIN
, RES_CHRATR_END
- 1,
333 RES_TXTATR_INETFMT
, RES_TXTATR_UNKNOWN_CONTAINER
,
334 RES_PARATR_BEGIN
, RES_FRMATR_END
- 1,
335 RES_UNKNOWNATR_BEGIN
, RES_UNKNOWNATR_END
- 1>
336 aDelSet(GetAttrPool());
337 for( auto it
= rAttrs
.rbegin(); it
!= rAttrs
.rend(); ++it
)
339 if( POOLATTR_END
> *it
)
340 aDelSet
.Put( *GetDfltAttr( *it
));
342 if( aDelSet
.Count() )
343 aPara
.pDelSet
= &aDelSet
;
346 SwNodeIndex
aTmpStt( pStart
->GetNode() );
347 SwNodeIndex
aTmpEnd( pEnd
->GetNode() );
348 if( pStart
->GetContentIndex() ) // just one part
350 // set up a later, and all CharFormatAttr -> TextFormatAttr
351 SwTextNode
* pTNd
= aTmpStt
.GetNode().GetTextNode();
352 if( pTNd
&& pTNd
->HasSwAttrSet() && pTNd
->GetpSwAttrSet()->Count() )
356 SwRegHistory
history(pTNd
, *pTNd
, pHst
);
357 pTNd
->FormatToTextAttr(pTNd
);
361 pTNd
->FormatToTextAttr(pTNd
);
367 if (!pEnd
->GetNode().IsContentNode()
368 || pEnd
->GetContentIndex() == pEnd
->GetNode().GetContentNode()->Len())
370 // set up a later, and all CharFormatAttr -> TextFormatAttr
374 else if( pStart
->GetNode() != pEnd
->GetNode() || !pStart
->GetContentIndex() )
376 SwTextNode
* pTNd
= aTmpEnd
.GetNode().GetTextNode();
377 if( pTNd
&& pTNd
->HasSwAttrSet() && pTNd
->GetpSwAttrSet()->Count() )
381 SwRegHistory
history(pTNd
, *pTNd
, pHst
);
382 pTNd
->FormatToTextAttr(pTNd
);
386 pTNd
->FormatToTextAttr(pTNd
);
391 if( aTmpStt
< aTmpEnd
)
392 GetNodes().ForEach( pStart
->GetNode(), aTmpEnd
.GetNode(), lcl_RstAttr
, &aPara
);
393 else if( !rRg
.HasMark() )
395 aPara
.bResetAll
= false ;
396 ::lcl_RstAttr( &pStart
->GetNode(), &aPara
);
397 aPara
.bResetAll
= true ;
404 GetNodes().ForEach( pStart
->GetNode(), aTmpEnd
.GetNode(), sw::DocumentContentOperationsManager::lcl_RstTextAttr
, &aPara
);
407 getIDocumentState().SetModified();
409 oDataChanged
.reset(); //before delete pPam
412 /// Set the rsid of the next nLen symbols of rRg to the current session number
413 void SwDoc::UpdateRsid( const SwPaM
&rRg
, const sal_Int32 nLen
)
415 if (!SwModule::get()->GetModuleConfig()->IsStoreRsid())
418 SwTextNode
*pTextNode
= rRg
.GetPoint()->GetNode().GetTextNode();
423 const sal_Int32
nStart(rRg
.GetPoint()->GetContentIndex() - nLen
);
424 SvxRsidItem
aRsid( mnRsid
, RES_CHRATR_RSID
);
426 SfxItemSetFixed
<RES_CHRATR_RSID
, RES_CHRATR_RSID
> aSet(GetAttrPool());
428 bool const bRet(pTextNode
->SetAttr(aSet
, nStart
,
429 rRg
.GetPoint()->GetContentIndex()));
431 if (bRet
&& GetIDocumentUndoRedo().DoesUndo())
433 SwUndo
*const pLastUndo
= GetUndoManager().GetLastUndo();
434 SwUndoInsert
*const pUndoInsert(dynamic_cast<SwUndoInsert
*>(pLastUndo
));
435 // this function is called after Insert so expects to find SwUndoInsert
439 pUndoInsert
->SetWithRsid();
444 bool SwDoc::UpdateParRsid( SwTextNode
*pTextNode
, sal_uInt32 nVal
)
446 if (!SwModule::get()->GetModuleConfig()->IsStoreRsid())
454 SvxRsidItem
aRsid( nVal
? nVal
: mnRsid
, RES_PARATR_RSID
);
455 return pTextNode
->SetAttr( aRsid
);
458 /// Set the attribute according to the stated format.
459 /// If Undo is enabled, the old values is added to the Undo history.
460 void SwDoc::SetAttr( const SfxPoolItem
& rAttr
, SwFormat
& rFormat
)
462 SfxItemSet
aSet( GetAttrPool(), rAttr
.Which(), rAttr
.Which() );
464 SetAttr( aSet
, rFormat
);
467 /// Set the attribute according to the stated format.
468 /// If Undo is enabled, the old values is added to the Undo history.
469 void SwDoc::SetAttr( const SfxItemSet
& rSet
, SwFormat
& rFormat
)
471 if (GetIDocumentUndoRedo().DoesUndo())
473 SwUndoFormatAttrHelper
aTmp( rFormat
);
474 rFormat
.SetFormatAttr( rSet
);
475 if ( aTmp
.GetUndo() )
477 GetIDocumentUndoRedo().AppendUndo( aTmp
.ReleaseUndo() );
481 GetIDocumentUndoRedo().ClearRedo();
486 rFormat
.SetFormatAttr( rSet
);
489 // If the format is a shape, and it has a textbox, sync.
490 auto pShapeFormat
= dynamic_cast<SwFrameFormat
*>(&rFormat
);
491 if (pShapeFormat
&& SwTextBoxHelper::isTextBox(pShapeFormat
, RES_DRAWFRMFMT
))
493 if (auto pObj
= pShapeFormat
->FindRealSdrObject())
495 SwTextBoxHelper::syncFlyFrameAttr(*pShapeFormat
, rSet
, pObj
);
496 SwTextBoxHelper::changeAnchor(pShapeFormat
, pObj
);
500 getIDocumentState().SetModified();
503 void SwDoc::ResetAttrAtFormat( const std::vector
<sal_uInt16
>& rIds
,
504 SwFormat
& rChangedFormat
)
506 std::unique_ptr
<SwUndo
> pUndo
;
507 if (GetIDocumentUndoRedo().DoesUndo())
508 pUndo
.reset(new SwUndoFormatResetAttr( rChangedFormat
, rIds
));
510 bool bAttrReset
= false;
511 for (const auto& nWhichId
: rIds
)
512 bAttrReset
= rChangedFormat
.ResetFormatAttr(nWhichId
) || bAttrReset
;
518 GetIDocumentUndoRedo().AppendUndo( std::move(pUndo
) );
521 getIDocumentState().SetModified();
525 static bool lcl_SetNewDefTabStops( SwTwips nOldWidth
, SwTwips nNewWidth
,
526 SvxTabStopItem
& rChgTabStop
)
528 // Set the default values of all TabStops to the new value.
529 // Attention: we always work with the PoolAttribute here, so that
530 // we don't calculate the same value on the same TabStop (pooled!) for all sets.
531 // We send a FormatChg to modify.
533 sal_uInt16 nOldCnt
= rChgTabStop
.Count();
534 if( !nOldCnt
|| nOldWidth
== nNewWidth
)
537 // Find the default's beginning
539 for( n
= nOldCnt
; n
; --n
)
540 if( SvxTabAdjust::Default
!= rChgTabStop
[n
- 1].GetAdjustment() )
543 if( n
< nOldCnt
) // delete the DefTabStops
544 rChgTabStop
.Remove( n
, nOldCnt
- n
);
548 /// Set the attribute as new default attribute in this document.
549 /// If Undo is enabled, the old value is added to the Undo history.
550 void SwDoc::SetDefault( const SfxPoolItem
& rAttr
)
552 SfxItemSet
aSet( GetAttrPool(), rAttr
.Which(), rAttr
.Which() );
557 void SwDoc::SetDefault( const SfxItemSet
& rSet
)
562 sw::BroadcastingModify aCallMod
;
563 SwAttrSet
aOld( GetAttrPool(), rSet
.GetRanges() ),
564 aNew( GetAttrPool(), rSet
.GetRanges() );
565 SfxItemIter
aIter( rSet
);
566 const SfxPoolItem
* pItem
= aIter
.GetCurItem();
567 SfxItemPool
* pSdrPool
= GetAttrPool().GetSecondaryPool();
570 bool bCheckSdrDflt
= false;
571 const sal_uInt16 nWhich
= pItem
->Which();
572 aOld
.Put( GetAttrPool().GetUserOrPoolDefaultItem( nWhich
) );
573 GetAttrPool().SetUserDefaultItem( *pItem
);
574 aNew
.Put( GetAttrPool().GetUserOrPoolDefaultItem( nWhich
) );
576 if (isCHRATR(nWhich
) || isTXTATR(nWhich
))
578 aCallMod
.Add(*mpDfltTextFormatColl
);
579 aCallMod
.Add(*mpDfltCharFormat
);
580 bCheckSdrDflt
= nullptr != pSdrPool
;
582 else if ( isPARATR(nWhich
) ||
583 isPARATR_LIST(nWhich
) )
585 aCallMod
.Add(*mpDfltTextFormatColl
);
586 bCheckSdrDflt
= nullptr != pSdrPool
;
588 else if (isGRFATR(nWhich
))
590 aCallMod
.Add(*mpDfltGrfFormatColl
);
592 else if (isFRMATR(nWhich
) || isDrawingLayerAttribute(nWhich
) )
594 aCallMod
.Add(*mpDfltGrfFormatColl
);
595 aCallMod
.Add(*mpDfltTextFormatColl
);
596 aCallMod
.Add(*mpDfltFrameFormat
);
598 else if (isBOXATR(nWhich
))
600 aCallMod
.Add(*mpDfltFrameFormat
);
603 // also copy the defaults
606 sal_uInt16 nSlotId
= GetAttrPool().GetSlotId( nWhich
);
607 if( 0 != nSlotId
&& nSlotId
!= nWhich
)
609 sal_uInt16 nEdtWhich
= pSdrPool
->GetWhichIDFromSlotID( nSlotId
);
610 if( 0 != nEdtWhich
&& nSlotId
!= nEdtWhich
)
612 std::unique_ptr
<SfxPoolItem
> pCpy(pItem
->Clone());
613 pCpy
->SetWhich( nEdtWhich
);
614 pSdrPool
->SetUserDefaultItem( *pCpy
);
619 pItem
= aIter
.NextItem();
622 if( aNew
.Count() && aCallMod
.HasWriterListeners() )
624 if (GetIDocumentUndoRedo().DoesUndo())
626 GetIDocumentUndoRedo().AppendUndo( std::make_unique
<SwUndoDefaultAttr
>( aOld
, *this ) );
629 const SvxTabStopItem
* pTmpItem
= aNew
.GetItemIfSet( RES_PARATR_TABSTOP
, false );
630 if( pTmpItem
&& pTmpItem
->Count() )
632 // Set the default values of all TabStops to the new value.
633 // Attention: we always work with the PoolAttribute here, so that
634 // we don't calculate the same value on the same TabStop (pooled!) for all sets.
635 // We send a FormatChg to modify.
636 SwTwips nNewWidth
= (*pTmpItem
)[ 0 ].GetTabPos(),
637 nOldWidth
= aOld
.Get(RES_PARATR_TABSTOP
)[ 0 ].GetTabPos();
640 ForEachParaAtrTabStopItem([&bChg
, &nOldWidth
, &nNewWidth
](const SvxTabStopItem
& rTabStopItem
) -> bool {
641 // pItem2 and thus pTabStopItem is a evtl. shared & RefCounted
642 // Item and *should* not be changed that way. lcl_SetNewDefTabStops
643 // seems to change pTabStopItem (!). This may need to be changed
644 // to use iterateItemSurrogates and a defined write cycle.
645 bChg
|= lcl_SetNewDefTabStops( nOldWidth
, nNewWidth
,
646 const_cast<SvxTabStopItem
&>(rTabStopItem
) );
650 aNew
.ClearItem( RES_PARATR_TABSTOP
);
651 aOld
.ClearItem( RES_PARATR_TABSTOP
);
654 SwFormatChangeHint
aChgFormat( mpDfltCharFormat
.get(), mpDfltCharFormat
.get() );
656 aCallMod
.CallSwClientNotify(aChgFormat
);
661 if( aNew
.Count() && aCallMod
.HasWriterListeners() )
663 SwAttrSetChg
aChgOld( aOld
, aOld
);
664 SwAttrSetChg
aChgNew( aNew
, aNew
);
665 aCallMod
.CallSwClientNotify(sw::LegacyModifyHint( &aChgOld
, &aChgNew
)); // all changed are sent
668 // remove the default formats from the object again
669 SwIterator
<SwClient
, sw::BroadcastingModify
> aClientIter(aCallMod
);
670 for(SwClient
* pClient
= aClientIter
.First(); pClient
; pClient
= aClientIter
.Next())
671 aCallMod
.Remove(*pClient
);
673 getIDocumentState().SetModified();
676 /// Get the default attribute in this document
677 const SfxPoolItem
& SwDoc::GetDefault( sal_uInt16 nFormatHint
) const
679 return GetAttrPool().GetUserOrPoolDefaultItem( nFormatHint
);
682 /// Delete the formats
683 void SwDoc::DelCharFormat(size_t nFormat
, bool bBroadcast
)
685 SwCharFormat
* pDel
= (*mpCharFormatTable
)[nFormat
];
688 BroadcastStyleOperation(pDel
->GetName(), SfxStyleFamily::Char
,
689 SfxHintId::StyleSheetErased
);
691 if (GetIDocumentUndoRedo().DoesUndo())
693 GetIDocumentUndoRedo().AppendUndo(
694 std::make_unique
<SwUndoCharFormatDelete
>(pDel
, *this));
697 // tdf#140061 keep SwCharFormat instances alive while SwDoc is alive
698 mpCharFormatDeletionTable
->insert(pDel
);
699 mpCharFormatTable
->erase(mpCharFormatTable
->begin() + nFormat
);
701 getIDocumentState().SetModified();
704 void SwDoc::DelCharFormat( SwCharFormat
const *pFormat
, bool bBroadcast
)
706 size_t nFormat
= mpCharFormatTable
->GetPos( pFormat
);
707 OSL_ENSURE( SIZE_MAX
!= nFormat
, "Format not found," );
708 DelCharFormat( nFormat
, bBroadcast
);
711 void SwDoc::DelFrameFormat( SwFrameFormat
*pFormat
, bool bBroadcast
)
713 assert(pFormat
&& "ContainsFormat will always deref pFormat");
714 if( dynamic_cast<const SwTableBoxFormat
*>( pFormat
) != nullptr || dynamic_cast<const SwTableLineFormat
*>( pFormat
) != nullptr )
716 OSL_ENSURE( false, "Format is not in the DocArray any more, "
717 "so it can be deleted with delete" );
722 // The format has to be in the one or the other, we'll see in which one.
723 if (mpFrameFormatTable
->ContainsFormat(pFormat
))
726 BroadcastStyleOperation(pFormat
->GetName(),
727 SfxStyleFamily::Frame
,
728 SfxHintId::StyleSheetErased
);
730 if (GetIDocumentUndoRedo().DoesUndo())
732 GetIDocumentUndoRedo().AppendUndo(
733 std::make_unique
<SwUndoFrameFormatDelete
>(pFormat
, *this));
736 mpFrameFormatTable
->erase( pFormat
);
741 auto pSpz
= static_cast<sw::SpzFrameFormat
*>(pFormat
);
742 if(GetSpzFrameFormats()->ContainsFormat(pSpz
))
744 GetSpzFrameFormats()->erase(pSpz
);
748 SAL_WARN("sw", "FrameFormat not found.");
753 void SwDoc::DelTableFrameFormat( SwTableFormat
*pFormat
)
755 auto it
= mpTableFrameFormatTable
->find( pFormat
);
756 OSL_ENSURE( it
!= mpTableFrameFormatTable
->end(), "Format not found," );
757 mpTableFrameFormatTable
->erase( it
);
761 SwFrameFormat
* SwDoc::FindFrameFormatByName( const OUString
& rName
) const
763 return static_cast<SwFrameFormat
*>(mpFrameFormatTable
->FindFormatByName(rName
));
766 /// Create the formats
767 SwFlyFrameFormat
*SwDoc::MakeFlyFrameFormat( const OUString
&rFormatName
,
768 SwFrameFormat
*pDerivedFrom
)
770 SwFlyFrameFormat
*pFormat
= new SwFlyFrameFormat( GetAttrPool(), rFormatName
, pDerivedFrom
);
771 GetSpzFrameFormats()->push_back(pFormat
);
772 getIDocumentState().SetModified();
776 SwDrawFrameFormat
*SwDoc::MakeDrawFrameFormat( const OUString
&rFormatName
,
777 SwFrameFormat
*pDerivedFrom
)
779 SwDrawFrameFormat
*pFormat
= new SwDrawFrameFormat( GetAttrPool(), rFormatName
, pDerivedFrom
);
780 GetSpzFrameFormats()->push_back(pFormat
);
781 getIDocumentState().SetModified();
785 size_t SwDoc::GetTableFrameFormatCount(bool bUsed
) const
788 return mpTableFrameFormatTable
->size();
789 return std::count_if(mpTableFrameFormatTable
->begin(), mpTableFrameFormatTable
->end(),
790 std::mem_fn(&SwFormat::IsUsed
));
793 SwTableFormat
& SwDoc::GetTableFrameFormat(size_t nFormat
, bool bUsed
) const
796 return *const_cast<SwTableFormat
*>((*mpTableFrameFormatTable
)[nFormat
]);
797 for(SwTableFormat
* pFormat
: *mpTableFrameFormatTable
)
799 if(!pFormat
->IsUsed())
806 throw std::out_of_range("Format index out of range.");
809 SwTableFormat
* SwDoc::MakeTableFrameFormat( const OUString
&rFormatName
,
810 SwFrameFormat
*pDerivedFrom
)
812 SwTableFormat
* pFormat
= new SwTableFormat( GetAttrPool(), rFormatName
, pDerivedFrom
);
813 mpTableFrameFormatTable
->push_back( pFormat
);
814 getIDocumentState().SetModified();
819 SwFrameFormat
*SwDoc::MakeFrameFormat(const OUString
&rFormatName
,
820 SwFrameFormat
*pDerivedFrom
,
823 SwFrameFormat
*pFormat
= new SwFrameFormat( GetAttrPool(), rFormatName
, pDerivedFrom
);
825 pFormat
->SetAuto(bAuto
);
826 mpFrameFormatTable
->push_back( pFormat
);
827 getIDocumentState().SetModified();
829 if (GetIDocumentUndoRedo().DoesUndo())
831 GetIDocumentUndoRedo().AppendUndo(
832 std::make_unique
<SwUndoFrameFormatCreate
>(pFormat
, pDerivedFrom
, *this));
838 SwFormat
*SwDoc::MakeFrameFormat_(const OUString
&rFormatName
,
839 SwFormat
*pDerivedFrom
,
842 SwFrameFormat
*pFrameFormat
= dynamic_cast<SwFrameFormat
*>(pDerivedFrom
);
843 pFrameFormat
= MakeFrameFormat( rFormatName
, pFrameFormat
, bAuto
);
847 SwCharFormat
*SwDoc::MakeCharFormat( const OUString
&rFormatName
,
848 SwCharFormat
*pDerivedFrom
)
850 SwCharFormat
*pFormat
= new SwCharFormat( GetAttrPool(), rFormatName
, pDerivedFrom
);
851 mpCharFormatTable
->insert( pFormat
);
852 pFormat
->SetAuto(false);
853 getIDocumentState().SetModified();
855 if (GetIDocumentUndoRedo().DoesUndo())
857 GetIDocumentUndoRedo().AppendUndo(
858 std::make_unique
<SwUndoCharFormatCreate
>(pFormat
, pDerivedFrom
, *this));
864 SwFormat
*SwDoc::MakeCharFormat_(const OUString
&rFormatName
,
865 SwFormat
*pDerivedFrom
,
868 SwCharFormat
*pCharFormat
= dynamic_cast<SwCharFormat
*>(pDerivedFrom
);
869 pCharFormat
= MakeCharFormat( rFormatName
, pCharFormat
);
873 /// Create the FormatCollections
874 SwTextFormatColl
* SwDoc::MakeTextFormatColl( const OUString
&rFormatName
,
875 SwTextFormatColl
*pDerivedFrom
)
877 SwTextFormatColl
*pFormatColl
= new SwTextFormatColl( GetAttrPool(), rFormatName
,
879 mpTextFormatCollTable
->push_back(pFormatColl
);
880 pFormatColl
->SetAuto(false);
881 getIDocumentState().SetModified();
883 if (GetIDocumentUndoRedo().DoesUndo())
885 GetIDocumentUndoRedo().AppendUndo(
886 std::make_unique
<SwUndoTextFormatCollCreate
>(pFormatColl
, pDerivedFrom
,
893 SwFormat
*SwDoc::MakeTextFormatColl_(const OUString
&rFormatName
,
894 SwFormat
*pDerivedFrom
,
897 SwTextFormatColl
*pTextFormatColl
= dynamic_cast<SwTextFormatColl
*>(pDerivedFrom
);
898 pTextFormatColl
= MakeTextFormatColl( rFormatName
, pTextFormatColl
);
899 return pTextFormatColl
;
902 SwConditionTextFormatColl
* SwDoc::MakeCondTextFormatColl( const OUString
&rFormatName
,
903 SwTextFormatColl
*pDerivedFrom
)
905 SwConditionTextFormatColl
*pFormatColl
= new SwConditionTextFormatColl( GetAttrPool(),
906 rFormatName
, pDerivedFrom
);
907 mpTextFormatCollTable
->push_back(pFormatColl
);
908 pFormatColl
->SetAuto(false);
909 getIDocumentState().SetModified();
911 if (GetIDocumentUndoRedo().DoesUndo())
913 GetIDocumentUndoRedo().AppendUndo(
914 std::make_unique
<SwUndoCondTextFormatCollCreate
>(pFormatColl
, pDerivedFrom
,
922 SwGrfFormatColl
* SwDoc::MakeGrfFormatColl( const OUString
&rFormatName
,
923 SwGrfFormatColl
*pDerivedFrom
)
925 SwGrfFormatColl
*pFormatColl
= new SwGrfFormatColl( GetAttrPool(), rFormatName
,
927 mpGrfFormatCollTable
->push_back( pFormatColl
);
928 pFormatColl
->SetAuto(false);
929 getIDocumentState().SetModified();
933 void SwDoc::DelTextFormatColl(size_t nFormatColl
, bool bBroadcast
)
935 OSL_ENSURE( nFormatColl
, "Remove of Coll 0." );
937 // Who has the to-be-deleted as their Next?
938 SwTextFormatColl
*pDel
= (*mpTextFormatCollTable
)[nFormatColl
];
939 if( mpDfltTextFormatColl
.get() == pDel
)
940 return; // never delete default!
943 BroadcastStyleOperation(pDel
->GetName(), SfxStyleFamily::Para
,
944 SfxHintId::StyleSheetErased
);
946 if (GetIDocumentUndoRedo().DoesUndo())
948 std::unique_ptr
<SwUndoTextFormatCollDelete
> pUndo
;
949 if (RES_CONDTXTFMTCOLL
== pDel
->Which())
951 pUndo
.reset(new SwUndoCondTextFormatCollDelete(pDel
, *this));
955 pUndo
.reset(new SwUndoTextFormatCollDelete(pDel
, *this));
958 GetIDocumentUndoRedo().AppendUndo(std::move(pUndo
));
961 // Remove the FormatColl
962 mpTextFormatCollTable
->erase(mpTextFormatCollTable
->begin() + nFormatColl
);
964 for( SwTextFormatColls::const_iterator it
= mpTextFormatCollTable
->begin() + 1; it
!= mpTextFormatCollTable
->end(); ++it
)
965 SetTextFormatCollNext( *it
, pDel
);
967 getIDocumentState().SetModified();
970 void SwDoc::DelTextFormatColl( SwTextFormatColl
const *pColl
, bool bBroadcast
)
972 size_t nFormat
= mpTextFormatCollTable
->GetPos( pColl
);
973 OSL_ENSURE( SIZE_MAX
!= nFormat
, "Collection not found," );
974 DelTextFormatColl( nFormat
, bBroadcast
);
977 static bool lcl_SetTextFormatColl( SwNode
* pNode
, void* pArgs
)
979 SwContentNode
* pCNd
= pNode
->GetTextNode();
984 sw::DocumentContentOperationsManager::ParaRstFormat
* pPara
= static_cast<sw::DocumentContentOperationsManager::ParaRstFormat
*>(pArgs
);
986 if (pPara
->pLayout
&& pPara
->pLayout
->HasMergedParas())
988 if (pCNd
->GetRedlineMergeFlag() == SwNode::Merge::Hidden
)
992 if (pCNd
->IsTextNode())
994 pCNd
= sw::GetParaPropsNode(*pPara
->pLayout
, *pCNd
);
998 SwTextFormatColl
* pFormat
= pPara
->pFormatColl
;
1001 if (pCNd
->IsTextNode() && pPara
->bResetAllCharAttrs
&& pPara
->pDelSet
&& pPara
->pDelSet
->Count())
1003 //TODO: copy to select the text node completely
1004 SwPosition
aStart(*pCNd
, 0);
1005 SwPosition
aEnd(*pCNd
, pCNd
->GetTextNode()->GetText().getLength());
1006 sw::DocumentContentOperationsManager::ParaRstFormat
aPara(
1007 &aStart
, &aEnd
, pPara
->pHistory
, nullptr, pPara
->pLayout
);
1008 aPara
.pFormatColl
= pPara
->pFormatColl
;
1009 aPara
.bReset
= pPara
->bReset
;
1011 aPara
.bResetListAttrs
= pPara
->bResetListAttrs
;
1012 aPara
.bResetAllCharAttrs
= pPara
->bResetAllCharAttrs
;
1013 aPara
.pDelSet
= pPara
->pDelSet
;
1014 sw::DocumentContentOperationsManager::lcl_RstTextAttr(pCNd
, &aPara
);
1017 lcl_RstAttr(pCNd
, pPara
);
1019 // #i62675# check, if paragraph style has changed
1020 if ( pPara
->bResetListAttrs
&&
1021 (pPara
->bResetAllCharAttrs
|| pFormat
!= pCNd
->GetFormatColl())
1022 && pCNd
->GetTextNode()->IsInList() )
1024 // Check, if the list style of the paragraph will change.
1025 bool bChangeOfListStyleAtParagraph( true );
1026 SwTextNode
& rTNd(*pCNd
->GetTextNode());
1028 SwNumRule
* pNumRuleAtParagraph(rTNd
.GetNumRule());
1029 if ( pNumRuleAtParagraph
)
1031 const SwNumRuleItem
& rNumRuleItemAtParagraphStyle
=
1032 rTNd
.GetTextColl()->GetNumRule();
1033 if ( rNumRuleItemAtParagraphStyle
.GetValue() ==
1034 pNumRuleAtParagraph
->GetName() )
1036 bChangeOfListStyleAtParagraph
= false;
1041 std::optional
<SwRegHistory
> oRegH
;
1042 if (pPara
->pHistory
)
1043 oRegH
.emplace(&rTNd
, rTNd
, pPara
->pHistory
);
1045 if ( bChangeOfListStyleAtParagraph
)
1047 pCNd
->ResetAttr( RES_PARATR_NUMRULE
);
1049 // reset all list attributes
1050 pCNd
->ResetAttr( RES_PARATR_LIST_LEVEL
);
1051 pCNd
->ResetAttr( RES_PARATR_LIST_ISRESTART
);
1052 pCNd
->ResetAttr( RES_PARATR_LIST_RESTARTVALUE
);
1053 pCNd
->ResetAttr( RES_PARATR_LIST_ISCOUNTED
);
1054 pCNd
->ResetAttr( RES_PARATR_LIST_ID
);
1058 // The List Level must be applied as direct formatting. The spec says:
1059 // 19.495 The style:list-level attribute specifies the list level value
1060 // of a list style that may be applied to any paragraph style.
1061 // It does not directly specify the paragraph's list level value,
1062 // but consumers can change the paragraph's list level value to the specified value
1063 // when the paragraph style is applied.
1064 pCNd
->SetAttr(pFormat
->GetFormatAttr(RES_PARATR_LIST_LEVEL
));
1069 // add to History so that old data is saved, if necessary
1070 if( pPara
->pHistory
)
1071 pPara
->pHistory
->AddColl(pCNd
->GetFormatColl(), pCNd
->GetIndex(),
1074 pCNd
->ChgFormatColl( pFormat
);
1081 bool SwDoc::SetTextFormatColl(const SwPaM
&rRg
,
1082 SwTextFormatColl
*pFormat
,
1084 const bool bResetListAttrs
,
1085 const bool bResetAllCharAttrs
,
1086 SwRootFrame
const*const pLayout
)
1088 SwDataChanged
aTmp( rRg
);
1089 auto [pStart
, pEnd
] = rRg
.StartEnd(); // SwPosition*
1090 SwHistory
* pHst
= nullptr;
1093 if (GetIDocumentUndoRedo().DoesUndo())
1095 std::unique_ptr
<SwUndoFormatColl
> pUndo(new SwUndoFormatColl( rRg
, pFormat
,
1098 pHst
= pUndo
->GetHistory();
1099 GetIDocumentUndoRedo().AppendUndo(std::move(pUndo
));
1102 std::shared_ptr
<SfxItemSet
> pDelSet
;
1103 sw::DocumentContentOperationsManager::ParaRstFormat
aPara(
1104 pStart
, pEnd
, pHst
, nullptr, pLayout
);
1105 aPara
.pFormatColl
= pFormat
;
1106 aPara
.bReset
= bReset
;
1108 aPara
.bResetListAttrs
= bResetListAttrs
;
1109 aPara
.bResetAllCharAttrs
= bResetAllCharAttrs
;
1110 if (bResetAllCharAttrs
)
1112 o3tl::sorted_vector
<sal_uInt16
> aAttribs
;
1113 pDelSet
= sw::DocumentContentOperationsManager::lcl_createDelSet(*this);
1114 aPara
.pDelSet
= pDelSet
.get();
1117 GetNodes().ForEach( pStart
->GetNodeIndex(), pEnd
->GetNodeIndex()+1,
1118 lcl_SetTextFormatColl
, &aPara
);
1120 bRet
= false; // didn't find a valid Node
1124 getIDocumentState().SetModified();
1130 /// Copy the formats to itself
1131 SwFormat
* SwDoc::CopyFormat( const SwFormat
& rFormat
,
1132 const SwFormatsBase
& rFormatArr
,
1133 FNCopyFormat fnCopyFormat
, const SwFormat
& rDfltFormat
)
1135 // It's no autoformat, default format or collection format,
1136 // then search for it.
1137 if( !rFormat
.IsAuto() || !rFormat
.GetRegisteredIn() )
1138 for( size_t n
= 0; n
< rFormatArr
.GetFormatCount(); ++n
)
1140 // Does the Doc already contain the template?
1141 if( rFormatArr
.GetFormat(n
)->GetName()==rFormat
.GetName() )
1142 return rFormatArr
.GetFormat(n
);
1145 // Search for the "parent" first
1146 SwFormat
* pParent
= const_cast<SwFormat
*>(&rDfltFormat
);
1147 if( rFormat
.DerivedFrom() && pParent
!= rFormat
.DerivedFrom() )
1148 pParent
= CopyFormat( *rFormat
.DerivedFrom(), rFormatArr
,
1149 fnCopyFormat
, rDfltFormat
);
1151 // Create the format and copy the attributes
1153 SwFormat
* pNewFormat
= (this->*fnCopyFormat
)( rFormat
.GetName(), pParent
, true );
1154 pNewFormat
->SetAuto( rFormat
.IsAuto() );
1155 pNewFormat
->CopyAttrs( rFormat
); // copy the attributes
1157 pNewFormat
->SetPoolFormatId( rFormat
.GetPoolFormatId() );
1158 pNewFormat
->SetPoolHelpId( rFormat
.GetPoolHelpId() );
1160 // Always set the HelpFile Id to default!
1161 pNewFormat
->SetPoolHlpFileId( UCHAR_MAX
);
1166 /// copy the frame format
1167 SwFrameFormat
* SwDoc::CopyFrameFormat( const SwFrameFormat
& rFormat
)
1169 return static_cast<SwFrameFormat
*>(CopyFormat( rFormat
, *GetFrameFormats(), &SwDoc::MakeFrameFormat_
,
1170 *GetDfltFrameFormat() ));
1173 /// copy the char format
1174 SwCharFormat
* SwDoc::CopyCharFormat( const SwCharFormat
& rFormat
)
1176 return static_cast<SwCharFormat
*>(CopyFormat( rFormat
, *GetCharFormats(),
1177 &SwDoc::MakeCharFormat_
,
1178 *GetDfltCharFormat() ));
1182 SwTextFormatColl
* SwDoc::CopyTextColl( const SwTextFormatColl
& rColl
)
1184 SwTextFormatColl
* pNewColl
= FindTextFormatCollByName( rColl
.GetName() );
1188 // search for the "parent" first
1189 SwTextFormatColl
* pParent
= mpDfltTextFormatColl
.get();
1190 if( pParent
!= rColl
.DerivedFrom() )
1191 pParent
= CopyTextColl( *static_cast<SwTextFormatColl
*>(rColl
.DerivedFrom()) );
1193 if( RES_CONDTXTFMTCOLL
== rColl
.Which() )
1195 pNewColl
= new SwConditionTextFormatColl( GetAttrPool(), rColl
.GetName(),
1197 mpTextFormatCollTable
->push_back( pNewColl
);
1198 pNewColl
->SetAuto(false);
1199 getIDocumentState().SetModified();
1201 // copy the conditions
1202 static_cast<SwConditionTextFormatColl
*>(pNewColl
)->SetConditions(
1203 static_cast<const SwConditionTextFormatColl
&>(rColl
).GetCondColls() );
1206 pNewColl
= MakeTextFormatColl( rColl
.GetName(), pParent
);
1208 // copy the auto formats or the attributes
1209 pNewColl
->CopyAttrs( rColl
);
1211 if(rColl
.IsAssignedToListLevelOfOutlineStyle())
1212 pNewColl
->AssignToListLevelOfOutlineStyle(rColl
.GetAssignedOutlineStyleLevel());
1213 pNewColl
->SetPoolFormatId( rColl
.GetPoolFormatId() );
1214 pNewColl
->SetPoolHelpId( rColl
.GetPoolHelpId() );
1216 // Always set the HelpFile Id to default!
1217 pNewColl
->SetPoolHlpFileId( UCHAR_MAX
);
1219 if( &rColl
.GetNextTextFormatColl() != &rColl
)
1220 pNewColl
->SetNextTextFormatColl( *CopyTextColl( rColl
.GetNextTextFormatColl() ));
1222 // create the NumRule if necessary
1223 if( this != rColl
.GetDoc() )
1225 const SwNumRuleItem
* pItem
= pNewColl
->GetItemIfSet( RES_PARATR_NUMRULE
,
1229 const OUString
& rName
= pItem
->GetValue();
1230 if( !rName
.isEmpty() )
1232 const SwNumRule
* pRule
= rColl
.GetDoc()->FindNumRulePtr( rName
);
1233 if( pRule
&& !pRule
->IsAutoRule() )
1235 SwNumRule
* pDestRule
= FindNumRulePtr( rName
);
1237 pDestRule
->Invalidate();
1239 MakeNumRule( rName
, pRule
);
1247 /// copy the graphic nodes
1248 SwGrfFormatColl
* SwDoc::CopyGrfColl( const SwGrfFormatColl
& rColl
)
1250 SwGrfFormatColl
* pNewColl
= mpGrfFormatCollTable
->FindFormatByName( rColl
.GetName() );
1254 // Search for the "parent" first
1255 SwGrfFormatColl
* pParent
= mpDfltGrfFormatColl
.get();
1256 if( pParent
!= rColl
.DerivedFrom() )
1257 pParent
= CopyGrfColl( *static_cast<SwGrfFormatColl
*>(rColl
.DerivedFrom()) );
1259 // if not, copy them
1260 pNewColl
= MakeGrfFormatColl( rColl
.GetName(), pParent
);
1262 // copy the attributes
1263 pNewColl
->CopyAttrs( rColl
);
1265 pNewColl
->SetPoolFormatId( rColl
.GetPoolFormatId() );
1266 pNewColl
->SetPoolHelpId( rColl
.GetPoolHelpId() );
1268 // Always set the HelpFile Id to default!
1269 pNewColl
->SetPoolHlpFileId( UCHAR_MAX
);
1274 void SwDoc::CopyFormatArr( const SwFormatsBase
& rSourceArr
,
1275 SwFormatsBase
const & rDestArr
,
1276 FNCopyFormat fnCopyFormat
,
1277 SwFormat
& rDfltFormat
)
1279 SwFormat
* pSrc
, *pDest
;
1281 // 1st step: Create all formats (skip the 0th - it's the default one)
1282 for( size_t nSrc
= rSourceArr
.GetFormatCount(); nSrc
> 1; )
1284 pSrc
= rSourceArr
.GetFormat( --nSrc
);
1285 if( pSrc
->IsDefault() || pSrc
->IsAuto() )
1288 if( nullptr == rDestArr
.FindFormatByName( pSrc
->GetName() ) )
1290 if( RES_CONDTXTFMTCOLL
== pSrc
->Which() )
1291 MakeCondTextFormatColl( pSrc
->GetName(), static_cast<SwTextFormatColl
*>(&rDfltFormat
) );
1294 (this->*fnCopyFormat
)( pSrc
->GetName(), &rDfltFormat
, true );
1298 // 2nd step: Copy all attributes, set the right parents
1299 for( size_t nSrc
= rSourceArr
.GetFormatCount(); nSrc
> 1; )
1301 pSrc
= rSourceArr
.GetFormat( --nSrc
);
1302 if( pSrc
->IsDefault() || pSrc
->IsAuto() )
1305 pDest
= rDestArr
.FindFormatByName( pSrc
->GetName() );
1306 pDest
->SetAuto(false);
1307 pDest
->DelDiffs( *pSrc
);
1309 // #i94285#: existing <SwFormatPageDesc> instance, before copying attributes
1310 const SwFormatPageDesc
* pItem
;
1311 if( &GetAttrPool() != pSrc
->GetAttrSet().GetPool()
1312 && (pItem
= pSrc
->GetAttrSet().GetItemIfSet( RES_PAGEDESC
, false ))
1313 && pItem
->GetPageDesc() )
1315 SwFormatPageDesc
aPageDesc( *pItem
);
1316 const OUString
& rNm
= aPageDesc
.GetPageDesc()->GetName();
1317 SwPageDesc
* pPageDesc
= FindPageDesc( rNm
);
1320 pPageDesc
= MakePageDesc(rNm
);
1322 aPageDesc
.RegisterToPageDesc( *pPageDesc
);
1323 SwAttrSet
aTmpAttrSet( pSrc
->GetAttrSet() );
1324 aTmpAttrSet
.Put( aPageDesc
);
1325 pDest
->SetFormatAttr( aTmpAttrSet
);
1329 pDest
->SetFormatAttr( pSrc
->GetAttrSet() );
1332 pDest
->SetPoolFormatId( pSrc
->GetPoolFormatId() );
1333 pDest
->SetPoolHelpId( pSrc
->GetPoolHelpId() );
1335 // Always set the HelpFile Id to default!
1336 pDest
->SetPoolHlpFileId( UCHAR_MAX
);
1338 if( pSrc
->DerivedFrom() )
1339 pDest
->SetDerivedFrom( rDestArr
.FindFormatByName(
1340 pSrc
->DerivedFrom()->GetName() ) );
1341 if( RES_TXTFMTCOLL
== pSrc
->Which() ||
1342 RES_CONDTXTFMTCOLL
== pSrc
->Which() )
1344 SwTextFormatColl
* pSrcColl
= static_cast<SwTextFormatColl
*>(pSrc
),
1345 * pDstColl
= static_cast<SwTextFormatColl
*>(pDest
);
1346 if( &pSrcColl
->GetNextTextFormatColl() != pSrcColl
)
1347 pDstColl
->SetNextTextFormatColl(
1348 *static_cast<SwTextFormatColl
*>(rDestArr
.FindFormatByName( pSrcColl
->GetNextTextFormatColl().GetName() )) );
1350 if(pSrcColl
->IsAssignedToListLevelOfOutlineStyle())
1351 pDstColl
->AssignToListLevelOfOutlineStyle(pSrcColl
->GetAssignedOutlineStyleLevel());
1353 if( RES_CONDTXTFMTCOLL
== pSrc
->Which() )
1355 if (pDstColl
->Which() != RES_CONDTXTFMTCOLL
)
1357 // Target already had a style with a matching name, but it's not a conditional
1358 // style, then don't copy the conditions.
1362 // Copy the conditions, but delete the old ones first!
1363 static_cast<SwConditionTextFormatColl
*>(pDstColl
)->SetConditions(
1364 static_cast<SwConditionTextFormatColl
*>(pSrc
)->GetCondColls() );
1370 void SwDoc::CopyPageDescHeaderFooterImpl( bool bCpyHeader
,
1371 const SwFrameFormat
& rSrcFormat
, SwFrameFormat
& rDestFormat
)
1373 // Treat the header and footer attributes in the right way:
1374 // Copy content nodes across documents!
1375 sal_uInt16 nAttr
= bCpyHeader
? sal_uInt16(RES_HEADER
) : sal_uInt16(RES_FOOTER
);
1376 const SfxPoolItem
* pItem
;
1377 if( SfxItemState::SET
!= rSrcFormat
.GetAttrSet().GetItemState( nAttr
, false, &pItem
))
1380 // The header only contains the reference to the format from the other document!
1381 std::unique_ptr
<SfxPoolItem
> pNewItem(pItem
->Clone());
1383 SwFrameFormat
* pOldFormat
;
1385 pOldFormat
= pNewItem
->StaticWhichCast(RES_HEADER
).GetHeaderFormat();
1387 pOldFormat
= pNewItem
->StaticWhichCast(RES_FOOTER
).GetFooterFormat();
1392 SwFrameFormat
* pNewFormat
= new SwFrameFormat( GetAttrPool(), u
"CpyDesc"_ustr
,
1393 GetDfltFrameFormat() );
1394 pNewFormat
->CopyAttrs( *pOldFormat
);
1396 if( const SwFormatContent
* pContent
= pNewFormat
->GetAttrSet().GetItemIfSet(
1397 RES_CNTNT
, false ) )
1399 if( pContent
->GetContentIdx() )
1401 const SwNodes
& rSrcNds
= rSrcFormat
.GetDoc()->GetNodes();
1402 SwStartNode
* pSttNd
= SwNodes::MakeEmptySection( GetNodes().GetEndOfAutotext(),
1405 : SwFooterStartNode
);
1406 const SwNode
& rCSttNd
= pContent
->GetContentIdx()->GetNode();
1407 SwNodeRange
aRg( rCSttNd
, SwNodeOffset(0), *rCSttNd
.EndOfSectionNode() );
1408 rSrcNds
.Copy_( aRg
, *pSttNd
->EndOfSectionNode() );
1409 rSrcFormat
.GetDoc()->GetDocumentContentOperationsManager().CopyFlyInFlyImpl(aRg
, nullptr, *pSttNd
);
1410 // TODO: investigate calling CopyWithFlyInFly?
1411 SwPaM
const source(aRg
.aStart
, aRg
.aEnd
);
1412 SwPosition
dest(*pSttNd
);
1413 sw::CopyBookmarks(source
, dest
);
1414 pNewFormat
->SetFormatAttr( SwFormatContent( pSttNd
));
1417 pNewFormat
->ResetFormatAttr( RES_CNTNT
);
1420 pNewItem
->StaticWhichCast(RES_HEADER
).RegisterToFormat(*pNewFormat
);
1422 pNewItem
->StaticWhichCast(RES_FOOTER
).RegisterToFormat(*pNewFormat
);
1423 rDestFormat
.SetFormatAttr( *pNewItem
);
1426 void SwDoc::CopyPageDesc( const SwPageDesc
& rSrcDesc
, SwPageDesc
& rDstDesc
,
1429 bool bNotifyLayout
= false;
1430 SwRootFrame
* pTmpRoot
= getIDocumentLayoutAccess().GetCurrentLayout();
1432 rDstDesc
.SetLandscape( rSrcDesc
.GetLandscape() );
1433 rDstDesc
.SetNumType( rSrcDesc
.GetNumType() );
1434 if( rDstDesc
.ReadUseOn() != rSrcDesc
.ReadUseOn() )
1436 rDstDesc
.WriteUseOn( rSrcDesc
.ReadUseOn() );
1437 bNotifyLayout
= true;
1442 rDstDesc
.SetPoolFormatId( rSrcDesc
.GetPoolFormatId() );
1443 rDstDesc
.SetPoolHelpId( rSrcDesc
.GetPoolHelpId() );
1444 // Always set the HelpFile Id to default!
1445 rDstDesc
.SetPoolHlpFileId( UCHAR_MAX
);
1448 if( rSrcDesc
.GetFollow() != &rSrcDesc
)
1450 const SwPageDesc
* pSrcFollow
= rSrcDesc
.GetFollow();
1451 SwPageDesc
* pFollow
= FindPageDesc( pSrcFollow
->GetName() );
1455 pFollow
= MakePageDesc( pSrcFollow
->GetName() );
1456 CopyPageDesc( *pSrcFollow
, *pFollow
);
1458 rDstDesc
.SetFollow( pFollow
);
1459 bNotifyLayout
= true;
1462 // the header and footer attributes are copied separately
1463 // the content sections have to be copied in their entirety
1465 SfxItemSet
aAttrSet( rSrcDesc
.GetMaster().GetAttrSet() );
1466 aAttrSet
.ClearItem( RES_HEADER
);
1467 aAttrSet
.ClearItem( RES_FOOTER
);
1469 rDstDesc
.GetMaster().DelDiffs( aAttrSet
);
1470 rDstDesc
.GetMaster().SetFormatAttr( aAttrSet
);
1472 aAttrSet
.ClearItem();
1473 aAttrSet
.Put( rSrcDesc
.GetLeft().GetAttrSet() );
1474 aAttrSet
.ClearItem( RES_HEADER
);
1475 aAttrSet
.ClearItem( RES_FOOTER
);
1477 rDstDesc
.GetLeft().DelDiffs( aAttrSet
);
1478 rDstDesc
.GetLeft().SetFormatAttr( aAttrSet
);
1480 aAttrSet
.ClearItem();
1481 aAttrSet
.Put( rSrcDesc
.GetFirstMaster().GetAttrSet() );
1482 aAttrSet
.ClearItem( RES_HEADER
);
1483 aAttrSet
.ClearItem( RES_FOOTER
);
1485 rDstDesc
.GetFirstMaster().DelDiffs( aAttrSet
);
1486 rDstDesc
.GetFirstMaster().SetFormatAttr( aAttrSet
);
1488 aAttrSet
.ClearItem();
1489 aAttrSet
.Put( rSrcDesc
.GetFirstLeft().GetAttrSet() );
1490 aAttrSet
.ClearItem( RES_HEADER
);
1491 aAttrSet
.ClearItem( RES_FOOTER
);
1493 rDstDesc
.GetFirstLeft().DelDiffs( aAttrSet
);
1494 rDstDesc
.GetFirstLeft().SetFormatAttr( aAttrSet
);
1497 CopyHeader( rSrcDesc
.GetMaster(), rDstDesc
.GetMaster() );
1498 CopyFooter( rSrcDesc
.GetMaster(), rDstDesc
.GetMaster() );
1499 if( !rDstDesc
.IsHeaderShared() )
1500 CopyHeader( rSrcDesc
.GetLeft(), rDstDesc
.GetLeft() );
1502 rDstDesc
.GetLeft().SetFormatAttr( rDstDesc
.GetMaster().GetHeader() );
1503 if( !rDstDesc
.IsFirstShared() )
1505 CopyHeader( rSrcDesc
.GetFirstMaster(), rDstDesc
.GetFirstMaster() );
1506 rDstDesc
.GetFirstLeft().SetFormatAttr(rDstDesc
.GetFirstMaster().GetHeader());
1510 rDstDesc
.GetFirstMaster().SetFormatAttr( rDstDesc
.GetMaster().GetHeader() );
1511 rDstDesc
.GetFirstLeft().SetFormatAttr(rDstDesc
.GetLeft().GetHeader());
1514 if( !rDstDesc
.IsFooterShared() )
1515 CopyFooter( rSrcDesc
.GetLeft(), rDstDesc
.GetLeft() );
1517 rDstDesc
.GetLeft().SetFormatAttr( rDstDesc
.GetMaster().GetFooter() );
1518 if( !rDstDesc
.IsFirstShared() )
1520 CopyFooter( rSrcDesc
.GetFirstMaster(), rDstDesc
.GetFirstMaster() );
1521 rDstDesc
.GetFirstLeft().SetFormatAttr(rDstDesc
.GetFirstMaster().GetFooter());
1525 rDstDesc
.GetFirstMaster().SetFormatAttr( rDstDesc
.GetMaster().GetFooter() );
1526 rDstDesc
.GetFirstLeft().SetFormatAttr(rDstDesc
.GetLeft().GetFooter());
1529 if( bNotifyLayout
&& pTmpRoot
)
1531 for( auto aLayout
: GetAllLayouts() )
1532 aLayout
->AllCheckPageDescs();
1535 // If foot notes change the pages have to be triggered
1536 if( !(rDstDesc
.GetFootnoteInfo() == rSrcDesc
.GetFootnoteInfo()) )
1538 sw::PageFootnoteHint aHint
;
1539 rDstDesc
.SetFootnoteInfo( rSrcDesc
.GetFootnoteInfo() );
1540 rDstDesc
.GetMaster().CallSwClientNotify(aHint
);
1541 rDstDesc
.GetLeft().CallSwClientNotify(aHint
);
1542 rDstDesc
.GetFirstMaster().CallSwClientNotify(aHint
);
1543 rDstDesc
.GetFirstLeft().CallSwClientNotify(aHint
);
1546 // Copy the stashed formats as well between the page descriptors...
1547 for (bool bFirst
: { true, false })
1549 for (bool bLeft
: { true, false })
1551 for (bool bHeader
: { true, false })
1553 if (!bLeft
&& !bFirst
)
1556 // Copy format only if it exists
1557 if (auto pStashedFormatSrc
= rSrcDesc
.GetStashedFrameFormat(bHeader
, bLeft
, bFirst
))
1559 if (pStashedFormatSrc
->GetDoc() != this)
1561 SwFrameFormat
newFormat(GetAttrPool(), u
"CopyDesc"_ustr
, GetDfltFrameFormat());
1563 SfxItemSet
aAttrSet(pStashedFormatSrc
->GetAttrSet());
1564 aAttrSet
.ClearItem(RES_HEADER
);
1565 aAttrSet
.ClearItem(RES_FOOTER
);
1567 newFormat
.DelDiffs(aAttrSet
);
1568 newFormat
.SetFormatAttr(aAttrSet
);
1571 CopyHeader(*pStashedFormatSrc
, newFormat
);
1573 CopyFooter(*pStashedFormatSrc
, newFormat
);
1575 rDstDesc
.StashFrameFormat(newFormat
, bHeader
, bLeft
, bFirst
);
1579 rDstDesc
.StashFrameFormat(*pStashedFormatSrc
, bHeader
, bLeft
, bFirst
);
1587 void SwDoc::ReplaceStyles( const SwDoc
& rSource
, bool bIncludePageStyles
)
1589 ::sw::UndoGuard
const undoGuard(GetIDocumentUndoRedo());
1591 CopyFormatArr( *rSource
.mpCharFormatTable
, *mpCharFormatTable
,
1592 &SwDoc::MakeCharFormat_
, *mpDfltCharFormat
);
1593 CopyFormatArr( *rSource
.mpFrameFormatTable
, *mpFrameFormatTable
,
1594 &SwDoc::MakeFrameFormat_
, *mpDfltFrameFormat
);
1595 CopyFormatArr( *rSource
.mpTextFormatCollTable
, *mpTextFormatCollTable
,
1596 &SwDoc::MakeTextFormatColl_
, *mpDfltTextFormatColl
);
1599 // a) in sd rtf import (View::InsertData) don't use
1600 // a super-fragile test for mere presence of \trowd to
1601 // indicate import of rtf into a table
1602 // b) then drop use of bIncludePageStyles
1603 if (bIncludePageStyles
)
1605 // and now the page templates
1606 SwPageDescs::size_type nCnt
= rSource
.m_PageDescs
.size();
1609 // a different Doc -> Number formatter needs to be merged
1610 SwTableNumFormatMerge
aTNFM( rSource
, *this );
1612 // 1st step: Create all formats (skip the 0th - it's the default!)
1615 const SwPageDesc
&rSrc
= *rSource
.m_PageDescs
[ --nCnt
];
1616 if( nullptr == FindPageDesc( rSrc
.GetName() ) )
1617 MakePageDesc( rSrc
.GetName() );
1620 // 2nd step: Copy all attributes, set the right parents
1621 for (SwPageDescs::size_type i
= rSource
.m_PageDescs
.size(); i
; )
1623 const SwPageDesc
&rSrc
= *rSource
.m_PageDescs
[ --i
];
1624 SwPageDesc
* pDesc
= FindPageDesc( rSrc
.GetName() );
1625 CopyPageDesc( rSrc
, *pDesc
);
1630 // then there are the numbering templates
1631 const SwNumRuleTable::size_type nCnt
= rSource
.GetNumRuleTable().size();
1634 const SwNumRuleTable
& rArr
= rSource
.GetNumRuleTable();
1635 for( SwNumRuleTable::size_type n
= 0; n
< nCnt
; ++n
)
1637 const SwNumRule
& rR
= *rArr
[ n
];
1638 SwNumRule
* pNew
= FindNumRulePtr( rR
.GetName());
1640 pNew
->CopyNumRule(*this, rR
);
1643 if( !rR
.IsAutoRule() )
1644 MakeNumRule( rR
.GetName(), &rR
);
1647 // as we reset all styles, there shouldn't be any unknown
1648 // automatic SwNumRules, because all should have been
1649 // created by the style copying!
1650 // So just warn and ignore.
1651 SAL_WARN( "sw.core", "Found unknown auto SwNumRule during reset!" );
1657 if (undoGuard
.UndoWasEnabled())
1659 // nodes array was modified!
1660 GetIDocumentUndoRedo().DelAllUndoObj();
1663 getIDocumentState().SetModified();
1666 void SwDoc::MoveLeftMargin(const SwPaM
& rPam
, bool bRight
, bool bModulus
,
1667 SwRootFrame
const*const pLayout
)
1669 SwHistory
* pHistory
= nullptr;
1670 if (GetIDocumentUndoRedo().DoesUndo())
1672 std::unique_ptr
<SwUndoMoveLeftMargin
> pUndo(new SwUndoMoveLeftMargin( rPam
, bRight
,
1674 pHistory
= &pUndo
->GetHistory();
1675 GetIDocumentUndoRedo().AppendUndo( std::move(pUndo
) );
1678 const SvxTabStopItem
& rTabItem
= GetDefault( RES_PARATR_TABSTOP
);
1679 const sal_Int32 nDefDist
= rTabItem
.Count() ? rTabItem
[0].GetTabPos() : 1134;
1680 const SwPosition
&rStt
= *rPam
.Start(), &rEnd
= *rPam
.End();
1681 SwNodeIndex
aIdx( rStt
.GetNode() );
1682 while( aIdx
<= rEnd
.GetNode() )
1684 SwTextNode
* pTNd
= aIdx
.GetNode().GetTextNode();
1687 pTNd
= sw::GetParaPropsNode(*pLayout
, aIdx
.GetNode());
1688 SvxFirstLineIndentItem
firstLine(pTNd
->SwContentNode::GetAttr(RES_MARGIN_FIRSTLINE
));
1689 SvxTextLeftMarginItem
leftMargin(pTNd
->SwContentNode::GetAttr(RES_MARGIN_TEXTLEFT
));
1691 // #i93873# See also lcl_MergeListLevelIndentAsLRSpaceItem in thints.cxx
1692 ::sw::ListLevelIndents
const indents(pTNd
->AreListLevelIndentsApplicable());
1693 if (indents
!= ::sw::ListLevelIndents::No
)
1695 const SwNumRule
* pRule
= pTNd
->GetNumRule();
1698 const int nListLevel
= pTNd
->GetActualListLevel();
1699 if ( nListLevel
>= 0 )
1701 const SwNumFormat
& rFormat
= pRule
->Get(o3tl::narrowing
<sal_uInt16
>(nListLevel
));
1702 if ( rFormat
.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT
)
1704 if (indents
& ::sw::ListLevelIndents::LeftMargin
)
1706 leftMargin
.SetTextLeft(
1707 SvxIndentValue::twips(rFormat
.GetIndentAt()));
1709 if (indents
& ::sw::ListLevelIndents::FirstLine
)
1711 firstLine
.SetTextFirstLineOffset(SvxIndentValue
{
1712 static_cast<double>(rFormat
.GetFirstLineIndent()),
1713 rFormat
.GetFirstLineIndentUnit() });
1720 tools::Long nNext
= leftMargin
.ResolveTextLeft({});
1722 nNext
= ( nNext
/ nDefDist
) * nDefDist
;
1727 if(nNext
>0) // fdo#75936 set limit for decreasing indent
1730 leftMargin
.SetTextLeft(SvxIndentValue::twips(nNext
));
1732 SwRegHistory
aRegH( pTNd
, *pTNd
, pHistory
);
1733 pTNd
->SetAttr(firstLine
);
1734 pTNd
->SetAttr(leftMargin
);
1735 aIdx
= *sw::GetFirstAndLastNode(*pLayout
, aIdx
.GetNode()).second
;
1739 getIDocumentState().SetModified();
1742 bool SwDoc::DontExpandFormat( const SwPosition
& rPos
, bool bFlag
)
1745 SwTextNode
* pTextNd
= rPos
.GetNode().GetTextNode();
1748 bRet
= pTextNd
->DontExpandFormat( rPos
.GetContentIndex(), bFlag
);
1749 if( bRet
&& GetIDocumentUndoRedo().DoesUndo() )
1751 GetIDocumentUndoRedo().AppendUndo( std::make_unique
<SwUndoDontExpandFormat
>(rPos
) );
1757 SwTableBoxFormat
* SwDoc::MakeTableBoxFormat()
1759 SwTableBoxFormat
* pFormat
= new SwTableBoxFormat( GetAttrPool(), mpDfltFrameFormat
.get() );
1760 pFormat
->SetFormatName("TableBox" + OUString::number(reinterpret_cast<sal_IntPtr
>(pFormat
)));
1761 getIDocumentState().SetModified();
1765 SwTableLineFormat
* SwDoc::MakeTableLineFormat()
1767 SwTableLineFormat
* pFormat
= new SwTableLineFormat( GetAttrPool(), mpDfltFrameFormat
.get() );
1768 pFormat
->SetFormatName("TableLine" + OUString::number(reinterpret_cast<sal_IntPtr
>(pFormat
)));
1769 getIDocumentState().SetModified();
1773 void SwDoc::EnsureNumberFormatter()
1775 if (mpNumberFormatter
== nullptr)
1777 LanguageType eLang
= LANGUAGE_SYSTEM
;
1778 mpNumberFormatter
= new SvNumberFormatter(comphelper::getProcessComponentContext(), eLang
);
1779 mpNumberFormatter
->SetEvalDateFormat( NF_EVALDATEFORMAT_FORMAT_INTL
);
1780 if (!comphelper::IsFuzzing())
1781 mpNumberFormatter
->SetYear2000(
1782 officecfg::Office::Common::DateFormat::TwoDigitYear::get());
1786 SwTableNumFormatMerge::SwTableNumFormatMerge( const SwDoc
& rSrc
, SwDoc
& rDest
)
1787 : pNFormat( nullptr )
1789 // a different Doc -> Number formatter needs to be merged
1790 if( &rSrc
!= &rDest
)
1792 SvNumberFormatter
* pN
= const_cast<SwDoc
&>(rSrc
).GetNumberFormatter( false );
1795 pNFormat
= rDest
.GetNumberFormatter();
1796 pNFormat
->MergeFormatter( *pN
);
1800 if( &rSrc
!= &rDest
)
1801 static_cast<SwGetRefFieldType
*>(rSrc
.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::GetRef
))->
1802 MergeWithOtherDoc( rDest
);
1805 SwTableNumFormatMerge::~SwTableNumFormatMerge()
1808 pNFormat
->ClearMergeTable();
1811 void SwDoc::SetTextFormatCollByAutoFormat( const SwPosition
& rPos
, sal_uInt16 nPoolId
,
1812 const SfxItemSet
* pSet
)
1815 SwTextNode
* pTNd
= rPos
.GetNode().GetTextNode();
1818 if (mbIsAutoFormatRedline
)
1820 // create the redline object
1821 const SwTextFormatColl
& rColl
= *pTNd
->GetTextColl();
1822 SwRangeRedline
* pRedl
= new SwRangeRedline( RedlineType::FmtColl
, aPam
);
1825 // Only those items that are not set by the Set again in the Node
1826 // are of interest. Thus, we take the difference.
1827 SwRedlineExtraData_FormatColl
aExtraData( rColl
.GetName(),
1828 rColl
.GetPoolFormatId() );
1829 if( pSet
&& pTNd
->HasSwAttrSet() )
1831 SfxItemSet
aTmp( *pTNd
->GetpSwAttrSet() );
1832 aTmp
.Differentiate( *pSet
);
1833 // we handle the adjust item separately
1834 const SfxPoolItem
* pItem
;
1835 if( SfxItemState::SET
== pTNd
->GetpSwAttrSet()->GetItemState(
1836 RES_PARATR_ADJUST
, false, &pItem
))
1838 aExtraData
.SetItemSet( aTmp
);
1840 pRedl
->SetExtraData( &aExtraData
);
1842 //TODO: Undo is still missing!
1843 getIDocumentRedlineAccess().AppendRedline( pRedl
, true );
1846 SetTextFormatColl( aPam
, getIDocumentStylePoolAccess().GetTextCollFromPool( nPoolId
) );
1848 if (pSet
&& pSet
->Count())
1851 aPam
.GetMark()->SetContent(pTNd
->GetText().getLength());
1852 // sw_redlinehide: don't need layout currently because the only caller
1853 // passes in the properties node
1854 assert(static_cast<SwTextFrame
const*>(pTNd
->getLayoutFrame(nullptr))->GetTextNodeForParaProps() == pTNd
);
1855 getIDocumentContentOperations().InsertItemSet( aPam
, *pSet
);
1859 void SwDoc::SetFormatItemByAutoFormat( const SwPaM
& rPam
, const SfxItemSet
& rSet
)
1861 SwTextNode
* pTNd
= rPam
.GetPoint()->GetNode().GetTextNode();
1864 RedlineFlags eOld
= getIDocumentRedlineAccess().GetRedlineFlags();
1866 if (mbIsAutoFormatRedline
)
1868 // create the redline object
1869 SwRangeRedline
* pRedl
= new SwRangeRedline( RedlineType::Format
, rPam
);
1870 if( !pRedl
->HasMark() )
1873 // Only those items that are not set by the Set again in the Node
1874 // are of interest. Thus, we take the difference.
1875 SwRedlineExtraData_Format
aExtraData( rSet
);
1877 pRedl
->SetExtraData( &aExtraData
);
1879 //TODO: Undo is still missing!
1880 getIDocumentRedlineAccess().AppendRedline( pRedl
, true );
1882 getIDocumentRedlineAccess().SetRedlineFlags_intern( eOld
| RedlineFlags::Ignore
);
1885 const sal_Int32
nEnd(rPam
.End()->GetContentIndex());
1886 std::vector
<WhichPair
> whichIds
;
1887 SfxItemIter
iter(rSet
);
1888 for (SfxPoolItem
const* pItem
= iter
.GetCurItem(); pItem
; pItem
= iter
.NextItem())
1890 if (RES_CHRATR_BEGIN
<= pItem
->Which() && pItem
->Which() < RES_CHRATR_END
)
1891 { // tdf#162911 don't add items with static default like INETFMT
1892 whichIds
.push_back({pItem
->Which(), pItem
->Which()});
1896 ::std::optional
<SfxItemSet
> oCurrentSet
;
1897 if (!whichIds
.empty())
1899 // ITEM: Need to sort these due to ItemSet using unordered_set and
1900 // WhichRangesContainer expect these sorted ascending
1901 std::sort(whichIds
.begin(), whichIds
.end(), [](WhichPair
& a
, WhichPair
& b
) {return a
.first
< b
.first
;});
1903 oCurrentSet
.emplace(GetAttrPool(), WhichRangesContainer(whichIds
.data(), whichIds
.size()));
1904 pTNd
->GetParaAttr(*oCurrentSet
, nEnd
, nEnd
);
1905 for (const WhichPair
& rPair
: whichIds
)
1906 { // yuk - want to explicitly set the pool defaults too :-/
1907 oCurrentSet
->Put(oCurrentSet
->Get(rPair
.first
));
1911 getIDocumentContentOperations().InsertItemSet( rPam
, rSet
, SetAttrMode::DONTEXPAND
);
1913 if (!whichIds
.empty())
1915 // fdo#62536: DONTEXPAND does not work when there is already an AUTOFMT
1916 // here, so insert the old attributes as an empty hint to stop expand
1917 SwPaM
endPam(*pTNd
, nEnd
);
1919 getIDocumentContentOperations().InsertItemSet(endPam
, *oCurrentSet
);
1922 getIDocumentRedlineAccess().SetRedlineFlags_intern( eOld
);
1925 void SwDoc::ChgFormat(SwFormat
& rFormat
, const SfxItemSet
& rSet
)
1927 if (GetIDocumentUndoRedo().DoesUndo())
1929 // copying <rSet> to <aSet>
1930 SfxItemSet
aSet(rSet
);
1931 // remove from <aSet> all items, which are already set at the format
1932 aSet
.Differentiate(rFormat
.GetAttrSet());
1933 // <aSet> contains now all *new* items for the format
1935 // copying current format item set to <aOldSet>
1936 SfxItemSet
aOldSet(rFormat
.GetAttrSet());
1937 // insert new items into <aOldSet>
1939 // invalidate all new items in <aOldSet> in order to clear these items,
1940 // if the undo action is triggered.
1942 SfxItemIter
aIter(aSet
);
1944 for (const SfxPoolItem
* pItem
= aIter
.GetCurItem(); pItem
; pItem
= aIter
.NextItem())
1946 aOldSet
.InvalidateItem(pItem
->Which());
1950 GetIDocumentUndoRedo().AppendUndo(
1951 std::make_unique
<SwUndoFormatAttr
>(std::move(aOldSet
), rFormat
, /*bSaveDrawPt*/true));
1954 rFormat
.SetFormatAttr(rSet
);
1957 void SwDoc::RenameFormat(SwFormat
& rFormat
, const OUString
& sNewName
,
1960 SfxStyleFamily eFamily
= SfxStyleFamily::All
;
1962 if (GetIDocumentUndoRedo().DoesUndo())
1964 std::unique_ptr
<SwUndo
> pUndo
;
1966 switch (rFormat
.Which())
1969 pUndo
.reset(new SwUndoRenameCharFormat(rFormat
.GetName(), sNewName
, *this));
1970 eFamily
= SfxStyleFamily::Char
;
1972 case RES_TXTFMTCOLL
:
1973 pUndo
.reset(new SwUndoRenameFormatColl(rFormat
.GetName(), sNewName
, *this));
1974 eFamily
= SfxStyleFamily::Para
;
1977 pUndo
.reset(new SwUndoRenameFrameFormat(rFormat
.GetName(), sNewName
, *this));
1978 eFamily
= SfxStyleFamily::Frame
;
1987 GetIDocumentUndoRedo().AppendUndo(std::move(pUndo
));
1991 // name change means the o3tl::sorted_array is not property sorted
1992 if (rFormat
.Which() == RES_CHRFMT
)
1993 mpCharFormatTable
->SetFormatNameAndReindex(static_cast<SwCharFormat
*>(&rFormat
), sNewName
);
1995 rFormat
.SetFormatName(sNewName
);
1998 BroadcastStyleOperation(sNewName
, eFamily
, SfxHintId::StyleSheetModified
);
2001 void SwDoc::dumpAsXml(xmlTextWriterPtr pWriter
) const
2006 pWriter
= xmlNewTextWriterFilename("nodes.xml", 0);
2007 xmlTextWriterSetIndent(pWriter
,1);
2008 (void)xmlTextWriterSetIndentString(pWriter
, BAD_CAST(" "));
2009 (void)xmlTextWriterStartDocument(pWriter
, nullptr, nullptr, nullptr);
2012 (void)xmlTextWriterStartElement(pWriter
, BAD_CAST("SwDoc"));
2013 (void)xmlTextWriterWriteFormatAttribute(pWriter
, BAD_CAST("ptr"), "%p", this);
2015 m_pNodes
->dumpAsXml(pWriter
);
2016 m_PageDescs
.dumpAsXml(pWriter
);
2017 maDBData
.dumpAsXml(pWriter
);
2018 mpMarkManager
->dumpAsXml(pWriter
);
2019 m_pContentControlManager
->dumpAsXml(pWriter
);
2020 m_pUndoManager
->dumpAsXml(pWriter
);
2021 m_pDocumentSettingManager
->dumpAsXml(pWriter
);
2022 getIDocumentFieldsAccess().GetFieldTypes()->dumpAsXml(pWriter
);
2023 mpTextFormatCollTable
->dumpAsXml(pWriter
);
2024 mpCharFormatTable
->dumpAsXml(pWriter
);
2025 mpFrameFormatTable
->dumpAsXml(pWriter
, "frmFormatTable");
2026 mpSpzFrameFormatTable
->dumpAsXml(pWriter
, "spzFrameFormatTable");
2027 mpSectionFormatTable
->dumpAsXml(pWriter
);
2028 mpTableFrameFormatTable
->dumpAsXml(pWriter
, "tableFrameFormatTable");
2029 mpNumRuleTable
->dumpAsXml(pWriter
);
2030 getIDocumentRedlineAccess().GetRedlineTable().dumpAsXml(pWriter
);
2031 getIDocumentRedlineAccess().GetExtraRedlineTable().dumpAsXml(pWriter
);
2032 if (const SdrModel
* pModel
= getIDocumentDrawModelAccess().GetDrawModel())
2033 pModel
->dumpAsXml(pWriter
);
2035 (void)xmlTextWriterStartElement(pWriter
, BAD_CAST("mbModified"));
2036 (void)xmlTextWriterWriteAttribute(pWriter
, BAD_CAST("value"), BAD_CAST(OString::boolean(getIDocumentState().IsModified()).getStr()));
2037 (void)xmlTextWriterEndElement(pWriter
);
2039 (void)xmlTextWriterEndElement(pWriter
);
2042 (void)xmlTextWriterEndDocument(pWriter
);
2043 xmlFreeTextWriter(pWriter
);
2047 void SwDBData::dumpAsXml(xmlTextWriterPtr pWriter
) const
2049 (void)xmlTextWriterStartElement(pWriter
, BAD_CAST("SwDBData"));
2051 (void)xmlTextWriterWriteAttribute(pWriter
, BAD_CAST("sDataSource"), BAD_CAST(sDataSource
.toUtf8().getStr()));
2052 (void)xmlTextWriterWriteAttribute(pWriter
, BAD_CAST("sCommand"), BAD_CAST(sCommand
.toUtf8().getStr()));
2053 (void)xmlTextWriterWriteAttribute(pWriter
, BAD_CAST("nCommandType"), BAD_CAST(OString::number(nCommandType
).getStr()));
2055 (void)xmlTextWriterEndElement(pWriter
);
2058 std::set
<Color
> SwDoc::GetDocColors()
2060 std::set
<Color
> aDocColors
;
2061 SwAttrPool
& rPool
= GetAttrPool();
2063 svx::DocumentColorHelper::queryColors
<SvxColorItem
>(RES_CHRATR_COLOR
, &rPool
, aDocColors
);
2064 svx::DocumentColorHelper::queryColors
<SvxBrushItem
>(RES_CHRATR_HIGHLIGHT
, &rPool
, aDocColors
);
2065 svx::DocumentColorHelper::queryColors
<SvxBrushItem
>(RES_CHRATR_BACKGROUND
, &rPool
, aDocColors
);
2073 bool HasOutlineStyleToBeWrittenAsNormalListStyle( SwDoc
& rDoc
)
2075 // If a parent paragraph style of one of the paragraph styles, which
2076 // are assigned to the list levels of the outline style, has a list style
2077 // set or inherits a list style from its parent style, the outline style
2078 // has to be written as a normal list style to the OpenDocument file
2079 // format or the OpenOffice.org file format.
2082 const SwTextFormatColls
* pTextFormatColls( rDoc
.GetTextFormatColls() );
2083 if ( pTextFormatColls
)
2085 for ( auto pTextFormatColl
: *pTextFormatColls
)
2087 if ( pTextFormatColl
->IsDefault() ||
2088 ! pTextFormatColl
->IsAssignedToListLevelOfOutlineStyle() )
2093 const SwTextFormatColl
* pParentTextFormatColl
=
2094 dynamic_cast<const SwTextFormatColl
*>( pTextFormatColl
->DerivedFrom());
2095 if ( !pParentTextFormatColl
)
2098 if ( SfxItemState::SET
== pParentTextFormatColl
->GetItemState( RES_PARATR_NUMRULE
) )
2100 // #i106218# consider that the outline style is set
2101 const SwNumRuleItem
& rDirectItem
= pParentTextFormatColl
->GetNumRule();
2102 if ( rDirectItem
.GetValue() != rDoc
.GetOutlineNumRule()->GetName() )
2114 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */