android: Update app-specific/MIME type icons
[LibreOffice.git] / sw / source / core / doc / docfmt.cxx
blob5119bf15c04b54e249be9f738b27bbbe71e24c1a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
40 #include <doc.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>
54 #include <txtfrm.hxx>
55 #include <hints.hxx>
56 #include <ndtxt.hxx>
57 #include <pam.hxx>
58 #include <UndoCore.hxx>
59 #include <UndoAttribute.hxx>
60 #include <UndoInsert.hxx>
61 #include <pagedesc.hxx>
62 #include <rolbck.hxx>
63 #include <mvsave.hxx>
64 #include <txatbase.hxx>
65 #include <swtblfmt.hxx>
66 #include <charfmt.hxx>
67 #include <docary.hxx>
68 #include <paratr.hxx>
69 #include <redline.hxx>
70 #include <reffld.hxx>
71 #include <fmtinfmt.hxx>
72 #include <breakit.hxx>
73 #include <SwUndoFmt.hxx>
74 #include <UndoManager.hxx>
75 #include <swmodule.hxx>
76 #include <modcfg.hxx>
77 #include <frameformats.hxx>
78 #include <textboxhelper.hxx>
79 #include <textcontentcontrol.hxx>
80 #include <memory>
82 using namespace ::com::sun::star::i18n;
83 using namespace ::com::sun::star::lang;
84 using namespace ::com::sun::star::uno;
87 * Internal functions
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)
105 return true;
107 if( pNode && pNode->HasSwAttrSet() )
109 const bool bLocked = pNode->IsModifyLocked();
110 pNode->LockModify();
112 SwDoc& rDoc = pNode->GetDoc();
114 // remove unused attribute RES_LR_SPACE
115 // add list attributes, except RES_PARATR_LIST_AUTOFMT
116 SfxItemSetFixed<
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();
133 while( pItem )
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 );
181 if( !bLocked )
182 pNode->UnlockModify();
184 if( pPara )
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();
208 else
209 pNode->ResetAttr( RES_PARATR_BEGIN, POOLATTR_END - 1 );
211 else
212 pNode->ResetAllAttr();
214 // only restore saved attributes, if needed
215 if (bKeepAttributes && aSavedAttrsSet.Count())
217 pNode->LockModify();
219 pNode->SetAttr(aSavedAttrsSet);
221 if( !bLocked )
222 pNode->UnlockModify();
225 return true;
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,
250 bool bTextAttr,
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()) )
258 bTextAttr = true;
260 if( !rRg.HasMark() )
262 SwTextNode* pTextNd = rRg.GetPoint()->GetNode().GetTextNode();
263 if( !pTextNd )
264 return ;
266 oExtraPaM.emplace( *rRg.GetPoint() );
267 pPam = &*oExtraPaM;
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();
280 else
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*/,
287 true);
289 if( aBndry.startPos < nPtPos && nPtPos < aBndry.endPos )
291 nMkPos = aBndry.startPos;
292 nPtPos = aBndry.endPos;
294 else
296 nPtPos = nMkPos = rSt.GetContentIndex();
297 if( bTextAttr )
298 pTextNd->DontExpandFormat( nPtPos );
302 rSt.SetContent(nMkPos);
303 pPam->SetMark();
304 pPam->GetPoint()->SetContent(nPtPos);
307 // #i96644#
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;
344 bool bAdd = true;
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() )
353 if (pHst)
355 SwRegHistory history(pTNd, *pTNd, pHst);
356 pTNd->FormatToTextAttr(pTNd);
358 else
360 pTNd->FormatToTextAttr(pTNd);
364 ++aTmpStt;
366 if( pEnd->GetContentIndex() == pEnd->GetNode().GetContentNode()->Len() )
368 // set up a later, and all CharFormatAttr -> TextFormatAttr
369 ++aTmpEnd;
370 bAdd = false;
372 else if( pStt->GetNode() != pEnd->GetNode() || !pStt->GetContentIndex() )
374 SwTextNode* pTNd = aTmpEnd.GetNode().GetTextNode();
375 if( pTNd && pTNd->HasSwAttrSet() && pTNd->GetpSwAttrSet()->Count() )
377 if (pHst)
379 SwRegHistory history(pTNd, *pTNd, pHst);
380 pTNd->FormatToTextAttr(pTNd);
382 else
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 ;
398 if( bTextAttr )
400 if( bAdd )
401 ++aTmpEnd;
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())
414 return;
416 SwTextNode *pTextNode = rRg.GetPoint()->GetNode().GetTextNode();
417 if (!pTextNode)
419 return;
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());
425 aSet.Put(aRsid);
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
434 assert(pUndoInsert);
435 if (pUndoInsert)
437 pUndoInsert->SetWithRsid();
442 bool SwDoc::UpdateParRsid( SwTextNode *pTextNode, sal_uInt32 nVal )
444 if (!SW_MOD()->GetModuleConfig()->IsStoreRsid())
445 return false;
447 if (!pTextNode)
449 return false;
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() );
461 aSet.Put( rAttr );
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() );
477 else
479 GetIDocumentUndoRedo().ClearRedo();
482 else
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 );
510 if ( bAttrReset )
512 if ( pUndo )
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 )
531 return false;
533 // Find the default's beginning
534 sal_uInt16 n;
535 for( n = nOldCnt; n ; --n )
536 if( SvxTabAdjust::Default != rChgTabStop[n - 1].GetAdjustment() )
537 break;
538 ++n;
539 if( n < nOldCnt ) // delete the DefTabStops
540 rChgTabStop.Remove( n, nOldCnt - n );
541 return true;
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() );
549 aSet.Put( rAttr );
550 SetDefault( aSet );
553 void SwDoc::SetDefault( const SfxItemSet& rSet )
555 if( !rSet.Count() )
556 return;
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
600 if( bCheckSdrDflt )
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();
616 } while (pItem);
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();
635 bool bChg = false;
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 );
645 if( bChg )
647 SwFormatChg aChgFormat( mpDfltCharFormat.get() );
648 // notify the frames
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];
680 if (bBroadcast)
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" );
709 delete pFormat;
711 else
713 // The format has to be in the one or the other, we'll see in which one.
714 if (mpFrameFormatTable->ContainsFormat(pFormat))
716 if (bBroadcast)
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 );
728 delete pFormat;
730 else
732 auto pSpz = static_cast<sw::SpzFrameFormat*>(pFormat);
733 if(GetSpzFrameFormats()->ContainsFormat(pSpz))
735 GetSpzFrameFormats()->erase(pSpz);
736 delete pSpz;
738 else
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 );
749 delete pFormat;
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();
764 return pFormat;
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();
773 return pFormat;
776 size_t SwDoc::GetTableFrameFormatCount(bool bUsed) const
778 if (!bUsed)
780 return mpTableFrameFormatTable->size();
783 SwAutoFormatGetDocNode aGetHt(&GetNodes());
784 size_t nCount = 0;
785 for (const SwTableFormat* pFormat: *mpTableFrameFormatTable)
787 if (!pFormat->GetInfo(aGetHt))
788 nCount++;
790 return nCount;
793 SwTableFormat& SwDoc::GetTableFrameFormat(size_t nFormat, bool bUsed) const
795 if (!bUsed)
797 return *const_cast<SwTableFormat*>((*mpTableFrameFormatTable)[nFormat]);
800 SwAutoFormatGetDocNode aGetHt(&GetNodes());
802 size_t index = 0;
804 for(SwTableFormat* pFormat: *mpTableFrameFormatTable)
806 if (!pFormat->GetInfo(aGetHt))
808 if (index == nFormat)
809 return *pFormat;
810 else
811 index++;
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();
824 return pFormat;
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));
843 if (bBroadcast)
845 BroadcastStyleOperation(rFormatName, SfxStyleFamily::Frame,
846 SfxHintId::StyleSheetCreated);
849 return pFormat;
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 );
858 return pFrameFormat;
861 SwCharFormat *SwDoc::MakeCharFormat( const OUString &rFormatName,
862 SwCharFormat *pDerivedFrom,
863 bool bBroadcast )
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));
876 if (bBroadcast)
878 BroadcastStyleOperation(rFormatName, SfxStyleFamily::Char,
879 SfxHintId::StyleSheetCreated);
882 return pFormat;
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 );
891 return pCharFormat;
894 /// Create the FormatCollections
895 SwTextFormatColl* SwDoc::MakeTextFormatColl( const OUString &rFormatName,
896 SwTextFormatColl *pDerivedFrom,
897 bool bBroadcast)
899 SwTextFormatColl *pFormatColl = new SwTextFormatColl( GetAttrPool(), rFormatName,
900 pDerivedFrom );
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,
909 *this));
912 if (bBroadcast)
913 BroadcastStyleOperation(rFormatName, SfxStyleFamily::Para,
914 SfxHintId::StyleSheetCreated);
916 return pFormatColl;
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,
930 bool bBroadcast)
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,
942 *this));
945 if (bBroadcast)
946 BroadcastStyleOperation(rFormatName, SfxStyleFamily::Para,
947 SfxHintId::StyleSheetCreated);
949 return pFormatColl;
952 // GRF
953 SwGrfFormatColl* SwDoc::MakeGrfFormatColl( const OUString &rFormatName,
954 SwGrfFormatColl *pDerivedFrom )
956 SwGrfFormatColl *pFormatColl = new SwGrfFormatColl( GetAttrPool(), rFormatName,
957 pDerivedFrom );
958 mpGrfFormatCollTable->push_back( pFormatColl );
959 pFormatColl->SetAuto(false);
960 getIDocumentState().SetModified();
961 return pFormatColl;
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!
973 if (bBroadcast)
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));
984 else
986 pUndo.reset(new SwUndoTextFormatCollDelete(pDel, *this));
989 GetIDocumentUndoRedo().AppendUndo(std::move(pUndo));
992 // Remove the FormatColl
993 mpTextFormatCollTable->erase(mpTextFormatCollTable->begin() + nFormatColl);
994 // Correct next
995 for( SwTextFormatColls::const_iterator it = mpTextFormatCollTable->begin() + 1; it != mpTextFormatCollTable->end(); ++it )
996 SetTextFormatCollNext( *it, pDel );
997 delete 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)
1013 return true;
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)
1021 return true;
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(),
1079 SwNodeType::Text );
1081 pCNd->ChgFormatColl( pFormat );
1083 pPara->nWhich++;
1085 return true;
1088 bool SwDoc::SetTextFormatColl(const SwPaM &rRg,
1089 SwTextFormatColl *pFormat,
1090 const bool bReset,
1091 const bool bResetListAttrs,
1092 SwRootFrame const*const pLayout)
1094 SwDataChanged aTmp( rRg );
1095 auto [pStt, pEnd] = rRg.StartEnd(); // SwPosition*
1096 SwHistory* pHst = nullptr;
1097 bool bRet = true;
1099 if (GetIDocumentUndoRedo().DoesUndo())
1101 std::unique_ptr<SwUndoFormatColl> pUndo(new SwUndoFormatColl( rRg, pFormat,
1102 bReset,
1103 bResetListAttrs ));
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;
1112 // #i62675#
1113 aPara.bResetListAttrs = bResetListAttrs;
1115 GetNodes().ForEach( pStt->GetNodeIndex(), pEnd->GetNodeIndex()+1,
1116 lcl_SetTextFormatColl, &aPara );
1117 if( !aPara.nWhich )
1118 bRet = false; // didn't find a valid Node
1120 if (bRet)
1122 getIDocumentState().SetModified();
1125 return bRet;
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
1150 // #i40550#
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 );
1161 return pNewFormat;
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() ));
1179 /// copy TextNodes
1180 SwTextFormatColl* SwDoc::CopyTextColl( const SwTextFormatColl& rColl )
1182 SwTextFormatColl* pNewColl = FindTextFormatCollByName( rColl.GetName() );
1183 if( pNewColl )
1184 return pNewColl;
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(),
1194 pParent);
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() );
1203 else
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,
1224 false );
1225 if( pItem )
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 );
1234 if( pDestRule )
1235 pDestRule->SetInvalidRule( true );
1236 else
1237 MakeNumRule( rName, pRule );
1242 return pNewColl;
1245 /// copy the graphic nodes
1246 SwGrfFormatColl* SwDoc::CopyGrfColl( const SwGrfFormatColl& rColl )
1248 SwGrfFormatColl* pNewColl = mpGrfFormatCollTable->FindFormatByName( rColl.GetName() );
1249 if( pNewColl )
1250 return pNewColl;
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 );
1269 return pNewColl;
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() )
1284 continue;
1286 if( nullptr == rDestArr.FindFormatByName( pSrc->GetName() ) )
1288 if( RES_CONDTXTFMTCOLL == pSrc->Which() )
1289 MakeCondTextFormatColl( pSrc->GetName(), static_cast<SwTextFormatColl*>(&rDfltFormat) );
1290 else
1291 // #i40550#
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() )
1301 continue;
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 );
1316 if( !pPageDesc )
1318 pPageDesc = MakePageDesc(rNm);
1320 aPageDesc.RegisterToPageDesc( *pPageDesc );
1321 SwAttrSet aTmpAttrSet( pSrc->GetAttrSet() );
1322 aTmpAttrSet.Put( aPageDesc );
1323 pDest->SetFormatAttr( aTmpAttrSet );
1325 else
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.
1357 continue;
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 ))
1376 return ;
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;
1382 if( bCpyHeader )
1383 pOldFormat = pNewItem->StaticWhichCast(RES_HEADER).GetHeaderFormat();
1384 else
1385 pOldFormat = pNewItem->StaticWhichCast(RES_FOOTER).GetFooterFormat();
1387 if( !pOldFormat )
1388 return;
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(),
1401 bCpyHeader
1402 ? SwHeaderStartNode
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 ));
1414 else
1415 pNewFormat->ResetFormatAttr( RES_CNTNT );
1417 if( bCpyHeader )
1418 pNewItem->StaticWhichCast(RES_HEADER).RegisterToFormat(*pNewFormat);
1419 else
1420 pNewItem->StaticWhichCast(RES_FOOTER).RegisterToFormat(*pNewFormat);
1421 rDestFormat.SetFormatAttr( *pNewItem );
1424 void SwDoc::CopyPageDesc( const SwPageDesc& rSrcDesc, SwPageDesc& rDstDesc,
1425 bool bCopyPoolIds )
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;
1438 if( bCopyPoolIds )
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() );
1450 if( !pFollow )
1452 // copy
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() );
1499 else
1500 rDstDesc.GetLeft().SetFormatAttr( rDstDesc.GetMaster().GetHeader() );
1501 if( !rDstDesc.IsFirstShared() )
1503 CopyHeader( rSrcDesc.GetFirstMaster(), rDstDesc.GetFirstMaster() );
1504 rDstDesc.GetFirstLeft().SetFormatAttr(rDstDesc.GetFirstMaster().GetHeader());
1506 else
1508 rDstDesc.GetFirstMaster().SetFormatAttr( rDstDesc.GetMaster().GetHeader() );
1509 rDstDesc.GetFirstLeft().SetFormatAttr(rDstDesc.GetLeft().GetHeader());
1512 if( !rDstDesc.IsFooterShared() )
1513 CopyFooter( rSrcDesc.GetLeft(), rDstDesc.GetLeft() );
1514 else
1515 rDstDesc.GetLeft().SetFormatAttr( rDstDesc.GetMaster().GetFooter() );
1516 if( !rDstDesc.IsFirstShared() )
1518 CopyFooter( rSrcDesc.GetFirstMaster(), rDstDesc.GetFirstMaster() );
1519 rDstDesc.GetFirstLeft().SetFormatAttr(rDstDesc.GetFirstMaster().GetFooter());
1521 else
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)
1550 continue;
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 );
1567 //To-Do:
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();
1578 if( nCnt )
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!)
1584 while( nCnt )
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();
1603 if( nCnt )
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());
1610 if( pNew )
1611 pNew->CopyNumRule(*this, rR);
1612 else
1614 if( !rR.IsAutoRule() )
1615 MakeNumRule( rR.GetName(), &rR );
1616 else
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,
1644 bModulus ));
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();
1656 if( pTNd )
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();
1667 if ( pRule )
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();
1689 if( bModulus )
1690 nNext = ( nNext / nDefDist ) * nDefDist;
1692 if( bRight )
1693 nNext += nDefDist;
1694 else
1695 if(nNext >0) // fdo#75936 set limit for decreasing indent
1696 nNext -= nDefDist;
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;
1705 ++aIdx;
1707 getIDocumentState().SetModified();
1710 bool SwDoc::DontExpandFormat( const SwPosition& rPos, bool bFlag )
1712 bool bRet = false;
1713 SwTextNode* pTextNd = rPos.GetNode().GetTextNode();
1714 if( pTextNd )
1716 bRet = pTextNd->DontExpandFormat( rPos.GetContentIndex(), bFlag );
1717 if( bRet && GetIDocumentUndoRedo().DoesUndo() )
1719 GetIDocumentUndoRedo().AppendUndo( std::make_unique<SwUndoDontExpandFormat>(rPos) );
1722 return bRet;
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();
1730 return pFormat;
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();
1738 return pFormat;
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 );
1761 if( pN )
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()
1775 if( pNFormat )
1776 pNFormat->ClearMergeTable();
1779 void SwDoc::SetTextFormatCollByAutoFormat( const SwPosition& rPos, sal_uInt16 nPoolId,
1780 const SfxItemSet* pSet )
1782 SwPaM aPam( rPos );
1783 SwTextNode* pTNd = rPos.GetNode().GetTextNode();
1784 assert(pTNd);
1786 if (mbIsAutoFormatRedline)
1788 // create the redline object
1789 const SwTextFormatColl& rColl = *pTNd->GetTextColl();
1790 SwRangeRedline* pRedl = new SwRangeRedline( RedlineType::FmtColl, aPam );
1791 pRedl->SetMark();
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 ))
1805 aTmp.Put( *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())
1818 aPam.SetMark();
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();
1830 assert(pTNd);
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() )
1839 pRedl->SetMark();
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);
1872 endPam.SetMark();
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>
1891 aOldSet.Put(aSet);
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,
1911 bool bBroadcast)
1913 SfxStyleFamily eFamily = SfxStyleFamily::All;
1915 if (GetIDocumentUndoRedo().DoesUndo())
1917 std::unique_ptr<SwUndo> pUndo;
1919 switch (rFormat.Which())
1921 case RES_CHRFMT:
1922 pUndo.reset(new SwUndoRenameCharFormat(rFormat.GetName(), sNewName, *this));
1923 eFamily = SfxStyleFamily::Char;
1924 break;
1925 case RES_TXTFMTCOLL:
1926 pUndo.reset(new SwUndoRenameFormatColl(rFormat.GetName(), sNewName, *this));
1927 eFamily = SfxStyleFamily::Para;
1928 break;
1929 case RES_FRMFMT:
1930 pUndo.reset(new SwUndoRenameFrameFormat(rFormat.GetName(), sNewName, *this));
1931 eFamily = SfxStyleFamily::Frame;
1932 break;
1934 default:
1935 break;
1938 if (pUndo)
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);
1947 else
1948 rFormat.SetFormatName(sNewName);
1950 if (bBroadcast)
1951 BroadcastStyleOperation(sNewName, eFamily, SfxHintId::StyleSheetModified);
1954 void SwDoc::dumpAsXml(xmlTextWriterPtr pWriter) const
1956 bool bOwns = false;
1957 if (!pWriter)
1959 pWriter = xmlNewTextWriterFilename("nodes.xml", 0);
1960 xmlTextWriterSetIndent(pWriter,1);
1961 (void)xmlTextWriterSetIndentString(pWriter, BAD_CAST(" "));
1962 (void)xmlTextWriterStartDocument(pWriter, nullptr, nullptr, nullptr);
1963 bOwns = true;
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);
1993 if (bOwns)
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);
2026 return aDocColors;
2029 // #i69627#
2030 namespace docfunc
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.
2039 bool bRet( false );
2041 const SwTextFormatColls* pTextFormatColls( rDoc.GetTextFormatColls() );
2042 if ( pTextFormatColls )
2044 for ( auto pTextFormatColl : *pTextFormatColls )
2046 if ( pTextFormatColl->IsDefault() ||
2047 ! pTextFormatColl->IsAssignedToListLevelOfOutlineStyle() )
2049 continue;
2052 const SwTextFormatColl* pParentTextFormatColl =
2053 dynamic_cast<const SwTextFormatColl*>( pTextFormatColl->DerivedFrom());
2054 if ( !pParentTextFormatColl )
2055 continue;
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() )
2063 bRet = true;
2064 break;
2070 return bRet;
2073 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */