ITEM: Refactor ItemType
[LibreOffice.git] / sw / source / core / attr / format.cxx
blob5c4683a0789778557bb6bc2859df9a006d14d709
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 <DocumentSettingManager.hxx> //For SwFmt::getIDocumentSettingAccess()
21 #include <IDocumentTimerAccess.hxx>
22 #include <doc.hxx>
23 #include <fmtcolfunc.hxx>
24 #include <format.hxx>
25 #include <frmatr.hxx>
26 #include <hintids.hxx>
27 #include <hints.hxx>
28 #include <o3tl/unit_conversion.hxx>
29 #include <osl/diagnose.h>
30 #include <sal/log.hxx>
31 #include <svl/grabbagitem.hxx>
32 #include <svx/sdr/attribute/sdrallfillattributeshelper.hxx>
33 #include <svx/unobrushitemhelper.hxx>
34 #include <svx/xdef.hxx>
35 #include <utility>
37 using namespace com::sun::star;
39 SwFormat::SwFormat( SwAttrPool& rPool, const OUString& rFormatNm,
40 const WhichRangesContainer& pWhichRanges, SwFormat *pDrvdFrame,
41 sal_uInt16 nFormatWhich ) :
42 m_aFormatName( rFormatNm ),
43 m_aSet( rPool, pWhichRanges ),
44 m_nWhichId( nFormatWhich ),
45 m_nPoolFormatId( USHRT_MAX ),
46 m_nPoolHelpId( USHRT_MAX ),
47 m_nPoolHlpFileId( UCHAR_MAX )
49 m_bAutoUpdateOnDirectFormat = false; // LAYER_IMPL
50 m_bAutoFormat = true;
51 m_bFormatInDTOR = m_bHidden = false;
53 if( pDrvdFrame )
55 pDrvdFrame->Add(*this);
56 m_aSet.SetParent( &pDrvdFrame->m_aSet );
60 SwFormat::SwFormat( const SwFormat& rFormat ) :
61 sw::BorderCacheOwner(),
62 m_aFormatName( rFormat.m_aFormatName ),
63 m_aSet( rFormat.m_aSet ),
64 m_nWhichId( rFormat.m_nWhichId ),
65 m_nPoolFormatId( rFormat.GetPoolFormatId() ),
66 m_nPoolHelpId( rFormat.GetPoolHelpId() ),
67 m_nPoolHlpFileId( rFormat.GetPoolHlpFileId() )
69 m_bFormatInDTOR = false; // LAYER_IMPL
70 m_bAutoFormat = rFormat.m_bAutoFormat;
71 m_bHidden = rFormat.m_bHidden;
72 m_bAutoUpdateOnDirectFormat = rFormat.m_bAutoUpdateOnDirectFormat;
74 if( auto pDerived = rFormat.DerivedFrom() )
76 pDerived->Add(*this);
77 m_aSet.SetParent( &pDerived->m_aSet );
79 // a few special treatments for attributes
80 m_aSet.SetModifyAtAttr( this );
83 SwFormat &SwFormat::operator=(const SwFormat& rFormat)
85 if(this == &rFormat)
86 return *this;
88 m_nWhichId = rFormat.m_nWhichId;
89 m_nPoolFormatId = rFormat.GetPoolFormatId();
90 m_nPoolHelpId = rFormat.GetPoolHelpId();
91 m_nPoolHlpFileId = rFormat.GetPoolHlpFileId();
93 InvalidateInSwCache();
95 // copy only array with attributes delta
96 SwAttrSet aOld( *m_aSet.GetPool(), m_aSet.GetRanges() ),
97 aNew( *m_aSet.GetPool(), m_aSet.GetRanges() );
98 m_aSet.Intersect_BC( rFormat.m_aSet, &aOld, &aNew );
99 (void)m_aSet.Put_BC( rFormat.m_aSet, &aOld, &aNew );
101 // a few special treatments for attributes
102 m_aSet.SetModifyAtAttr( this );
104 // create PoolItem attribute for Modify
105 if( aOld.Count() )
107 sw::ClientNotifyAttrChg(*this, m_aSet, aOld, aNew);
110 if(GetRegisteredIn() != rFormat.GetRegisteredIn())
112 StartListeningToSameModifyAs(rFormat);
113 m_aSet.SetParent( GetRegisteredIn()
114 ? &rFormat.m_aSet
115 : nullptr);
118 m_bAutoFormat = rFormat.m_bAutoFormat;
119 m_bHidden = rFormat.m_bHidden;
120 m_bAutoUpdateOnDirectFormat = rFormat.m_bAutoUpdateOnDirectFormat;
121 return *this;
124 void SwFormat::SetFormatName( const OUString& rNewName, bool bBroadcast )
126 OSL_ENSURE( !IsDefault(), "SetName: Defaultformat" );
127 if( bBroadcast )
129 m_aFormatName = rNewName;
130 const sw::NameChanged aHint(m_aFormatName, rNewName);
131 SwClientNotify(*this, aHint);
133 else
135 m_aFormatName = rNewName;
139 /** Copy attributes
141 This function is called in every Copy-Ctor for copying the attributes.
142 The latter can be only copied as soon as the derived class exists since
143 for setting them the Which() function is called and that has the default
144 value of 0 in the base class and is then overridden by the derived class.
146 If we copy over multiple documents then the new document has to be provided
147 in which <this> is defined. Currently this is important for DropCaps
148 because that contains data that needs to be copied deeply.
150 void SwFormat::CopyAttrs( const SwFormat& rFormat )
152 // copy only array with attributes delta
153 InvalidateInSwCache();
154 InvalidateInSwFntCache();
156 // special treatments for some attributes
157 SwAttrSet* pChgSet = const_cast<SwAttrSet*>(&rFormat.m_aSet);
159 // copy only array with attributes delta
160 if( pChgSet->GetPool() != m_aSet.GetPool() )
161 pChgSet->CopyToModify( *this );
162 else
164 SwAttrSet aOld( *m_aSet.GetPool(), m_aSet.GetRanges() ),
165 aNew( *m_aSet.GetPool(), m_aSet.GetRanges() );
167 if ( m_aSet.Put_BC( *pChgSet, &aOld, &aNew ) )
169 // a few special treatments for attributes
170 m_aSet.SetModifyAtAttr( this );
172 SwAttrSetChg aChgOld( m_aSet, aOld );
173 SwAttrSetChg aChgNew( m_aSet, aNew );
174 SwClientNotify(*this, sw::LegacyModifyHint(&aChgOld, &aChgNew)); // send all modified ones
178 if( pChgSet != &rFormat.m_aSet ) // was a Set created?
179 delete pChgSet;
182 void SwFormat::Destr()
184 // This happens at an ObjectDying message. Thus put all dependent
185 // ones on DerivedFrom.
186 if (!HasWriterListeners())
187 return;
189 m_bFormatInDTOR = true;
191 if (!DerivedFrom())
193 SwFormat::ResetFormatAttr(RES_PAGEDESC);
194 SAL_WARN("sw.core",
195 "~SwFormat: format still has clients on death, but parent format is missing: "
196 << GetName());
197 return;
199 SwIterator<SwClient, SwFormat> aIter(*this);
200 for (SwClient* pClient = aIter.First(); pClient; pClient = aIter.Next())
201 pClient->CheckRegistrationFormat(*this);
202 assert(!HasWriterListeners());
205 SwFormat::~SwFormat()
207 Destr();
210 void SwFormat::SwClientNotify(const SwModify&, const SfxHint& rHint)
212 if (rHint.GetId() == SfxHintId::SwRemoveUnoObject)
214 SwModify::SwClientNotify(*this, rHint);
215 return;
217 if (rHint.GetId() == SfxHintId::SwFormatChange)
219 auto pChangeHint = static_cast<const SwFormatChangeHint*>(&rHint);
221 InvalidateInSwCache();
223 // if the format parent will be moved so register my attribute set at
224 // the new one
226 // skip my own Modify
227 // NB: this still notifies depends even if this condition is not met, which seems non-obvious
228 if(pChangeHint->m_pOldFormat != this && pChangeHint->m_pNewFormat == GetRegisteredIn())
230 // attach Set to new parent
231 m_aSet.SetParent(DerivedFrom() ? &DerivedFrom()->m_aSet : nullptr);
233 InvalidateInSwFntCache();
234 SwModify::SwClientNotify(*this, rHint);
235 return;
237 if (rHint.GetId() != SfxHintId::SwLegacyModify)
238 return;
239 auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
241 std::optional<SwAttrSetChg> oOldClientChg, oNewClientChg;
242 std::optional<sw::LegacyModifyHint> oDependsHint(std::in_place, pLegacy->m_pOld, pLegacy->m_pNew);
243 const sal_uInt16 nWhich = pLegacy->GetWhich();
244 InvalidateInSwCache(nWhich);
245 switch(nWhich)
247 case 0:
248 break;
249 case RES_OBJECTDYING:
251 // NB: this still notifies depends even if pLegacy->m_pNew is nullptr, which seems non-obvious
252 if(!pLegacy->m_pNew)
253 break;
254 // If the dying object is the parent format of this format so
255 // attach this to the parent of the parent
256 SwFormat* pFormat = static_cast<SwFormat*>(pLegacy->m_pNew->StaticWhichCast(RES_OBJECTDYING).pObject);
258 // do not move if this is the topmost format
259 if(GetRegisteredIn() && GetRegisteredIn() == pFormat)
261 if(pFormat->GetRegisteredIn())
263 // if parent so register in new parent
264 pFormat->DerivedFrom()->Add(*this);
265 m_aSet.SetParent(&DerivedFrom()->m_aSet);
267 else
269 // otherwise de-register at least from dying one
270 EndListeningAll();
271 m_aSet.SetParent(nullptr);
274 break;
276 case RES_ATTRSET_CHG:
278 // NB: this still notifies depends even if this condition is not met, which seems non-obvious
279 auto pOldAttrSetChg = static_cast<const SwAttrSetChg*>(pLegacy->m_pOld);
280 auto pNewAttrSetChg = static_cast<const SwAttrSetChg*>(pLegacy->m_pNew);
281 if (pOldAttrSetChg && pNewAttrSetChg && pOldAttrSetChg->GetTheChgdSet() != &m_aSet)
283 // pass only those that are not set...
284 oNewClientChg.emplace(*pNewAttrSetChg);
285 oNewClientChg->GetChgSet()->Differentiate(m_aSet);
286 if(oNewClientChg->Count()) // ... if any
288 oOldClientChg.emplace(*pOldAttrSetChg);
289 oOldClientChg->GetChgSet()->Differentiate(m_aSet);
290 oDependsHint.emplace(&*oOldClientChg, &*oNewClientChg);
292 else
293 oDependsHint.reset();
295 break;
297 default:
298 // attribute is defined in this format
299 if(SfxItemState::SET == m_aSet.GetItemState(nWhich, false))
301 // DropCaps might come into this block
302 SAL_WARN_IF(RES_PARATR_DROP != nWhich, "sw.core", "Hint was sent without sender");
303 oDependsHint.reset();
306 if(oDependsHint)
308 InvalidateInSwFntCache(oDependsHint->GetWhich());
309 SwModify::SwClientNotify(*this, *oDependsHint);
313 bool SwFormat::SetDerivedFrom(SwFormat *pDerFrom)
315 if ( pDerFrom )
317 const SwFormat* pFormat = pDerFrom;
318 while ( pFormat != nullptr )
320 if ( pFormat == this )
321 return false;
323 pFormat=pFormat->DerivedFrom();
326 else
328 // nothing provided, search for Dflt format
329 pDerFrom = this;
330 while ( pDerFrom->DerivedFrom() )
331 pDerFrom = pDerFrom->DerivedFrom();
333 if ( (pDerFrom == DerivedFrom()) || (pDerFrom == this) )
334 return false;
336 assert( Which()==pDerFrom->Which()
337 || (Which()==RES_CONDTXTFMTCOLL && pDerFrom->Which()==RES_TXTFMTCOLL)
338 || (Which()==RES_TXTFMTCOLL && pDerFrom->Which()==RES_CONDTXTFMTCOLL)
339 || (Which()==RES_FLYFRMFMT && pDerFrom->Which()==RES_FRMFMT)
342 InvalidateInSwCache();
343 InvalidateInSwFntCache();
345 pDerFrom->Add(*this);
346 m_aSet.SetParent( &pDerFrom->m_aSet );
348 const SwFormatChangeHint aHint(this, this);
349 SwClientNotify(*this, aHint);
351 return true;
354 bool SwFormat::supportsFullDrawingLayerFillAttributeSet() const
356 return false;
359 const SfxPoolItem& SwFormat::GetFormatAttr( sal_uInt16 nWhich, bool bInParents ) const
361 if (RES_BACKGROUND == nWhich && supportsFullDrawingLayerFillAttributeSet())
363 // FALLBACKBREAKHERE should not be used; instead use [XATTR_FILL_FIRST .. XATTR_FILL_LAST]
364 SAL_INFO("sw.core", "Do no longer use SvxBrushItem, instead use [XATTR_FILL_FIRST .. XATTR_FILL_LAST] FillAttributes or makeBackgroundBrushItem (simple fallback is in place and used)");
365 static std::unique_ptr<SvxBrushItem> aSvxBrushItem; //(std::make_shared<SvxBrushItem>(RES_BACKGROUND));
367 // fill the local static SvxBrushItem from the current ItemSet so that
368 // the fill attributes [XATTR_FILL_FIRST .. XATTR_FILL_LAST] are used
369 // as good as possible to create a fallback representation and return that
370 aSvxBrushItem = getSvxBrushItemFromSourceSet(m_aSet, RES_BACKGROUND, bInParents);
372 return *aSvxBrushItem;
375 return m_aSet.Get( nWhich, bInParents );
378 SfxItemState SwFormat::GetItemState( sal_uInt16 nWhich, bool bSrchInParent, const SfxPoolItem **ppItem ) const
380 if (RES_BACKGROUND == nWhich && supportsFullDrawingLayerFillAttributeSet())
382 // FALLBACKBREAKHERE should not be used; instead use [XATTR_FILL_FIRST .. XATTR_FILL_LAST]
383 SAL_INFO("sw.core", "Do no longer use SvxBrushItem, instead use [XATTR_FILL_FIRST .. XATTR_FILL_LAST] FillAttributes or SwFormat::GetBackgroundStat (simple fallback is in place and used)");
384 const drawinglayer::attribute::SdrAllFillAttributesHelperPtr aFill = getSdrAllFillAttributesHelper();
386 // check if the new fill attributes are used
387 if(aFill && aFill->isUsed())
389 // if yes, fill the local SvxBrushItem using the new fill attributes
390 // as good as possible to have an instance for the pointer to point
391 // to and return as state that it is set
392 static std::unique_ptr<SvxBrushItem> aSvxBrushItem; //(RES_BACKGROUND);
394 aSvxBrushItem = getSvxBrushItemFromSourceSet(m_aSet, RES_BACKGROUND, bSrchInParent);
395 if( ppItem )
396 *ppItem = aSvxBrushItem.get();
398 return SfxItemState::SET;
401 // if not, reset pointer and return SfxItemState::DEFAULT to signal that
402 // the item is not set
403 if( ppItem )
404 *ppItem = nullptr;
406 return SfxItemState::DEFAULT;
409 return m_aSet.GetItemState( nWhich, bSrchInParent, ppItem );
412 SfxItemState SwFormat::GetBackgroundState(std::unique_ptr<SvxBrushItem>& rItem) const
414 if (supportsFullDrawingLayerFillAttributeSet())
416 // FALLBACKBREAKHERE should not be used; instead use [XATTR_FILL_FIRST .. XATTR_FILL_LAST]
417 const drawinglayer::attribute::SdrAllFillAttributesHelperPtr aFill = getSdrAllFillAttributesHelper();
419 // check if the new fill attributes are used
420 if(aFill && aFill->isUsed())
422 // if yes, fill the local SvxBrushItem using the new fill attributes
423 // as good as possible to have an instance for the pointer to point
424 // to and return as state that it is set
425 rItem = getSvxBrushItemFromSourceSet(m_aSet, RES_BACKGROUND);
426 return SfxItemState::SET;
429 // if not return SfxItemState::DEFAULT to signal that the item is not set
430 return SfxItemState::DEFAULT;
433 const SvxBrushItem* pItem = nullptr;
434 SfxItemState eRet = m_aSet.GetItemState(RES_BACKGROUND, true, &pItem);
435 if (pItem)
436 rItem.reset(pItem->Clone());
437 return eRet;
440 bool SwFormat::SetFormatAttr( const SfxPoolItem& rAttr )
442 const sal_uInt16 nWhich = rAttr.Which();
443 InvalidateInSwFntCache( nWhich );
444 InvalidateInSwCache( nWhich );
446 bool bRet = false;
448 if (RES_BACKGROUND == rAttr.Which() && supportsFullDrawingLayerFillAttributeSet())
450 // FALLBACKBREAKHERE should not be used; instead use [XATTR_FILL_FIRST .. XATTR_FILL_LAST]
451 SAL_INFO("sw.core", "Do no longer use SvxBrushItem, instead use [XATTR_FILL_FIRST .. XATTR_FILL_LAST] FillAttributes (simple fallback is in place and used)");
452 SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST> aTempSet(*m_aSet.GetPool());
453 const SvxBrushItem& rSource = rAttr.StaticWhichCast(RES_BACKGROUND);
455 // fill a local ItemSet with the attributes corresponding as good as possible
456 // to the new fill properties [XATTR_FILL_FIRST .. XATTR_FILL_LAST] and set these
457 // as ItemSet
458 setSvxBrushItemAsFillAttributesToTargetSet(rSource, aTempSet);
460 if(IsModifyLocked())
462 bRet = m_aSet.Put( aTempSet );
463 if( bRet )
465 m_aSet.SetModifyAtAttr( this );
468 else
470 SwAttrSet aOld(*m_aSet.GetPool(), m_aSet.GetRanges()), aNew(*m_aSet.GetPool(), m_aSet.GetRanges());
472 bRet = m_aSet.Put_BC(aTempSet, &aOld, &aNew);
474 if(bRet)
476 m_aSet.SetModifyAtAttr(this);
477 sw::ClientNotifyAttrChg(*this, m_aSet, aOld, aNew);
481 return bRet;
484 // if Modify is locked then no modifications will be sent;
485 // but call Modify always for FrameFormats
486 const sal_uInt16 nFormatWhich = Which();
487 if( IsModifyLocked() ||
488 ( !HasWriterListeners() &&
489 (RES_GRFFMTCOLL == nFormatWhich ||
490 RES_TXTFMTCOLL == nFormatWhich ) ) )
492 bRet = nullptr != m_aSet.Put( rAttr );
493 if( bRet )
494 m_aSet.SetModifyAtAttr( this );
495 // #i71574#
496 if ( nFormatWhich == RES_TXTFMTCOLL && rAttr.Which() == RES_PARATR_NUMRULE )
498 TextFormatCollFunc::CheckTextFormatCollForDeletionOfAssignmentToOutlineStyle( this );
501 else
503 // copy only array with attributes delta
504 SwAttrSet aOld( *m_aSet.GetPool(), m_aSet.GetRanges() ),
505 aNew( *m_aSet.GetPool(), m_aSet.GetRanges() );
507 bRet = m_aSet.Put_BC( rAttr, &aOld, &aNew );
508 if( bRet )
510 // some special treatments for attributes
511 m_aSet.SetModifyAtAttr( this );
513 sw::ClientNotifyAttrChg(*this, m_aSet, aOld, aNew);
516 return bRet;
519 bool SwFormat::SetFormatAttr( const SfxItemSet& rSet )
521 if( !rSet.Count() )
522 return false;
524 InvalidateInSwCache();
525 InvalidateInSwFntCache();
527 bool bRet = false;
529 // Use local copy to be able to apply needed changes, e.g. call
530 // CheckForUniqueItemForLineFillNameOrIndex which is needed for NameOrIndex stuff
531 SfxItemSet aTempSet(rSet);
533 // Need to check for unique item for DrawingLayer items of type NameOrIndex
534 // and evtl. correct that item to ensure unique names for that type. This call may
535 // modify/correct entries inside of the given SfxItemSet
536 if(GetDoc())
538 GetDoc()->CheckForUniqueItemForLineFillNameOrIndex(aTempSet);
541 if (supportsFullDrawingLayerFillAttributeSet())
543 if(const SvxBrushItem* pSource = aTempSet.GetItemIfSet(RES_BACKGROUND, false))
545 // FALLBACKBREAKHERE should not be used; instead use [XATTR_FILL_FIRST .. XATTR_FILL_LAST]
546 SAL_INFO("sw.core", "Do no longer use SvxBrushItem, instead use [XATTR_FILL_FIRST .. XATTR_FILL_LAST] FillAttributes (simple fallback is in place and used)");
548 // copy all items to be set anyways to a local ItemSet with is also prepared for the new
549 // fill attribute ranges [XATTR_FILL_FIRST .. XATTR_FILL_LAST]. Add the attributes
550 // corresponding as good as possible to the new fill properties and set the whole ItemSet
551 setSvxBrushItemAsFillAttributesToTargetSet(*pSource, aTempSet);
553 if(IsModifyLocked())
555 bRet = m_aSet.Put( aTempSet );
556 if( bRet )
558 m_aSet.SetModifyAtAttr( this );
561 else
563 SwAttrSet aOld(*m_aSet.GetPool(), m_aSet.GetRanges()), aNew(*m_aSet.GetPool(), m_aSet.GetRanges());
565 bRet = m_aSet.Put_BC(aTempSet, &aOld, &aNew);
567 if(bRet)
569 m_aSet.SetModifyAtAttr(this);
570 sw::ClientNotifyAttrChg(*this, m_aSet, aOld, aNew);
574 return bRet;
578 // if Modify is locked then no modifications will be sent;
579 // but call Modify always for FrameFormats
580 const sal_uInt16 nFormatWhich = Which();
581 if ( IsModifyLocked() ||
582 ( !HasWriterListeners() &&
583 ( RES_GRFFMTCOLL == nFormatWhich ||
584 RES_TXTFMTCOLL == nFormatWhich ) ) )
586 bRet = m_aSet.Put( aTempSet );
587 if( bRet )
588 m_aSet.SetModifyAtAttr( this );
589 // #i71574#
590 if ( nFormatWhich == RES_TXTFMTCOLL )
592 TextFormatCollFunc::CheckTextFormatCollForDeletionOfAssignmentToOutlineStyle( this );
595 else
597 SwAttrSet aOld( *m_aSet.GetPool(), m_aSet.GetRanges() ),
598 aNew( *m_aSet.GetPool(), m_aSet.GetRanges() );
599 bRet = m_aSet.Put_BC( aTempSet, &aOld, &aNew );
600 if( bRet )
602 // some special treatments for attributes
603 m_aSet.SetModifyAtAttr( this );
604 sw::ClientNotifyAttrChg(*this, m_aSet, aOld, aNew);
607 return bRet;
610 // remove Hint using nWhich from array with delta
611 bool SwFormat::ResetFormatAttr( sal_uInt16 nWhich1, sal_uInt16 nWhich2 )
613 if( !m_aSet.Count() )
614 return false;
616 if( !nWhich2 || nWhich2 < nWhich1 )
617 nWhich2 = nWhich1; // then set to 1st ID, only this item
619 for( sal_uInt16 n = nWhich1; n < nWhich2; ++n )
620 InvalidateInSwFntCache( n );
621 for( sal_uInt16 n = nWhich1; n < nWhich2 && IsInCache(); ++n )
622 InvalidateInSwCache( n );
624 // if Modify is locked then no modifications will be sent
625 if( IsModifyLocked() )
626 return 0 != (( nWhich2 == nWhich1 )
627 ? m_aSet.ClearItem( nWhich1 )
628 : m_aSet.ClearItem_BC( nWhich1, nWhich2 ));
630 SwAttrSet aOld( *m_aSet.GetPool(), m_aSet.GetRanges() ),
631 aNew( *m_aSet.GetPool(), m_aSet.GetRanges() );
632 bool bRet = 0 != m_aSet.ClearItem_BC( nWhich1, nWhich2, &aOld, &aNew );
633 if( bRet )
634 sw::ClientNotifyAttrChg(*this, m_aSet, aOld, aNew);
635 return bRet;
638 // #i73790#
639 sal_uInt16 SwFormat::ResetAllFormatAttr()
641 if( !m_aSet.Count() )
642 return 0;
644 InvalidateInSwCache();
645 InvalidateInSwFntCache();
647 // if Modify is locked then no modifications will be sent
648 if( IsModifyLocked() )
649 return m_aSet.ClearItem();
651 SwAttrSet aOld( *m_aSet.GetPool(), m_aSet.GetRanges() ),
652 aNew( *m_aSet.GetPool(), m_aSet.GetRanges() );
653 bool bRet = 0 != m_aSet.ClearItem_BC( 0, &aOld, &aNew );
654 if( bRet )
655 sw::ClientNotifyAttrChg(*this, m_aSet, aOld, aNew);
656 return aNew.Count();
659 void SwFormat::DelDiffs( const SfxItemSet& rSet )
661 if( !m_aSet.Count() )
662 return;
664 InvalidateInSwCache();
665 InvalidateInSwFntCache();
667 // if Modify is locked then no modifications will be sent
668 if( IsModifyLocked() )
670 m_aSet.Intersect( rSet );
671 return;
674 SwAttrSet aOld( *m_aSet.GetPool(), m_aSet.GetRanges() ),
675 aNew( *m_aSet.GetPool(), m_aSet.GetRanges() );
676 bool bRet = 0 != m_aSet.Intersect_BC( rSet, &aOld, &aNew );
677 if( bRet )
678 sw::ClientNotifyAttrChg(*this, m_aSet, aOld, aNew);
681 void SwFormat::SetPageFormatToDefault()
683 const sal_Int32 nSize = o3tl::convert(2, o3tl::Length::cm, o3tl::Length::twip);
684 SetFormatAttr(SvxLRSpaceItem(SvxIndentValue::twips(nSize), SvxIndentValue::twips(nSize),
685 SvxIndentValue::zero(), RES_LR_SPACE));
686 SetFormatAttr(SvxULSpaceItem(nSize, nSize, RES_UL_SPACE));
689 /** SwFormat::IsBackgroundTransparent
691 Virtual method to determine, if background of format is transparent.
692 Default implementation returns false. Thus, subclasses have to override
693 method, if the specific subclass can have a transparent background.
695 @return false, default implementation
697 bool SwFormat::IsBackgroundTransparent() const
699 return false;
703 * Document Interface Access
705 const IDocumentSettingAccess& SwFormat::getIDocumentSettingAccess() const { return GetDoc()->GetDocumentSettingManager(); }
706 const IDocumentDrawModelAccess& SwFormat::getIDocumentDrawModelAccess() const { return GetDoc()->getIDocumentDrawModelAccess(); }
707 IDocumentDrawModelAccess& SwFormat::getIDocumentDrawModelAccess() { return GetDoc()->getIDocumentDrawModelAccess(); }
708 const IDocumentLayoutAccess& SwFormat::getIDocumentLayoutAccess() const { return GetDoc()->getIDocumentLayoutAccess(); }
709 IDocumentLayoutAccess& SwFormat::getIDocumentLayoutAccess() { return GetDoc()->getIDocumentLayoutAccess(); }
710 IDocumentTimerAccess& SwFormat::getIDocumentTimerAccess() { return GetDoc()->getIDocumentTimerAccess(); }
711 IDocumentFieldsAccess& SwFormat::getIDocumentFieldsAccess() { return GetDoc()->getIDocumentFieldsAccess(); }
712 IDocumentChartDataProviderAccess& SwFormat::getIDocumentChartDataProviderAccess() { return GetDoc()->getIDocumentChartDataProviderAccess(); }
714 void SwFormat::GetGrabBagItem(uno::Any& rVal) const
716 if (m_pGrabBagItem)
717 m_pGrabBagItem->QueryValue(rVal);
718 else
719 rVal <<= uno::Sequence<beans::PropertyValue>();
722 void SwFormat::SetGrabBagItem(const uno::Any& rVal)
724 if (!m_pGrabBagItem)
725 m_pGrabBagItem = std::make_shared<SfxGrabBagItem>();
727 m_pGrabBagItem->PutValue(rVal, 0);
730 std::unique_ptr<SvxBrushItem> SwFormat::makeBackgroundBrushItem(bool bInP) const
732 if (supportsFullDrawingLayerFillAttributeSet())
734 // FALLBACKBREAKHERE should not be used; instead use [XATTR_FILL_FIRST .. XATTR_FILL_LAST]
735 SAL_INFO("sw.core", "Do no longer use SvxBrushItem, instead use [XATTR_FILL_FIRST .. XATTR_FILL_LAST] FillAttributes (simple fallback is in place and used)");
737 // fill the local static SvxBrushItem from the current ItemSet so that
738 // the fill attributes [XATTR_FILL_FIRST .. XATTR_FILL_LAST] are used
739 // as good as possible to create a fallback representation and return that
740 return getSvxBrushItemFromSourceSet(m_aSet, RES_BACKGROUND, bInP);
743 return std::unique_ptr<SvxBrushItem>(m_aSet.GetBackground(bInP).Clone());
746 drawinglayer::attribute::SdrAllFillAttributesHelperPtr SwFormat::getSdrAllFillAttributesHelper() const
748 return drawinglayer::attribute::SdrAllFillAttributesHelperPtr();
751 void SwFormat::RemoveAllUnos()
753 sw::RemoveUnoObjectHint aMsgHint(this);
754 SwClientNotify(*this, aMsgHint);
757 bool SwFormat::IsUsed() const
759 auto pDoc = GetDoc();
760 if(!pDoc)
761 return false;
762 bool isUsed = false;
763 sw::AutoFormatUsedHint aHint(isUsed, pDoc->GetNodes());
764 CallSwClientNotify(aHint);
765 return isUsed;
768 void SwFormat::dumpAsXml(xmlTextWriterPtr pWriter) const
770 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormat"));
771 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
772 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("symbol"), "%s", BAD_CAST(typeid(*this).name()));
773 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("name"),
774 BAD_CAST(m_aFormatName.toUtf8().getStr()));
775 if (SwFormat* pDerivedFrom = DerivedFrom())
777 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("derived-from"),
778 BAD_CAST(pDerivedFrom->GetName().toUtf8().getStr()));
780 m_aSet.dumpAsXml(pWriter);
781 (void)xmlTextWriterEndElement(pWriter);
784 SwFormatsBase::~SwFormatsBase()
787 SwFormat* SwFormatsBase::FindFormatByName( const OUString& rName ) const
789 SwFormat* pFnd = nullptr;
790 for( size_t n = 0; n < GetFormatCount(); ++n )
792 // Does the Doc already contain the template?
793 if( GetFormat(n)->HasName( rName ) )
795 pFnd = GetFormat(n);
796 break;
799 return pFnd;
802 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */