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 <editeng/colritem.hxx>
29 #include <officecfg/Office/Common.hxx>
30 #include <osl/diagnose.h>
31 #include <svl/zforlist.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>
82 using namespace ::com::sun::star::i18n
;
83 using namespace ::com::sun::star::lang
;
84 using namespace ::com::sun::star::uno
;
90 static void SetTextFormatCollNext( SwTextFormatColl
* pTextColl
, const SwTextFormatColl
* pDel
)
92 if ( &pTextColl
->GetNextTextFormatColl() == pDel
)
94 pTextColl
->SetNextTextFormatColl( *pTextColl
);
98 static bool lcl_RstAttr( SwNode
* pNd
, void* pArgs
)
100 const sw::DocumentContentOperationsManager::ParaRstFormat
* pPara
= static_cast<sw::DocumentContentOperationsManager::ParaRstFormat
*>(pArgs
);
101 SwContentNode
* pNode
= pNd
->GetContentNode();
102 if (pPara
&& pPara
->pLayout
&& pPara
->pLayout
->HasMergedParas()
103 && pNode
&& pNode
->GetRedlineMergeFlag() == SwNode::Merge::Hidden
)
107 if( pNode
&& pNode
->HasSwAttrSet() )
109 const bool bLocked
= pNode
->IsModifyLocked();
112 SwDoc
& rDoc
= pNode
->GetDoc();
114 // remove unused attribute RES_LR_SPACE
115 // add list attributes, except RES_PARATR_LIST_AUTOFMT
117 RES_PARATR_NUMRULE
, RES_PARATR_NUMRULE
,
118 RES_PARATR_LIST_BEGIN
, RES_PARATR_LIST_AUTOFMT
- 1,
119 RES_PAGEDESC
, RES_BREAK
,
120 RES_FRMATR_STYLE_NAME
, RES_FRMATR_CONDITIONAL_STYLE_NAME
> aSavedAttrsSet(rDoc
.GetAttrPool());
121 const SfxItemSet
* pAttrSetOfNode
= pNode
->GetpSwAttrSet();
123 std::vector
<sal_uInt16
> aClearWhichIds
;
124 // restoring all paragraph list attributes
126 SfxItemSetFixed
<RES_PARATR_LIST_BEGIN
, RES_PARATR_LIST_AUTOFMT
- 1> aListAttrSet( rDoc
.GetAttrPool() );
127 aListAttrSet
.Set(*pAttrSetOfNode
);
128 if ( aListAttrSet
.Count() )
130 aSavedAttrsSet
.Put(aListAttrSet
);
131 SfxItemIter
aIter( aListAttrSet
);
132 const SfxPoolItem
* pItem
= aIter
.GetCurItem();
135 aClearWhichIds
.push_back( pItem
->Which() );
136 pItem
= aIter
.NextItem();
141 if (auto pItem
= pAttrSetOfNode
->GetItemIfSet(RES_PARATR_NUMRULE
, false);
142 pItem
&& !pItem
->GetValue().isEmpty())
144 aSavedAttrsSet
.Put(*pItem
);
145 aClearWhichIds
.push_back(RES_PARATR_NUMRULE
);
147 if (auto pItem
= pAttrSetOfNode
->GetItemIfSet(RES_PAGEDESC
, false);
148 pItem
&& pItem
->GetPageDesc())
150 aSavedAttrsSet
.Put(*pItem
);
151 aClearWhichIds
.push_back(RES_PAGEDESC
);
153 if (auto pItem
= pAttrSetOfNode
->GetItemIfSet(RES_BREAK
, false);
154 pItem
&& pItem
->GetBreak() != SvxBreak::NONE
)
156 aSavedAttrsSet
.Put(*pItem
);
157 aClearWhichIds
.push_back(RES_BREAK
);
159 if (auto pItem
= pAttrSetOfNode
->GetItemIfSet(RES_FRMATR_STYLE_NAME
, false);
160 pItem
&& !pItem
->GetValue().isEmpty())
162 aSavedAttrsSet
.Put(*pItem
);
163 aClearWhichIds
.push_back(RES_FRMATR_STYLE_NAME
);
165 if (auto pItem
= pAttrSetOfNode
->GetItemIfSet(RES_FRMATR_CONDITIONAL_STYLE_NAME
, false);
166 pItem
&& !pItem
->GetValue().isEmpty())
168 aSavedAttrsSet
.Put(*pItem
);
169 aClearWhichIds
.push_back(RES_FRMATR_CONDITIONAL_STYLE_NAME
);
172 // do not clear items directly from item set and only clear to be kept
173 // attributes, if no deletion item set is found.
174 const bool bKeepAttributes
=
175 !pPara
|| !pPara
->pDelSet
|| pPara
->pDelSet
->Count() == 0;
176 if ( bKeepAttributes
)
178 pNode
->ResetAttr( aClearWhichIds
);
182 pNode
->UnlockModify();
186 SwRegHistory
aRegH( pNode
, *pNode
, pPara
->pHistory
);
188 if( pPara
->pDelSet
&& pPara
->pDelSet
->Count() )
190 OSL_ENSURE( !bKeepAttributes
,
191 "<lcl_RstAttr(..)> - certain attributes are kept, but not needed." );
192 SfxItemIter
aIter( *pPara
->pDelSet
);
193 for (const SfxPoolItem
* pItem
= aIter
.GetCurItem(); pItem
; pItem
= aIter
.NextItem())
195 if ( ( pItem
->Which() != RES_PAGEDESC
&&
196 pItem
->Which() != RES_BREAK
&&
197 pItem
->Which() != RES_FRMATR_STYLE_NAME
&&
198 pItem
->Which() != RES_FRMATR_CONDITIONAL_STYLE_NAME
&&
199 pItem
->Which() != RES_PARATR_NUMRULE
) ||
200 ( aSavedAttrsSet
.GetItemState( pItem
->Which(), false ) != SfxItemState::SET
) )
202 pNode
->ResetAttr( pItem
->Which() );
206 else if( pPara
->bResetAll
)
207 pNode
->ResetAllAttr();
209 pNode
->ResetAttr( RES_PARATR_BEGIN
, POOLATTR_END
- 1 );
212 pNode
->ResetAllAttr();
214 // only restore saved attributes, if needed
215 if (bKeepAttributes
&& aSavedAttrsSet
.Count())
219 pNode
->SetAttr(aSavedAttrsSet
);
222 pNode
->UnlockModify();
228 void SwDoc::RstTextAttrs(const SwPaM
&rRg
, bool bInclRefToxMark
,
229 bool bExactRange
, SwRootFrame
const*const pLayout
)
231 SwHistory
* pHst
= nullptr;
232 SwDataChanged
aTmp( rRg
);
233 if (GetIDocumentUndoRedo().DoesUndo())
235 std::unique_ptr
<SwUndoResetAttr
> pUndo(new SwUndoResetAttr( rRg
, RES_CHRFMT
));
236 pHst
= &pUndo
->GetHistory();
237 GetIDocumentUndoRedo().AppendUndo(std::move(pUndo
));
239 auto [pStt
, pEnd
] = rRg
.StartEnd(); // SwPosition*
240 sw::DocumentContentOperationsManager::ParaRstFormat
aPara(
241 pStt
, pEnd
, pHst
, nullptr, pLayout
);
242 aPara
.bInclRefToxMark
= bInclRefToxMark
;
243 aPara
.bExactRange
= bExactRange
;
244 GetNodes().ForEach( pStt
->GetNodeIndex(), pEnd
->GetNodeIndex()+1,
245 sw::DocumentContentOperationsManager::lcl_RstTextAttr
, &aPara
);
246 getIDocumentState().SetModified();
249 void SwDoc::ResetAttrs( const SwPaM
&rRg
,
251 const o3tl::sorted_vector
<sal_uInt16
> &rAttrs
,
252 const bool bSendDataChangedEvents
,
253 SwRootFrame
const*const pLayout
)
255 SwPaM
* pPam
= const_cast<SwPaM
*>(&rRg
);
256 std::optional
<SwPaM
> oExtraPaM
;
257 if( !bTextAttr
&& !rAttrs
.empty() && RES_TXTATR_END
> *(rAttrs
.begin()) )
262 SwTextNode
* pTextNd
= rRg
.GetPoint()->GetNode().GetTextNode();
266 oExtraPaM
.emplace( *rRg
.GetPoint() );
269 SwPosition
& rSt
= *pPam
->GetPoint();
270 sal_Int32 nMkPos
, nPtPos
= rSt
.GetContentIndex();
272 // Special case: if the Cursor is located within a URL attribute, we take over it's area
273 SwTextAttr
const*const pURLAttr(
274 pTextNd
->GetTextAttrAt(rSt
.GetContentIndex(), RES_TXTATR_INETFMT
));
275 if (pURLAttr
&& !pURLAttr
->GetINetFormat().GetValue().isEmpty())
277 nMkPos
= pURLAttr
->GetStart();
278 nPtPos
= *pURLAttr
->End();
282 assert(g_pBreakIt
&& g_pBreakIt
->GetBreakIter().is());
283 Boundary aBndry
= g_pBreakIt
->GetBreakIter()->getWordBoundary(
284 pTextNd
->GetText(), nPtPos
,
285 g_pBreakIt
->GetLocale( pTextNd
->GetLang( nPtPos
) ),
286 WordType::ANY_WORD
/*ANYWORD_IGNOREWHITESPACES*/,
289 if( aBndry
.startPos
< nPtPos
&& nPtPos
< aBndry
.endPos
)
291 nMkPos
= aBndry
.startPos
;
292 nPtPos
= aBndry
.endPos
;
296 nPtPos
= nMkPos
= rSt
.GetContentIndex();
298 pTextNd
->DontExpandFormat( nPtPos
);
302 rSt
.SetContent(nMkPos
);
304 pPam
->GetPoint()->SetContent(nPtPos
);
308 std::optional
< SwDataChanged
> oDataChanged
;
309 if ( bSendDataChangedEvents
)
311 oDataChanged
.emplace( *pPam
);
313 SwHistory
* pHst
= nullptr;
314 if (GetIDocumentUndoRedo().DoesUndo())
316 std::unique_ptr
<SwUndoResetAttr
> pUndo(new SwUndoResetAttr( rRg
,
317 bTextAttr
? sal_uInt16(RES_CONDTXTFMTCOLL
) : sal_uInt16(RES_TXTFMTCOLL
) ));
318 if( !rAttrs
.empty() )
320 pUndo
->SetAttrs( o3tl::sorted_vector(rAttrs
) );
322 pHst
= &pUndo
->GetHistory();
323 GetIDocumentUndoRedo().AppendUndo(std::move(pUndo
));
326 auto [pStt
, pEnd
] = pPam
->StartEnd(); // SwPosition*
327 sw::DocumentContentOperationsManager::ParaRstFormat
aPara(
328 pStt
, pEnd
, pHst
, nullptr, pLayout
);
330 // mst: not including META here; it seems attrs with CH_TXTATR are omitted
331 SfxItemSetFixed
<RES_CHRATR_BEGIN
, RES_CHRATR_END
- 1,
332 RES_TXTATR_INETFMT
, RES_TXTATR_UNKNOWN_CONTAINER
,
333 RES_PARATR_BEGIN
, RES_FRMATR_END
- 1,
334 RES_UNKNOWNATR_BEGIN
, RES_UNKNOWNATR_END
- 1>
335 aDelSet(GetAttrPool());
336 for( auto it
= rAttrs
.rbegin(); it
!= rAttrs
.rend(); ++it
)
338 if( POOLATTR_END
> *it
)
339 aDelSet
.Put( *GetDfltAttr( *it
));
341 if( aDelSet
.Count() )
342 aPara
.pDelSet
= &aDelSet
;
345 SwNodeIndex
aTmpStt( pStt
->GetNode() );
346 SwNodeIndex
aTmpEnd( pEnd
->GetNode() );
347 if( pStt
->GetContentIndex() ) // just one part
349 // set up a later, and all CharFormatAttr -> TextFormatAttr
350 SwTextNode
* pTNd
= aTmpStt
.GetNode().GetTextNode();
351 if( pTNd
&& pTNd
->HasSwAttrSet() && pTNd
->GetpSwAttrSet()->Count() )
355 SwRegHistory
history(pTNd
, *pTNd
, pHst
);
356 pTNd
->FormatToTextAttr(pTNd
);
360 pTNd
->FormatToTextAttr(pTNd
);
366 if( pEnd
->GetContentIndex() == pEnd
->GetNode().GetContentNode()->Len() )
368 // set up a later, and all CharFormatAttr -> TextFormatAttr
372 else if( pStt
->GetNode() != pEnd
->GetNode() || !pStt
->GetContentIndex() )
374 SwTextNode
* pTNd
= aTmpEnd
.GetNode().GetTextNode();
375 if( pTNd
&& pTNd
->HasSwAttrSet() && pTNd
->GetpSwAttrSet()->Count() )
379 SwRegHistory
history(pTNd
, *pTNd
, pHst
);
380 pTNd
->FormatToTextAttr(pTNd
);
384 pTNd
->FormatToTextAttr(pTNd
);
389 if( aTmpStt
< aTmpEnd
)
390 GetNodes().ForEach( pStt
->GetNode(), aTmpEnd
.GetNode(), lcl_RstAttr
, &aPara
);
391 else if( !rRg
.HasMark() )
393 aPara
.bResetAll
= false ;
394 ::lcl_RstAttr( &pStt
->GetNode(), &aPara
);
395 aPara
.bResetAll
= true ;
402 GetNodes().ForEach( pStt
->GetNode(), aTmpEnd
.GetNode(), sw::DocumentContentOperationsManager::lcl_RstTextAttr
, &aPara
);
405 getIDocumentState().SetModified();
407 oDataChanged
.reset(); //before delete pPam
410 /// Set the rsid of the next nLen symbols of rRg to the current session number
411 void SwDoc::UpdateRsid( const SwPaM
&rRg
, const sal_Int32 nLen
)
413 if (!SW_MOD()->GetModuleConfig()->IsStoreRsid())
416 SwTextNode
*pTextNode
= rRg
.GetPoint()->GetNode().GetTextNode();
421 const sal_Int32
nStart(rRg
.GetPoint()->GetContentIndex() - nLen
);
422 SvxRsidItem
aRsid( mnRsid
, RES_CHRATR_RSID
);
424 SfxItemSetFixed
<RES_CHRATR_RSID
, RES_CHRATR_RSID
> aSet(GetAttrPool());
426 bool const bRet(pTextNode
->SetAttr(aSet
, nStart
,
427 rRg
.GetPoint()->GetContentIndex()));
429 if (bRet
&& GetIDocumentUndoRedo().DoesUndo())
431 SwUndo
*const pLastUndo
= GetUndoManager().GetLastUndo();
432 SwUndoInsert
*const pUndoInsert(dynamic_cast<SwUndoInsert
*>(pLastUndo
));
433 // this function is called after Insert so expects to find SwUndoInsert
437 pUndoInsert
->SetWithRsid();
442 bool SwDoc::UpdateParRsid( SwTextNode
*pTextNode
, sal_uInt32 nVal
)
444 if (!SW_MOD()->GetModuleConfig()->IsStoreRsid())
452 SvxRsidItem
aRsid( nVal
? nVal
: mnRsid
, RES_PARATR_RSID
);
453 return pTextNode
->SetAttr( aRsid
);
456 /// Set the attribute according to the stated format.
457 /// If Undo is enabled, the old values is added to the Undo history.
458 void SwDoc::SetAttr( const SfxPoolItem
& rAttr
, SwFormat
& rFormat
)
460 SfxItemSet
aSet( GetAttrPool(), rAttr
.Which(), rAttr
.Which() );
462 SetAttr( aSet
, rFormat
);
465 /// Set the attribute according to the stated format.
466 /// If Undo is enabled, the old values is added to the Undo history.
467 void SwDoc::SetAttr( const SfxItemSet
& rSet
, SwFormat
& rFormat
)
469 if (GetIDocumentUndoRedo().DoesUndo())
471 SwUndoFormatAttrHelper
aTmp( rFormat
);
472 rFormat
.SetFormatAttr( rSet
);
473 if ( aTmp
.GetUndo() )
475 GetIDocumentUndoRedo().AppendUndo( aTmp
.ReleaseUndo() );
479 GetIDocumentUndoRedo().ClearRedo();
484 rFormat
.SetFormatAttr( rSet
);
487 // If the format is a shape, and it has a textbox, sync.
488 auto pShapeFormat
= dynamic_cast<SwFrameFormat
*>(&rFormat
);
489 if (pShapeFormat
&& SwTextBoxHelper::isTextBox(pShapeFormat
, RES_DRAWFRMFMT
))
491 if (auto pObj
= pShapeFormat
->FindRealSdrObject())
493 SwTextBoxHelper::syncFlyFrameAttr(*pShapeFormat
, rSet
, pObj
);
494 SwTextBoxHelper::changeAnchor(pShapeFormat
, pObj
);
498 getIDocumentState().SetModified();
501 void SwDoc::ResetAttrAtFormat( const sal_uInt16 nWhichId
,
502 SwFormat
& rChangedFormat
)
504 std::unique_ptr
<SwUndo
> pUndo
;
505 if (GetIDocumentUndoRedo().DoesUndo())
506 pUndo
.reset(new SwUndoFormatResetAttr( rChangedFormat
, nWhichId
));
508 const bool bAttrReset
= rChangedFormat
.ResetFormatAttr( nWhichId
);
514 GetIDocumentUndoRedo().AppendUndo( std::move(pUndo
) );
517 getIDocumentState().SetModified();
521 static bool lcl_SetNewDefTabStops( SwTwips nOldWidth
, SwTwips nNewWidth
,
522 SvxTabStopItem
& rChgTabStop
)
524 // Set the default values of all TabStops to the new value.
525 // Attention: we always work with the PoolAttribute here, so that
526 // we don't calculate the same value on the same TabStop (pooled!) for all sets.
527 // We send a FormatChg to modify.
529 sal_uInt16 nOldCnt
= rChgTabStop
.Count();
530 if( !nOldCnt
|| nOldWidth
== nNewWidth
)
533 // Find the default's beginning
535 for( n
= nOldCnt
; n
; --n
)
536 if( SvxTabAdjust::Default
!= rChgTabStop
[n
- 1].GetAdjustment() )
539 if( n
< nOldCnt
) // delete the DefTabStops
540 rChgTabStop
.Remove( n
, nOldCnt
- n
);
544 /// Set the attribute as new default attribute in this document.
545 /// If Undo is enabled, the old value is added to the Undo history.
546 void SwDoc::SetDefault( const SfxPoolItem
& rAttr
)
548 SfxItemSet
aSet( GetAttrPool(), rAttr
.Which(), rAttr
.Which() );
553 void SwDoc::SetDefault( const SfxItemSet
& rSet
)
558 sw::BroadcastingModify aCallMod
;
559 SwAttrSet
aOld( GetAttrPool(), rSet
.GetRanges() ),
560 aNew( GetAttrPool(), rSet
.GetRanges() );
561 SfxItemIter
aIter( rSet
);
562 const SfxPoolItem
* pItem
= aIter
.GetCurItem();
563 SfxItemPool
* pSdrPool
= GetAttrPool().GetSecondaryPool();
566 bool bCheckSdrDflt
= false;
567 const sal_uInt16 nWhich
= pItem
->Which();
568 aOld
.Put( GetAttrPool().GetDefaultItem( nWhich
) );
569 GetAttrPool().SetPoolDefaultItem( *pItem
);
570 aNew
.Put( GetAttrPool().GetDefaultItem( nWhich
) );
572 if (isCHRATR(nWhich
) || isTXTATR(nWhich
))
574 aCallMod
.Add( mpDfltTextFormatColl
.get() );
575 aCallMod
.Add( mpDfltCharFormat
.get() );
576 bCheckSdrDflt
= nullptr != pSdrPool
;
578 else if ( isPARATR(nWhich
) ||
579 isPARATR_LIST(nWhich
) )
581 aCallMod
.Add( mpDfltTextFormatColl
.get() );
582 bCheckSdrDflt
= nullptr != pSdrPool
;
584 else if (isGRFATR(nWhich
))
586 aCallMod
.Add( mpDfltGrfFormatColl
.get() );
588 else if (isFRMATR(nWhich
) || isDrawingLayerAttribute(nWhich
) )
590 aCallMod
.Add( mpDfltGrfFormatColl
.get() );
591 aCallMod
.Add( mpDfltTextFormatColl
.get() );
592 aCallMod
.Add( mpDfltFrameFormat
.get() );
594 else if (isBOXATR(nWhich
))
596 aCallMod
.Add( mpDfltFrameFormat
.get() );
599 // also copy the defaults
602 sal_uInt16 nSlotId
= GetAttrPool().GetSlotId( nWhich
);
603 if( 0 != nSlotId
&& nSlotId
!= nWhich
)
605 sal_uInt16 nEdtWhich
= pSdrPool
->GetWhich( nSlotId
);
606 if( 0 != nEdtWhich
&& nSlotId
!= nEdtWhich
)
608 std::unique_ptr
<SfxPoolItem
> pCpy(pItem
->Clone());
609 pCpy
->SetWhich( nEdtWhich
);
610 pSdrPool
->SetPoolDefaultItem( *pCpy
);
615 pItem
= aIter
.NextItem();
618 if( aNew
.Count() && aCallMod
.HasWriterListeners() )
620 if (GetIDocumentUndoRedo().DoesUndo())
622 GetIDocumentUndoRedo().AppendUndo( std::make_unique
<SwUndoDefaultAttr
>( aOld
, *this ) );
625 const SvxTabStopItem
* pTmpItem
= aNew
.GetItemIfSet( RES_PARATR_TABSTOP
, false );
626 if( pTmpItem
&& pTmpItem
->Count() )
628 // Set the default values of all TabStops to the new value.
629 // Attention: we always work with the PoolAttribute here, so that
630 // we don't calculate the same value on the same TabStop (pooled!) for all sets.
631 // We send a FormatChg to modify.
632 SwTwips nNewWidth
= (*pTmpItem
)[ 0 ].GetTabPos(),
633 nOldWidth
= aOld
.Get(RES_PARATR_TABSTOP
)[ 0 ].GetTabPos();
636 for (const SfxPoolItem
* pItem2
: GetAttrPool().GetItemSurrogates(RES_PARATR_TABSTOP
))
638 if(auto pTabStopItem
= pItem2
->DynamicWhichCast(RES_PARATR_TABSTOP
))
639 bChg
|= lcl_SetNewDefTabStops( nOldWidth
, nNewWidth
,
640 *const_cast<SvxTabStopItem
*>(pTabStopItem
) );
643 aNew
.ClearItem( RES_PARATR_TABSTOP
);
644 aOld
.ClearItem( RES_PARATR_TABSTOP
);
647 SwFormatChg
aChgFormat( mpDfltCharFormat
.get() );
649 aCallMod
.CallSwClientNotify(sw::LegacyModifyHint( &aChgFormat
, &aChgFormat
));
654 if( aNew
.Count() && aCallMod
.HasWriterListeners() )
656 SwAttrSetChg
aChgOld( aOld
, aOld
);
657 SwAttrSetChg
aChgNew( aNew
, aNew
);
658 aCallMod
.CallSwClientNotify(sw::LegacyModifyHint( &aChgOld
, &aChgNew
)); // all changed are sent
661 // remove the default formats from the object again
662 SwIterator
<SwClient
, sw::BroadcastingModify
> aClientIter(aCallMod
);
663 for(SwClient
* pClient
= aClientIter
.First(); pClient
; pClient
= aClientIter
.Next())
664 aCallMod
.Remove( pClient
);
666 getIDocumentState().SetModified();
669 /// Get the default attribute in this document
670 const SfxPoolItem
& SwDoc::GetDefault( sal_uInt16 nFormatHint
) const
672 return GetAttrPool().GetDefaultItem( nFormatHint
);
675 /// Delete the formats
676 void SwDoc::DelCharFormat(size_t nFormat
, bool bBroadcast
)
678 SwCharFormat
* pDel
= (*mpCharFormatTable
)[nFormat
];
681 BroadcastStyleOperation(pDel
->GetName(), SfxStyleFamily::Char
,
682 SfxHintId::StyleSheetErased
);
684 if (GetIDocumentUndoRedo().DoesUndo())
686 GetIDocumentUndoRedo().AppendUndo(
687 std::make_unique
<SwUndoCharFormatDelete
>(pDel
, *this));
690 delete (*mpCharFormatTable
)[nFormat
];
691 mpCharFormatTable
->erase(mpCharFormatTable
->begin() + nFormat
);
693 getIDocumentState().SetModified();
696 void SwDoc::DelCharFormat( SwCharFormat
const *pFormat
, bool bBroadcast
)
698 size_t nFormat
= mpCharFormatTable
->GetPos( pFormat
);
699 OSL_ENSURE( SIZE_MAX
!= nFormat
, "Format not found," );
700 DelCharFormat( nFormat
, bBroadcast
);
703 void SwDoc::DelFrameFormat( SwFrameFormat
*pFormat
, bool bBroadcast
)
705 if( dynamic_cast<const SwTableBoxFormat
*>( pFormat
) != nullptr || dynamic_cast<const SwTableLineFormat
*>( pFormat
) != nullptr )
707 OSL_ENSURE( false, "Format is not in the DocArray any more, "
708 "so it can be deleted with delete" );
713 // The format has to be in the one or the other, we'll see in which one.
714 if (mpFrameFormatTable
->ContainsFormat(pFormat
))
717 BroadcastStyleOperation(pFormat
->GetName(),
718 SfxStyleFamily::Frame
,
719 SfxHintId::StyleSheetErased
);
721 if (GetIDocumentUndoRedo().DoesUndo())
723 GetIDocumentUndoRedo().AppendUndo(
724 std::make_unique
<SwUndoFrameFormatDelete
>(pFormat
, *this));
727 mpFrameFormatTable
->erase( pFormat
);
732 auto pSpz
= static_cast<sw::SpzFrameFormat
*>(pFormat
);
733 if(GetSpzFrameFormats()->ContainsFormat(pSpz
))
735 GetSpzFrameFormats()->erase(pSpz
);
739 SAL_WARN("sw", "FrameFormat not found.");
744 void SwDoc::DelTableFrameFormat( SwTableFormat
*pFormat
)
746 auto it
= mpTableFrameFormatTable
->find( pFormat
);
747 OSL_ENSURE( it
!= mpTableFrameFormatTable
->end(), "Format not found," );
748 mpTableFrameFormatTable
->erase( it
);
752 SwFrameFormat
* SwDoc::FindFrameFormatByName( const OUString
& rName
) const
754 return static_cast<SwFrameFormat
*>(mpFrameFormatTable
->FindFormatByName(rName
));
757 /// Create the formats
758 SwFlyFrameFormat
*SwDoc::MakeFlyFrameFormat( const OUString
&rFormatName
,
759 SwFrameFormat
*pDerivedFrom
)
761 SwFlyFrameFormat
*pFormat
= new SwFlyFrameFormat( GetAttrPool(), rFormatName
, pDerivedFrom
);
762 GetSpzFrameFormats()->push_back(pFormat
);
763 getIDocumentState().SetModified();
767 SwDrawFrameFormat
*SwDoc::MakeDrawFrameFormat( const OUString
&rFormatName
,
768 SwFrameFormat
*pDerivedFrom
)
770 SwDrawFrameFormat
*pFormat
= new SwDrawFrameFormat( GetAttrPool(), rFormatName
, pDerivedFrom
);
771 GetSpzFrameFormats()->push_back(pFormat
);
772 getIDocumentState().SetModified();
776 size_t SwDoc::GetTableFrameFormatCount(bool bUsed
) const
780 return mpTableFrameFormatTable
->size();
783 SwAutoFormatGetDocNode
aGetHt(&GetNodes());
785 for (const SwTableFormat
* pFormat
: *mpTableFrameFormatTable
)
787 if (!pFormat
->GetInfo(aGetHt
))
793 SwTableFormat
& SwDoc::GetTableFrameFormat(size_t nFormat
, bool bUsed
) const
797 return *const_cast<SwTableFormat
*>((*mpTableFrameFormatTable
)[nFormat
]);
800 SwAutoFormatGetDocNode
aGetHt(&GetNodes());
804 for(SwTableFormat
* pFormat
: *mpTableFrameFormatTable
)
806 if (!pFormat
->GetInfo(aGetHt
))
808 if (index
== nFormat
)
814 throw std::out_of_range("Format index out of range.");
817 SwTableFormat
* SwDoc::MakeTableFrameFormat( const OUString
&rFormatName
,
818 SwFrameFormat
*pDerivedFrom
)
820 SwTableFormat
* pFormat
= new SwTableFormat( GetAttrPool(), rFormatName
, pDerivedFrom
);
821 mpTableFrameFormatTable
->push_back( pFormat
);
822 getIDocumentState().SetModified();
827 SwFrameFormat
*SwDoc::MakeFrameFormat(const OUString
&rFormatName
,
828 SwFrameFormat
*pDerivedFrom
,
829 bool bBroadcast
, bool bAuto
)
831 SwFrameFormat
*pFormat
= new SwFrameFormat( GetAttrPool(), rFormatName
, pDerivedFrom
);
833 pFormat
->SetAuto(bAuto
);
834 mpFrameFormatTable
->push_back( pFormat
);
835 getIDocumentState().SetModified();
837 if (GetIDocumentUndoRedo().DoesUndo())
839 GetIDocumentUndoRedo().AppendUndo(
840 std::make_unique
<SwUndoFrameFormatCreate
>(pFormat
, pDerivedFrom
, *this));
845 BroadcastStyleOperation(rFormatName
, SfxStyleFamily::Frame
,
846 SfxHintId::StyleSheetCreated
);
852 SwFormat
*SwDoc::MakeFrameFormat_(const OUString
&rFormatName
,
853 SwFormat
*pDerivedFrom
,
854 bool bBroadcast
, bool bAuto
)
856 SwFrameFormat
*pFrameFormat
= dynamic_cast<SwFrameFormat
*>(pDerivedFrom
);
857 pFrameFormat
= MakeFrameFormat( rFormatName
, pFrameFormat
, bBroadcast
, bAuto
);
861 SwCharFormat
*SwDoc::MakeCharFormat( const OUString
&rFormatName
,
862 SwCharFormat
*pDerivedFrom
,
865 SwCharFormat
*pFormat
= new SwCharFormat( GetAttrPool(), rFormatName
, pDerivedFrom
);
866 mpCharFormatTable
->insert( pFormat
);
867 pFormat
->SetAuto(false);
868 getIDocumentState().SetModified();
870 if (GetIDocumentUndoRedo().DoesUndo())
872 GetIDocumentUndoRedo().AppendUndo(
873 std::make_unique
<SwUndoCharFormatCreate
>(pFormat
, pDerivedFrom
, *this));
878 BroadcastStyleOperation(rFormatName
, SfxStyleFamily::Char
,
879 SfxHintId::StyleSheetCreated
);
885 SwFormat
*SwDoc::MakeCharFormat_(const OUString
&rFormatName
,
886 SwFormat
*pDerivedFrom
,
887 bool bBroadcast
, bool /*bAuto*/)
889 SwCharFormat
*pCharFormat
= dynamic_cast<SwCharFormat
*>(pDerivedFrom
);
890 pCharFormat
= MakeCharFormat( rFormatName
, pCharFormat
, bBroadcast
);
894 /// Create the FormatCollections
895 SwTextFormatColl
* SwDoc::MakeTextFormatColl( const OUString
&rFormatName
,
896 SwTextFormatColl
*pDerivedFrom
,
899 SwTextFormatColl
*pFormatColl
= new SwTextFormatColl( GetAttrPool(), rFormatName
,
901 mpTextFormatCollTable
->push_back(pFormatColl
);
902 pFormatColl
->SetAuto(false);
903 getIDocumentState().SetModified();
905 if (GetIDocumentUndoRedo().DoesUndo())
907 GetIDocumentUndoRedo().AppendUndo(
908 std::make_unique
<SwUndoTextFormatCollCreate
>(pFormatColl
, pDerivedFrom
,
913 BroadcastStyleOperation(rFormatName
, SfxStyleFamily::Para
,
914 SfxHintId::StyleSheetCreated
);
919 SwFormat
*SwDoc::MakeTextFormatColl_(const OUString
&rFormatName
,
920 SwFormat
*pDerivedFrom
,
921 bool bBroadcast
, bool /*bAuto*/)
923 SwTextFormatColl
*pTextFormatColl
= dynamic_cast<SwTextFormatColl
*>(pDerivedFrom
);
924 pTextFormatColl
= MakeTextFormatColl( rFormatName
, pTextFormatColl
, bBroadcast
);
925 return pTextFormatColl
;
928 SwConditionTextFormatColl
* SwDoc::MakeCondTextFormatColl( const OUString
&rFormatName
,
929 SwTextFormatColl
*pDerivedFrom
,
932 SwConditionTextFormatColl
*pFormatColl
= new SwConditionTextFormatColl( GetAttrPool(),
933 rFormatName
, pDerivedFrom
);
934 mpTextFormatCollTable
->push_back(pFormatColl
);
935 pFormatColl
->SetAuto(false);
936 getIDocumentState().SetModified();
938 if (GetIDocumentUndoRedo().DoesUndo())
940 GetIDocumentUndoRedo().AppendUndo(
941 std::make_unique
<SwUndoCondTextFormatCollCreate
>(pFormatColl
, pDerivedFrom
,
946 BroadcastStyleOperation(rFormatName
, SfxStyleFamily::Para
,
947 SfxHintId::StyleSheetCreated
);
953 SwGrfFormatColl
* SwDoc::MakeGrfFormatColl( const OUString
&rFormatName
,
954 SwGrfFormatColl
*pDerivedFrom
)
956 SwGrfFormatColl
*pFormatColl
= new SwGrfFormatColl( GetAttrPool(), rFormatName
,
958 mpGrfFormatCollTable
->push_back( pFormatColl
);
959 pFormatColl
->SetAuto(false);
960 getIDocumentState().SetModified();
964 void SwDoc::DelTextFormatColl(size_t nFormatColl
, bool bBroadcast
)
966 OSL_ENSURE( nFormatColl
, "Remove of Coll 0." );
968 // Who has the to-be-deleted as their Next?
969 SwTextFormatColl
*pDel
= (*mpTextFormatCollTable
)[nFormatColl
];
970 if( mpDfltTextFormatColl
.get() == pDel
)
971 return; // never delete default!
974 BroadcastStyleOperation(pDel
->GetName(), SfxStyleFamily::Para
,
975 SfxHintId::StyleSheetErased
);
977 if (GetIDocumentUndoRedo().DoesUndo())
979 std::unique_ptr
<SwUndoTextFormatCollDelete
> pUndo
;
980 if (RES_CONDTXTFMTCOLL
== pDel
->Which())
982 pUndo
.reset(new SwUndoCondTextFormatCollDelete(pDel
, *this));
986 pUndo
.reset(new SwUndoTextFormatCollDelete(pDel
, *this));
989 GetIDocumentUndoRedo().AppendUndo(std::move(pUndo
));
992 // Remove the FormatColl
993 mpTextFormatCollTable
->erase(mpTextFormatCollTable
->begin() + nFormatColl
);
995 for( SwTextFormatColls::const_iterator it
= mpTextFormatCollTable
->begin() + 1; it
!= mpTextFormatCollTable
->end(); ++it
)
996 SetTextFormatCollNext( *it
, pDel
);
998 getIDocumentState().SetModified();
1001 void SwDoc::DelTextFormatColl( SwTextFormatColl
const *pColl
, bool bBroadcast
)
1003 size_t nFormat
= mpTextFormatCollTable
->GetPos( pColl
);
1004 OSL_ENSURE( SIZE_MAX
!= nFormat
, "Collection not found," );
1005 DelTextFormatColl( nFormat
, bBroadcast
);
1008 static bool lcl_SetTextFormatColl( SwNode
* pNode
, void* pArgs
)
1010 SwContentNode
* pCNd
= pNode
->GetTextNode();
1012 if( pCNd
== nullptr)
1015 sw::DocumentContentOperationsManager::ParaRstFormat
* pPara
= static_cast<sw::DocumentContentOperationsManager::ParaRstFormat
*>(pArgs
);
1017 if (pPara
->pLayout
&& pPara
->pLayout
->HasMergedParas())
1019 if (pCNd
->GetRedlineMergeFlag() == SwNode::Merge::Hidden
)
1023 if (pCNd
->IsTextNode())
1025 pCNd
= sw::GetParaPropsNode(*pPara
->pLayout
, *pCNd
);
1029 SwTextFormatColl
* pFormat
= static_cast<SwTextFormatColl
*>(pPara
->pFormatColl
);
1030 if ( pPara
->bReset
)
1032 lcl_RstAttr(pCNd
, pPara
);
1034 // #i62675# check, if paragraph style has changed
1035 if ( pPara
->bResetListAttrs
&&
1036 pFormat
!= pCNd
->GetFormatColl() &&
1037 pFormat
->GetItemState( RES_PARATR_NUMRULE
) == SfxItemState::SET
)
1039 // Check, if the list style of the paragraph will change.
1040 bool bChangeOfListStyleAtParagraph( true );
1041 SwTextNode
& rTNd(*pCNd
->GetTextNode());
1043 SwNumRule
* pNumRuleAtParagraph(rTNd
.GetNumRule());
1044 if ( pNumRuleAtParagraph
)
1046 const SwNumRuleItem
& rNumRuleItemAtParagraphStyle
=
1047 pFormat
->GetNumRule();
1048 if ( rNumRuleItemAtParagraphStyle
.GetValue() ==
1049 pNumRuleAtParagraph
->GetName() )
1051 bChangeOfListStyleAtParagraph
= false;
1056 if ( bChangeOfListStyleAtParagraph
)
1058 std::unique_ptr
< SwRegHistory
> pRegH
;
1059 if ( pPara
->pHistory
)
1061 pRegH
.reset(new SwRegHistory(&rTNd
, rTNd
, pPara
->pHistory
));
1064 pCNd
->ResetAttr( RES_PARATR_NUMRULE
);
1066 // reset all list attributes
1067 pCNd
->ResetAttr( RES_PARATR_LIST_LEVEL
);
1068 pCNd
->ResetAttr( RES_PARATR_LIST_ISRESTART
);
1069 pCNd
->ResetAttr( RES_PARATR_LIST_RESTARTVALUE
);
1070 pCNd
->ResetAttr( RES_PARATR_LIST_ISCOUNTED
);
1071 pCNd
->ResetAttr( RES_PARATR_LIST_ID
);
1076 // add to History so that old data is saved, if necessary
1077 if( pPara
->pHistory
)
1078 pPara
->pHistory
->Add( pCNd
->GetFormatColl(), pCNd
->GetIndex(),
1081 pCNd
->ChgFormatColl( pFormat
);
1088 bool SwDoc::SetTextFormatColl(const SwPaM
&rRg
,
1089 SwTextFormatColl
*pFormat
,
1091 const bool bResetListAttrs
,
1092 SwRootFrame
const*const pLayout
)
1094 SwDataChanged
aTmp( rRg
);
1095 auto [pStt
, pEnd
] = rRg
.StartEnd(); // SwPosition*
1096 SwHistory
* pHst
= nullptr;
1099 if (GetIDocumentUndoRedo().DoesUndo())
1101 std::unique_ptr
<SwUndoFormatColl
> pUndo(new SwUndoFormatColl( rRg
, pFormat
,
1104 pHst
= pUndo
->GetHistory();
1105 GetIDocumentUndoRedo().AppendUndo(std::move(pUndo
));
1108 sw::DocumentContentOperationsManager::ParaRstFormat
aPara(
1109 pStt
, pEnd
, pHst
, nullptr, pLayout
);
1110 aPara
.pFormatColl
= pFormat
;
1111 aPara
.bReset
= bReset
;
1113 aPara
.bResetListAttrs
= bResetListAttrs
;
1115 GetNodes().ForEach( pStt
->GetNodeIndex(), pEnd
->GetNodeIndex()+1,
1116 lcl_SetTextFormatColl
, &aPara
);
1118 bRet
= false; // didn't find a valid Node
1122 getIDocumentState().SetModified();
1128 /// Copy the formats to itself
1129 SwFormat
* SwDoc::CopyFormat( const SwFormat
& rFormat
,
1130 const SwFormatsBase
& rFormatArr
,
1131 FNCopyFormat fnCopyFormat
, const SwFormat
& rDfltFormat
)
1133 // It's no autoformat, default format or collection format,
1134 // then search for it.
1135 if( !rFormat
.IsAuto() || !rFormat
.GetRegisteredIn() )
1136 for( size_t n
= 0; n
< rFormatArr
.GetFormatCount(); ++n
)
1138 // Does the Doc already contain the template?
1139 if( rFormatArr
.GetFormat(n
)->GetName()==rFormat
.GetName() )
1140 return rFormatArr
.GetFormat(n
);
1143 // Search for the "parent" first
1144 SwFormat
* pParent
= const_cast<SwFormat
*>(&rDfltFormat
);
1145 if( rFormat
.DerivedFrom() && pParent
!= rFormat
.DerivedFrom() )
1146 pParent
= CopyFormat( *rFormat
.DerivedFrom(), rFormatArr
,
1147 fnCopyFormat
, rDfltFormat
);
1149 // Create the format and copy the attributes
1151 SwFormat
* pNewFormat
= (this->*fnCopyFormat
)( rFormat
.GetName(), pParent
, false, true );
1152 pNewFormat
->SetAuto( rFormat
.IsAuto() );
1153 pNewFormat
->CopyAttrs( rFormat
); // copy the attributes
1155 pNewFormat
->SetPoolFormatId( rFormat
.GetPoolFormatId() );
1156 pNewFormat
->SetPoolHelpId( rFormat
.GetPoolHelpId() );
1158 // Always set the HelpFile Id to default!
1159 pNewFormat
->SetPoolHlpFileId( UCHAR_MAX
);
1164 /// copy the frame format
1165 SwFrameFormat
* SwDoc::CopyFrameFormat( const SwFrameFormat
& rFormat
)
1167 return static_cast<SwFrameFormat
*>(CopyFormat( rFormat
, *GetFrameFormats(), &SwDoc::MakeFrameFormat_
,
1168 *GetDfltFrameFormat() ));
1171 /// copy the char format
1172 SwCharFormat
* SwDoc::CopyCharFormat( const SwCharFormat
& rFormat
)
1174 return static_cast<SwCharFormat
*>(CopyFormat( rFormat
, *GetCharFormats(),
1175 &SwDoc::MakeCharFormat_
,
1176 *GetDfltCharFormat() ));
1180 SwTextFormatColl
* SwDoc::CopyTextColl( const SwTextFormatColl
& rColl
)
1182 SwTextFormatColl
* pNewColl
= FindTextFormatCollByName( rColl
.GetName() );
1186 // search for the "parent" first
1187 SwTextFormatColl
* pParent
= mpDfltTextFormatColl
.get();
1188 if( pParent
!= rColl
.DerivedFrom() )
1189 pParent
= CopyTextColl( *static_cast<SwTextFormatColl
*>(rColl
.DerivedFrom()) );
1191 if( RES_CONDTXTFMTCOLL
== rColl
.Which() )
1193 pNewColl
= new SwConditionTextFormatColl( GetAttrPool(), rColl
.GetName(),
1195 mpTextFormatCollTable
->push_back( pNewColl
);
1196 pNewColl
->SetAuto(false);
1197 getIDocumentState().SetModified();
1199 // copy the conditions
1200 static_cast<SwConditionTextFormatColl
*>(pNewColl
)->SetConditions(
1201 static_cast<const SwConditionTextFormatColl
&>(rColl
).GetCondColls() );
1204 pNewColl
= MakeTextFormatColl( rColl
.GetName(), pParent
);
1206 // copy the auto formats or the attributes
1207 pNewColl
->CopyAttrs( rColl
);
1209 if(rColl
.IsAssignedToListLevelOfOutlineStyle())
1210 pNewColl
->AssignToListLevelOfOutlineStyle(rColl
.GetAssignedOutlineStyleLevel());
1211 pNewColl
->SetPoolFormatId( rColl
.GetPoolFormatId() );
1212 pNewColl
->SetPoolHelpId( rColl
.GetPoolHelpId() );
1214 // Always set the HelpFile Id to default!
1215 pNewColl
->SetPoolHlpFileId( UCHAR_MAX
);
1217 if( &rColl
.GetNextTextFormatColl() != &rColl
)
1218 pNewColl
->SetNextTextFormatColl( *CopyTextColl( rColl
.GetNextTextFormatColl() ));
1220 // create the NumRule if necessary
1221 if( this != rColl
.GetDoc() )
1223 const SwNumRuleItem
* pItem
= pNewColl
->GetItemIfSet( RES_PARATR_NUMRULE
,
1227 const OUString
& rName
= pItem
->GetValue();
1228 if( !rName
.isEmpty() )
1230 const SwNumRule
* pRule
= rColl
.GetDoc()->FindNumRulePtr( rName
);
1231 if( pRule
&& !pRule
->IsAutoRule() )
1233 SwNumRule
* pDestRule
= FindNumRulePtr( rName
);
1235 pDestRule
->SetInvalidRule( true );
1237 MakeNumRule( rName
, pRule
);
1245 /// copy the graphic nodes
1246 SwGrfFormatColl
* SwDoc::CopyGrfColl( const SwGrfFormatColl
& rColl
)
1248 SwGrfFormatColl
* pNewColl
= mpGrfFormatCollTable
->FindFormatByName( rColl
.GetName() );
1252 // Search for the "parent" first
1253 SwGrfFormatColl
* pParent
= mpDfltGrfFormatColl
.get();
1254 if( pParent
!= rColl
.DerivedFrom() )
1255 pParent
= CopyGrfColl( *static_cast<SwGrfFormatColl
*>(rColl
.DerivedFrom()) );
1257 // if not, copy them
1258 pNewColl
= MakeGrfFormatColl( rColl
.GetName(), pParent
);
1260 // copy the attributes
1261 pNewColl
->CopyAttrs( rColl
);
1263 pNewColl
->SetPoolFormatId( rColl
.GetPoolFormatId() );
1264 pNewColl
->SetPoolHelpId( rColl
.GetPoolHelpId() );
1266 // Always set the HelpFile Id to default!
1267 pNewColl
->SetPoolHlpFileId( UCHAR_MAX
);
1272 void SwDoc::CopyFormatArr( const SwFormatsBase
& rSourceArr
,
1273 SwFormatsBase
const & rDestArr
,
1274 FNCopyFormat fnCopyFormat
,
1275 SwFormat
& rDfltFormat
)
1277 SwFormat
* pSrc
, *pDest
;
1279 // 1st step: Create all formats (skip the 0th - it's the default one)
1280 for( size_t nSrc
= rSourceArr
.GetFormatCount(); nSrc
> 1; )
1282 pSrc
= rSourceArr
.GetFormat( --nSrc
);
1283 if( pSrc
->IsDefault() || pSrc
->IsAuto() )
1286 if( nullptr == rDestArr
.FindFormatByName( pSrc
->GetName() ) )
1288 if( RES_CONDTXTFMTCOLL
== pSrc
->Which() )
1289 MakeCondTextFormatColl( pSrc
->GetName(), static_cast<SwTextFormatColl
*>(&rDfltFormat
) );
1292 (this->*fnCopyFormat
)( pSrc
->GetName(), &rDfltFormat
, false, true );
1296 // 2nd step: Copy all attributes, set the right parents
1297 for( size_t nSrc
= rSourceArr
.GetFormatCount(); nSrc
> 1; )
1299 pSrc
= rSourceArr
.GetFormat( --nSrc
);
1300 if( pSrc
->IsDefault() || pSrc
->IsAuto() )
1303 pDest
= rDestArr
.FindFormatByName( pSrc
->GetName() );
1304 pDest
->SetAuto(false);
1305 pDest
->DelDiffs( *pSrc
);
1307 // #i94285#: existing <SwFormatPageDesc> instance, before copying attributes
1308 const SwFormatPageDesc
* pItem
;
1309 if( &GetAttrPool() != pSrc
->GetAttrSet().GetPool()
1310 && (pItem
= pSrc
->GetAttrSet().GetItemIfSet( RES_PAGEDESC
, false ))
1311 && pItem
->GetPageDesc() )
1313 SwFormatPageDesc
aPageDesc( *pItem
);
1314 const OUString
& rNm
= aPageDesc
.GetPageDesc()->GetName();
1315 SwPageDesc
* pPageDesc
= FindPageDesc( rNm
);
1318 pPageDesc
= MakePageDesc(rNm
);
1320 aPageDesc
.RegisterToPageDesc( *pPageDesc
);
1321 SwAttrSet
aTmpAttrSet( pSrc
->GetAttrSet() );
1322 aTmpAttrSet
.Put( aPageDesc
);
1323 pDest
->SetFormatAttr( aTmpAttrSet
);
1327 pDest
->SetFormatAttr( pSrc
->GetAttrSet() );
1330 pDest
->SetPoolFormatId( pSrc
->GetPoolFormatId() );
1331 pDest
->SetPoolHelpId( pSrc
->GetPoolHelpId() );
1333 // Always set the HelpFile Id to default!
1334 pDest
->SetPoolHlpFileId( UCHAR_MAX
);
1336 if( pSrc
->DerivedFrom() )
1337 pDest
->SetDerivedFrom( rDestArr
.FindFormatByName(
1338 pSrc
->DerivedFrom()->GetName() ) );
1339 if( RES_TXTFMTCOLL
== pSrc
->Which() ||
1340 RES_CONDTXTFMTCOLL
== pSrc
->Which() )
1342 SwTextFormatColl
* pSrcColl
= static_cast<SwTextFormatColl
*>(pSrc
),
1343 * pDstColl
= static_cast<SwTextFormatColl
*>(pDest
);
1344 if( &pSrcColl
->GetNextTextFormatColl() != pSrcColl
)
1345 pDstColl
->SetNextTextFormatColl(
1346 *static_cast<SwTextFormatColl
*>(rDestArr
.FindFormatByName( pSrcColl
->GetNextTextFormatColl().GetName() )) );
1348 if(pSrcColl
->IsAssignedToListLevelOfOutlineStyle())
1349 pDstColl
->AssignToListLevelOfOutlineStyle(pSrcColl
->GetAssignedOutlineStyleLevel());
1351 if( RES_CONDTXTFMTCOLL
== pSrc
->Which() )
1353 if (pDstColl
->Which() != RES_CONDTXTFMTCOLL
)
1355 // Target already had a style with a matching name, but it's not a conditional
1356 // style, then don't copy the conditions.
1360 // Copy the conditions, but delete the old ones first!
1361 static_cast<SwConditionTextFormatColl
*>(pDstColl
)->SetConditions(
1362 static_cast<SwConditionTextFormatColl
*>(pSrc
)->GetCondColls() );
1368 void SwDoc::CopyPageDescHeaderFooterImpl( bool bCpyHeader
,
1369 const SwFrameFormat
& rSrcFormat
, SwFrameFormat
& rDestFormat
)
1371 // Treat the header and footer attributes in the right way:
1372 // Copy content nodes across documents!
1373 sal_uInt16 nAttr
= bCpyHeader
? sal_uInt16(RES_HEADER
) : sal_uInt16(RES_FOOTER
);
1374 const SfxPoolItem
* pItem
;
1375 if( SfxItemState::SET
!= rSrcFormat
.GetAttrSet().GetItemState( nAttr
, false, &pItem
))
1378 // The header only contains the reference to the format from the other document!
1379 std::unique_ptr
<SfxPoolItem
> pNewItem(pItem
->Clone());
1381 SwFrameFormat
* pOldFormat
;
1383 pOldFormat
= pNewItem
->StaticWhichCast(RES_HEADER
).GetHeaderFormat();
1385 pOldFormat
= pNewItem
->StaticWhichCast(RES_FOOTER
).GetFooterFormat();
1390 SwFrameFormat
* pNewFormat
= new SwFrameFormat( GetAttrPool(), "CpyDesc",
1391 GetDfltFrameFormat() );
1392 pNewFormat
->CopyAttrs( *pOldFormat
);
1394 if( const SwFormatContent
* pContent
= pNewFormat
->GetAttrSet().GetItemIfSet(
1395 RES_CNTNT
, false ) )
1397 if( pContent
->GetContentIdx() )
1399 const SwNodes
& rSrcNds
= rSrcFormat
.GetDoc()->GetNodes();
1400 SwStartNode
* pSttNd
= SwNodes::MakeEmptySection( GetNodes().GetEndOfAutotext(),
1403 : SwFooterStartNode
);
1404 const SwNode
& rCSttNd
= pContent
->GetContentIdx()->GetNode();
1405 SwNodeRange
aRg( rCSttNd
, SwNodeOffset(0), *rCSttNd
.EndOfSectionNode() );
1406 rSrcNds
.Copy_( aRg
, *pSttNd
->EndOfSectionNode() );
1407 rSrcFormat
.GetDoc()->GetDocumentContentOperationsManager().CopyFlyInFlyImpl(aRg
, nullptr, *pSttNd
);
1408 // TODO: investigate calling CopyWithFlyInFly?
1409 SwPaM
const source(aRg
.aStart
, aRg
.aEnd
);
1410 SwPosition
dest(*pSttNd
);
1411 sw::CopyBookmarks(source
, dest
);
1412 pNewFormat
->SetFormatAttr( SwFormatContent( pSttNd
));
1415 pNewFormat
->ResetFormatAttr( RES_CNTNT
);
1418 pNewItem
->StaticWhichCast(RES_HEADER
).RegisterToFormat(*pNewFormat
);
1420 pNewItem
->StaticWhichCast(RES_FOOTER
).RegisterToFormat(*pNewFormat
);
1421 rDestFormat
.SetFormatAttr( *pNewItem
);
1424 void SwDoc::CopyPageDesc( const SwPageDesc
& rSrcDesc
, SwPageDesc
& rDstDesc
,
1427 bool bNotifyLayout
= false;
1428 SwRootFrame
* pTmpRoot
= getIDocumentLayoutAccess().GetCurrentLayout();
1430 rDstDesc
.SetLandscape( rSrcDesc
.GetLandscape() );
1431 rDstDesc
.SetNumType( rSrcDesc
.GetNumType() );
1432 if( rDstDesc
.ReadUseOn() != rSrcDesc
.ReadUseOn() )
1434 rDstDesc
.WriteUseOn( rSrcDesc
.ReadUseOn() );
1435 bNotifyLayout
= true;
1440 rDstDesc
.SetPoolFormatId( rSrcDesc
.GetPoolFormatId() );
1441 rDstDesc
.SetPoolHelpId( rSrcDesc
.GetPoolHelpId() );
1442 // Always set the HelpFile Id to default!
1443 rDstDesc
.SetPoolHlpFileId( UCHAR_MAX
);
1446 if( rSrcDesc
.GetFollow() != &rSrcDesc
)
1448 const SwPageDesc
* pSrcFollow
= rSrcDesc
.GetFollow();
1449 SwPageDesc
* pFollow
= FindPageDesc( pSrcFollow
->GetName() );
1453 pFollow
= MakePageDesc( pSrcFollow
->GetName() );
1454 CopyPageDesc( *pSrcFollow
, *pFollow
);
1456 rDstDesc
.SetFollow( pFollow
);
1457 bNotifyLayout
= true;
1460 // the header and footer attributes are copied separately
1461 // the content sections have to be copied in their entirety
1463 SfxItemSet
aAttrSet( rSrcDesc
.GetMaster().GetAttrSet() );
1464 aAttrSet
.ClearItem( RES_HEADER
);
1465 aAttrSet
.ClearItem( RES_FOOTER
);
1467 rDstDesc
.GetMaster().DelDiffs( aAttrSet
);
1468 rDstDesc
.GetMaster().SetFormatAttr( aAttrSet
);
1470 aAttrSet
.ClearItem();
1471 aAttrSet
.Put( rSrcDesc
.GetLeft().GetAttrSet() );
1472 aAttrSet
.ClearItem( RES_HEADER
);
1473 aAttrSet
.ClearItem( RES_FOOTER
);
1475 rDstDesc
.GetLeft().DelDiffs( aAttrSet
);
1476 rDstDesc
.GetLeft().SetFormatAttr( aAttrSet
);
1478 aAttrSet
.ClearItem();
1479 aAttrSet
.Put( rSrcDesc
.GetFirstMaster().GetAttrSet() );
1480 aAttrSet
.ClearItem( RES_HEADER
);
1481 aAttrSet
.ClearItem( RES_FOOTER
);
1483 rDstDesc
.GetFirstMaster().DelDiffs( aAttrSet
);
1484 rDstDesc
.GetFirstMaster().SetFormatAttr( aAttrSet
);
1486 aAttrSet
.ClearItem();
1487 aAttrSet
.Put( rSrcDesc
.GetFirstLeft().GetAttrSet() );
1488 aAttrSet
.ClearItem( RES_HEADER
);
1489 aAttrSet
.ClearItem( RES_FOOTER
);
1491 rDstDesc
.GetFirstLeft().DelDiffs( aAttrSet
);
1492 rDstDesc
.GetFirstLeft().SetFormatAttr( aAttrSet
);
1495 CopyHeader( rSrcDesc
.GetMaster(), rDstDesc
.GetMaster() );
1496 CopyFooter( rSrcDesc
.GetMaster(), rDstDesc
.GetMaster() );
1497 if( !rDstDesc
.IsHeaderShared() )
1498 CopyHeader( rSrcDesc
.GetLeft(), rDstDesc
.GetLeft() );
1500 rDstDesc
.GetLeft().SetFormatAttr( rDstDesc
.GetMaster().GetHeader() );
1501 if( !rDstDesc
.IsFirstShared() )
1503 CopyHeader( rSrcDesc
.GetFirstMaster(), rDstDesc
.GetFirstMaster() );
1504 rDstDesc
.GetFirstLeft().SetFormatAttr(rDstDesc
.GetFirstMaster().GetHeader());
1508 rDstDesc
.GetFirstMaster().SetFormatAttr( rDstDesc
.GetMaster().GetHeader() );
1509 rDstDesc
.GetFirstLeft().SetFormatAttr(rDstDesc
.GetLeft().GetHeader());
1512 if( !rDstDesc
.IsFooterShared() )
1513 CopyFooter( rSrcDesc
.GetLeft(), rDstDesc
.GetLeft() );
1515 rDstDesc
.GetLeft().SetFormatAttr( rDstDesc
.GetMaster().GetFooter() );
1516 if( !rDstDesc
.IsFirstShared() )
1518 CopyFooter( rSrcDesc
.GetFirstMaster(), rDstDesc
.GetFirstMaster() );
1519 rDstDesc
.GetFirstLeft().SetFormatAttr(rDstDesc
.GetFirstMaster().GetFooter());
1523 rDstDesc
.GetFirstMaster().SetFormatAttr( rDstDesc
.GetMaster().GetFooter() );
1524 rDstDesc
.GetFirstLeft().SetFormatAttr(rDstDesc
.GetLeft().GetFooter());
1527 if( bNotifyLayout
&& pTmpRoot
)
1529 for( auto aLayout
: GetAllLayouts() )
1530 aLayout
->AllCheckPageDescs();
1533 // If foot notes change the pages have to be triggered
1534 if( !(rDstDesc
.GetFootnoteInfo() == rSrcDesc
.GetFootnoteInfo()) )
1536 sw::PageFootnoteHint aHint
;
1537 rDstDesc
.SetFootnoteInfo( rSrcDesc
.GetFootnoteInfo() );
1538 rDstDesc
.GetMaster().CallSwClientNotify(aHint
);
1539 rDstDesc
.GetLeft().CallSwClientNotify(aHint
);
1540 rDstDesc
.GetFirstMaster().CallSwClientNotify(aHint
);
1541 rDstDesc
.GetFirstLeft().CallSwClientNotify(aHint
);
1544 // Copy the stashed formats as well between the page descriptors...
1545 for (bool bFirst
: { true, false })
1546 for (bool bLeft
: { true, false })
1547 for (bool bHeader
: { true, false })
1549 if (!bLeft
&& !bFirst
)
1551 if (auto pStashedFormat
= rSrcDesc
.GetStashedFrameFormat(bHeader
, bLeft
, bFirst
))
1552 rDstDesc
.StashFrameFormat(*pStashedFormat
, bHeader
, bLeft
, bFirst
);
1556 void SwDoc::ReplaceStyles( const SwDoc
& rSource
, bool bIncludePageStyles
)
1558 ::sw::UndoGuard
const undoGuard(GetIDocumentUndoRedo());
1560 CopyFormatArr( *rSource
.mpCharFormatTable
, *mpCharFormatTable
,
1561 &SwDoc::MakeCharFormat_
, *mpDfltCharFormat
);
1562 CopyFormatArr( *rSource
.mpFrameFormatTable
, *mpFrameFormatTable
,
1563 &SwDoc::MakeFrameFormat_
, *mpDfltFrameFormat
);
1564 CopyFormatArr( *rSource
.mpTextFormatCollTable
, *mpTextFormatCollTable
,
1565 &SwDoc::MakeTextFormatColl_
, *mpDfltTextFormatColl
);
1568 // a) in rtf export don't export our hideous pgdsctbl
1569 // extension to rtf anymore
1570 // b) in sd rtf import (View::InsertData) don't use
1571 // a super-fragile test for mere presence of \trowd to
1572 // indicate import of rtf into a table
1573 // c) then drop use of bIncludePageStyles
1574 if (bIncludePageStyles
)
1576 // and now the page templates
1577 SwPageDescs::size_type nCnt
= rSource
.m_PageDescs
.size();
1580 // a different Doc -> Number formatter needs to be merged
1581 SwTableNumFormatMerge
aTNFM( rSource
, *this );
1583 // 1st step: Create all formats (skip the 0th - it's the default!)
1586 const SwPageDesc
&rSrc
= *rSource
.m_PageDescs
[ --nCnt
];
1587 if( nullptr == FindPageDesc( rSrc
.GetName() ) )
1588 MakePageDesc( rSrc
.GetName() );
1591 // 2nd step: Copy all attributes, set the right parents
1592 for (SwPageDescs::size_type i
= rSource
.m_PageDescs
.size(); i
; )
1594 const SwPageDesc
&rSrc
= *rSource
.m_PageDescs
[ --i
];
1595 SwPageDesc
* pDesc
= FindPageDesc( rSrc
.GetName() );
1596 CopyPageDesc( rSrc
, *pDesc
);
1601 // then there are the numbering templates
1602 const SwNumRuleTable::size_type nCnt
= rSource
.GetNumRuleTable().size();
1605 const SwNumRuleTable
& rArr
= rSource
.GetNumRuleTable();
1606 for( SwNumRuleTable::size_type n
= 0; n
< nCnt
; ++n
)
1608 const SwNumRule
& rR
= *rArr
[ n
];
1609 SwNumRule
* pNew
= FindNumRulePtr( rR
.GetName());
1611 pNew
->CopyNumRule(*this, rR
);
1614 if( !rR
.IsAutoRule() )
1615 MakeNumRule( rR
.GetName(), &rR
);
1618 // as we reset all styles, there shouldn't be any unknown
1619 // automatic SwNumRules, because all should have been
1620 // created by the style copying!
1621 // So just warn and ignore.
1622 SAL_WARN( "sw.core", "Found unknown auto SwNumRule during reset!" );
1628 if (undoGuard
.UndoWasEnabled())
1630 // nodes array was modified!
1631 GetIDocumentUndoRedo().DelAllUndoObj();
1634 getIDocumentState().SetModified();
1637 void SwDoc::MoveLeftMargin(const SwPaM
& rPam
, bool bRight
, bool bModulus
,
1638 SwRootFrame
const*const pLayout
)
1640 SwHistory
* pHistory
= nullptr;
1641 if (GetIDocumentUndoRedo().DoesUndo())
1643 std::unique_ptr
<SwUndoMoveLeftMargin
> pUndo(new SwUndoMoveLeftMargin( rPam
, bRight
,
1645 pHistory
= &pUndo
->GetHistory();
1646 GetIDocumentUndoRedo().AppendUndo( std::move(pUndo
) );
1649 const SvxTabStopItem
& rTabItem
= GetDefault( RES_PARATR_TABSTOP
);
1650 const sal_Int32 nDefDist
= rTabItem
.Count() ? rTabItem
[0].GetTabPos() : 1134;
1651 const SwPosition
&rStt
= *rPam
.Start(), &rEnd
= *rPam
.End();
1652 SwNodeIndex
aIdx( rStt
.GetNode() );
1653 while( aIdx
<= rEnd
.GetNode() )
1655 SwTextNode
* pTNd
= aIdx
.GetNode().GetTextNode();
1658 pTNd
= sw::GetParaPropsNode(*pLayout
, aIdx
.GetNode());
1659 SvxFirstLineIndentItem
firstLine(pTNd
->SwContentNode::GetAttr(RES_MARGIN_FIRSTLINE
));
1660 SvxTextLeftMarginItem
leftMargin(pTNd
->SwContentNode::GetAttr(RES_MARGIN_TEXTLEFT
));
1662 // #i93873# See also lcl_MergeListLevelIndentAsLRSpaceItem in thints.cxx
1663 ::sw::ListLevelIndents
const indents(pTNd
->AreListLevelIndentsApplicable());
1664 if (indents
!= ::sw::ListLevelIndents::No
)
1666 const SwNumRule
* pRule
= pTNd
->GetNumRule();
1669 const int nListLevel
= pTNd
->GetActualListLevel();
1670 if ( nListLevel
>= 0 )
1672 const SwNumFormat
& rFormat
= pRule
->Get(o3tl::narrowing
<sal_uInt16
>(nListLevel
));
1673 if ( rFormat
.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT
)
1675 if (indents
& ::sw::ListLevelIndents::LeftMargin
)
1677 leftMargin
.SetTextLeft(rFormat
.GetIndentAt());
1679 if (indents
& ::sw::ListLevelIndents::FirstLine
)
1681 firstLine
.SetTextFirstLineOffset(static_cast<short>(rFormat
.GetFirstLineIndent()));
1688 tools::Long nNext
= leftMargin
.GetTextLeft();
1690 nNext
= ( nNext
/ nDefDist
) * nDefDist
;
1695 if(nNext
>0) // fdo#75936 set limit for decreasing indent
1698 leftMargin
.SetTextLeft( nNext
);
1700 SwRegHistory
aRegH( pTNd
, *pTNd
, pHistory
);
1701 pTNd
->SetAttr(firstLine
);
1702 pTNd
->SetAttr(leftMargin
);
1703 aIdx
= *sw::GetFirstAndLastNode(*pLayout
, aIdx
.GetNode()).second
;
1707 getIDocumentState().SetModified();
1710 bool SwDoc::DontExpandFormat( const SwPosition
& rPos
, bool bFlag
)
1713 SwTextNode
* pTextNd
= rPos
.GetNode().GetTextNode();
1716 bRet
= pTextNd
->DontExpandFormat( rPos
.GetContentIndex(), bFlag
);
1717 if( bRet
&& GetIDocumentUndoRedo().DoesUndo() )
1719 GetIDocumentUndoRedo().AppendUndo( std::make_unique
<SwUndoDontExpandFormat
>(rPos
) );
1725 SwTableBoxFormat
* SwDoc::MakeTableBoxFormat()
1727 SwTableBoxFormat
* pFormat
= new SwTableBoxFormat( GetAttrPool(), mpDfltFrameFormat
.get() );
1728 pFormat
->SetFormatName("TableBox" + OUString::number(reinterpret_cast<sal_IntPtr
>(pFormat
)));
1729 getIDocumentState().SetModified();
1733 SwTableLineFormat
* SwDoc::MakeTableLineFormat()
1735 SwTableLineFormat
* pFormat
= new SwTableLineFormat( GetAttrPool(), mpDfltFrameFormat
.get() );
1736 pFormat
->SetFormatName("TableLine" + OUString::number(reinterpret_cast<sal_IntPtr
>(pFormat
)));
1737 getIDocumentState().SetModified();
1741 void SwDoc::EnsureNumberFormatter()
1743 if (mpNumberFormatter
== nullptr)
1745 LanguageType eLang
= LANGUAGE_SYSTEM
;
1746 mpNumberFormatter
= new SvNumberFormatter(comphelper::getProcessComponentContext(), eLang
);
1747 mpNumberFormatter
->SetEvalDateFormat( NF_EVALDATEFORMAT_FORMAT_INTL
);
1748 if (!utl::ConfigManager::IsFuzzing())
1749 mpNumberFormatter
->SetYear2000(
1750 officecfg::Office::Common::DateFormat::TwoDigitYear::get());
1754 SwTableNumFormatMerge::SwTableNumFormatMerge( const SwDoc
& rSrc
, SwDoc
& rDest
)
1755 : pNFormat( nullptr )
1757 // a different Doc -> Number formatter needs to be merged
1758 if( &rSrc
!= &rDest
)
1760 SvNumberFormatter
* pN
= const_cast<SwDoc
&>(rSrc
).GetNumberFormatter( false );
1763 pNFormat
= rDest
.GetNumberFormatter();
1764 pNFormat
->MergeFormatter( *pN
);
1768 if( &rSrc
!= &rDest
)
1769 static_cast<SwGetRefFieldType
*>(rSrc
.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::GetRef
))->
1770 MergeWithOtherDoc( rDest
);
1773 SwTableNumFormatMerge::~SwTableNumFormatMerge()
1776 pNFormat
->ClearMergeTable();
1779 void SwDoc::SetTextFormatCollByAutoFormat( const SwPosition
& rPos
, sal_uInt16 nPoolId
,
1780 const SfxItemSet
* pSet
)
1783 SwTextNode
* pTNd
= rPos
.GetNode().GetTextNode();
1786 if (mbIsAutoFormatRedline
)
1788 // create the redline object
1789 const SwTextFormatColl
& rColl
= *pTNd
->GetTextColl();
1790 SwRangeRedline
* pRedl
= new SwRangeRedline( RedlineType::FmtColl
, aPam
);
1793 // Only those items that are not set by the Set again in the Node
1794 // are of interest. Thus, we take the difference.
1795 SwRedlineExtraData_FormatColl
aExtraData( rColl
.GetName(),
1796 rColl
.GetPoolFormatId() );
1797 if( pSet
&& pTNd
->HasSwAttrSet() )
1799 SfxItemSet
aTmp( *pTNd
->GetpSwAttrSet() );
1800 aTmp
.Differentiate( *pSet
);
1801 // we handle the adjust item separately
1802 const SfxPoolItem
* pItem
;
1803 if( SfxItemState::SET
== pTNd
->GetpSwAttrSet()->GetItemState(
1804 RES_PARATR_ADJUST
, false, &pItem
))
1806 aExtraData
.SetItemSet( aTmp
);
1808 pRedl
->SetExtraData( &aExtraData
);
1810 //TODO: Undo is still missing!
1811 getIDocumentRedlineAccess().AppendRedline( pRedl
, true );
1814 SetTextFormatColl( aPam
, getIDocumentStylePoolAccess().GetTextCollFromPool( nPoolId
) );
1816 if (pSet
&& pSet
->Count())
1819 aPam
.GetMark()->SetContent(pTNd
->GetText().getLength());
1820 // sw_redlinehide: don't need layout currently because the only caller
1821 // passes in the properties node
1822 assert(static_cast<SwTextFrame
const*>(pTNd
->getLayoutFrame(nullptr))->GetTextNodeForParaProps() == pTNd
);
1823 getIDocumentContentOperations().InsertItemSet( aPam
, *pSet
);
1827 void SwDoc::SetFormatItemByAutoFormat( const SwPaM
& rPam
, const SfxItemSet
& rSet
)
1829 SwTextNode
* pTNd
= rPam
.GetPoint()->GetNode().GetTextNode();
1832 RedlineFlags eOld
= getIDocumentRedlineAccess().GetRedlineFlags();
1834 if (mbIsAutoFormatRedline
)
1836 // create the redline object
1837 SwRangeRedline
* pRedl
= new SwRangeRedline( RedlineType::Format
, rPam
);
1838 if( !pRedl
->HasMark() )
1841 // Only those items that are not set by the Set again in the Node
1842 // are of interest. Thus, we take the difference.
1843 SwRedlineExtraData_Format
aExtraData( rSet
);
1845 pRedl
->SetExtraData( &aExtraData
);
1847 //TODO: Undo is still missing!
1848 getIDocumentRedlineAccess().AppendRedline( pRedl
, true );
1850 getIDocumentRedlineAccess().SetRedlineFlags_intern( eOld
| RedlineFlags::Ignore
);
1853 const sal_Int32
nEnd(rPam
.End()->GetContentIndex());
1854 std::vector
<WhichPair
> whichIds
;
1855 SfxItemIter
iter(rSet
);
1856 for (SfxPoolItem
const* pItem
= iter
.GetCurItem(); pItem
; pItem
= iter
.NextItem())
1858 whichIds
.push_back({pItem
->Which(), pItem
->Which()});
1860 SfxItemSet
currentSet(GetAttrPool(), WhichRangesContainer(whichIds
.data(), whichIds
.size()));
1861 pTNd
->GetParaAttr(currentSet
, nEnd
, nEnd
);
1862 for (const WhichPair
& rPair
: whichIds
)
1863 { // yuk - want to explicitly set the pool defaults too :-/
1864 currentSet
.Put(currentSet
.Get(rPair
.first
));
1867 getIDocumentContentOperations().InsertItemSet( rPam
, rSet
, SetAttrMode::DONTEXPAND
);
1869 // fdo#62536: DONTEXPAND does not work when there is already an AUTOFMT
1870 // here, so insert the old attributes as an empty hint to stop expand
1871 SwPaM
endPam(*pTNd
, nEnd
);
1873 getIDocumentContentOperations().InsertItemSet(endPam
, currentSet
);
1875 getIDocumentRedlineAccess().SetRedlineFlags_intern( eOld
);
1878 void SwDoc::ChgFormat(SwFormat
& rFormat
, const SfxItemSet
& rSet
)
1880 if (GetIDocumentUndoRedo().DoesUndo())
1882 // copying <rSet> to <aSet>
1883 SfxItemSet
aSet(rSet
);
1884 // remove from <aSet> all items, which are already set at the format
1885 aSet
.Differentiate(rFormat
.GetAttrSet());
1886 // <aSet> contains now all *new* items for the format
1888 // copying current format item set to <aOldSet>
1889 SfxItemSet
aOldSet(rFormat
.GetAttrSet());
1890 // insert new items into <aOldSet>
1892 // invalidate all new items in <aOldSet> in order to clear these items,
1893 // if the undo action is triggered.
1895 SfxItemIter
aIter(aSet
);
1897 for (const SfxPoolItem
* pItem
= aIter
.GetCurItem(); pItem
; pItem
= aIter
.NextItem())
1899 aOldSet
.InvalidateItem(pItem
->Which());
1903 GetIDocumentUndoRedo().AppendUndo(
1904 std::make_unique
<SwUndoFormatAttr
>(std::move(aOldSet
), rFormat
, /*bSaveDrawPt*/true));
1907 rFormat
.SetFormatAttr(rSet
);
1910 void SwDoc::RenameFormat(SwFormat
& rFormat
, const OUString
& sNewName
,
1913 SfxStyleFamily eFamily
= SfxStyleFamily::All
;
1915 if (GetIDocumentUndoRedo().DoesUndo())
1917 std::unique_ptr
<SwUndo
> pUndo
;
1919 switch (rFormat
.Which())
1922 pUndo
.reset(new SwUndoRenameCharFormat(rFormat
.GetName(), sNewName
, *this));
1923 eFamily
= SfxStyleFamily::Char
;
1925 case RES_TXTFMTCOLL
:
1926 pUndo
.reset(new SwUndoRenameFormatColl(rFormat
.GetName(), sNewName
, *this));
1927 eFamily
= SfxStyleFamily::Para
;
1930 pUndo
.reset(new SwUndoRenameFrameFormat(rFormat
.GetName(), sNewName
, *this));
1931 eFamily
= SfxStyleFamily::Frame
;
1940 GetIDocumentUndoRedo().AppendUndo(std::move(pUndo
));
1944 // name change means the o3tl::sorted_array is not property sorted
1945 if (rFormat
.Which() == RES_CHRFMT
)
1946 mpCharFormatTable
->SetFormatNameAndReindex(static_cast<SwCharFormat
*>(&rFormat
), sNewName
);
1948 rFormat
.SetFormatName(sNewName
);
1951 BroadcastStyleOperation(sNewName
, eFamily
, SfxHintId::StyleSheetModified
);
1954 void SwDoc::dumpAsXml(xmlTextWriterPtr pWriter
) const
1959 pWriter
= xmlNewTextWriterFilename("nodes.xml", 0);
1960 xmlTextWriterSetIndent(pWriter
,1);
1961 (void)xmlTextWriterSetIndentString(pWriter
, BAD_CAST(" "));
1962 (void)xmlTextWriterStartDocument(pWriter
, nullptr, nullptr, nullptr);
1965 (void)xmlTextWriterStartElement(pWriter
, BAD_CAST("SwDoc"));
1966 (void)xmlTextWriterWriteFormatAttribute(pWriter
, BAD_CAST("ptr"), "%p", this);
1968 m_pNodes
->dumpAsXml(pWriter
);
1969 m_PageDescs
.dumpAsXml(pWriter
);
1970 maDBData
.dumpAsXml(pWriter
);
1971 mpMarkManager
->dumpAsXml(pWriter
);
1972 m_pContentControlManager
->dumpAsXml(pWriter
);
1973 m_pUndoManager
->dumpAsXml(pWriter
);
1974 m_pDocumentSettingManager
->dumpAsXml(pWriter
);
1975 getIDocumentFieldsAccess().GetFieldTypes()->dumpAsXml(pWriter
);
1976 mpTextFormatCollTable
->dumpAsXml(pWriter
);
1977 mpCharFormatTable
->dumpAsXml(pWriter
);
1978 mpFrameFormatTable
->dumpAsXml(pWriter
, "frmFormatTable");
1979 mpSpzFrameFormatTable
->dumpAsXml(pWriter
, "spzFrameFormatTable");
1980 mpSectionFormatTable
->dumpAsXml(pWriter
);
1981 mpTableFrameFormatTable
->dumpAsXml(pWriter
, "tableFrameFormatTable");
1982 mpNumRuleTable
->dumpAsXml(pWriter
);
1983 getIDocumentRedlineAccess().GetRedlineTable().dumpAsXml(pWriter
);
1984 getIDocumentRedlineAccess().GetExtraRedlineTable().dumpAsXml(pWriter
);
1985 if (const SdrModel
* pModel
= getIDocumentDrawModelAccess().GetDrawModel())
1986 pModel
->dumpAsXml(pWriter
);
1988 (void)xmlTextWriterStartElement(pWriter
, BAD_CAST("mbModified"));
1989 (void)xmlTextWriterWriteAttribute(pWriter
, BAD_CAST("value"), BAD_CAST(OString::boolean(getIDocumentState().IsModified()).getStr()));
1990 (void)xmlTextWriterEndElement(pWriter
);
1992 (void)xmlTextWriterEndElement(pWriter
);
1995 (void)xmlTextWriterEndDocument(pWriter
);
1996 xmlFreeTextWriter(pWriter
);
2000 void SwDBData::dumpAsXml(xmlTextWriterPtr pWriter
) const
2002 (void)xmlTextWriterStartElement(pWriter
, BAD_CAST("SwDBData"));
2004 (void)xmlTextWriterWriteAttribute(pWriter
, BAD_CAST("sDataSource"), BAD_CAST(sDataSource
.toUtf8().getStr()));
2005 (void)xmlTextWriterWriteAttribute(pWriter
, BAD_CAST("sCommand"), BAD_CAST(sCommand
.toUtf8().getStr()));
2006 (void)xmlTextWriterWriteAttribute(pWriter
, BAD_CAST("nCommandType"), BAD_CAST(OString::number(nCommandType
).getStr()));
2008 (void)xmlTextWriterEndElement(pWriter
);
2011 std::set
<Color
> SwDoc::GetDocColors()
2013 std::set
<Color
> aDocColors
;
2014 SwAttrPool
& rPool
= GetAttrPool();
2015 const sal_uInt16 pAttribs
[] = {RES_CHRATR_COLOR
, RES_CHRATR_HIGHLIGHT
, RES_BACKGROUND
};
2016 for (sal_uInt16 nAttrib
: pAttribs
)
2018 for (const SfxPoolItem
* pItem
: rPool
.GetItemSurrogates(nAttrib
))
2020 auto pColorItem
= static_cast<const SvxColorItem
*>(pItem
);
2021 Color
aColor( pColorItem
->GetValue() );
2022 if (COL_AUTO
!= aColor
)
2023 aDocColors
.insert(aColor
);
2032 bool HasOutlineStyleToBeWrittenAsNormalListStyle( SwDoc
& rDoc
)
2034 // If a parent paragraph style of one of the paragraph styles, which
2035 // are assigned to the list levels of the outline style, has a list style
2036 // set or inherits a list style from its parent style, the outline style
2037 // has to be written as a normal list style to the OpenDocument file
2038 // format or the OpenOffice.org file format.
2041 const SwTextFormatColls
* pTextFormatColls( rDoc
.GetTextFormatColls() );
2042 if ( pTextFormatColls
)
2044 for ( auto pTextFormatColl
: *pTextFormatColls
)
2046 if ( pTextFormatColl
->IsDefault() ||
2047 ! pTextFormatColl
->IsAssignedToListLevelOfOutlineStyle() )
2052 const SwTextFormatColl
* pParentTextFormatColl
=
2053 dynamic_cast<const SwTextFormatColl
*>( pTextFormatColl
->DerivedFrom());
2054 if ( !pParentTextFormatColl
)
2057 if ( SfxItemState::SET
== pParentTextFormatColl
->GetItemState( RES_PARATR_NUMRULE
) )
2059 // #i106218# consider that the outline style is set
2060 const SwNumRuleItem
& rDirectItem
= pParentTextFormatColl
->GetNumRule();
2061 if ( rDirectItem
.GetValue() != rDoc
.GetOutlineNumRule()->GetName() )
2073 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */