1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <doc.hxx>
21 #include <DocumentSettingManager.hxx> //For SwFmt::getIDocumentSettingAccess()
22 #include <IDocumentTimerAccess.hxx>
23 #include <fmtcolfunc.hxx>
24 #include <frame.hxx>
25 #include <format.hxx>
26 #include <hintids.hxx>
27 #include <hints.hxx>
28 #include <swcache.hxx>
29 #include <frmatr.hxx>
30 #include <svl/grabbagitem.hxx>
31 #include <svx/sdr/attribute/sdrallfillattributeshelper.hxx>
32 #include <svx/unobrushitemhelper.hxx>
33 #include <svx/xdef.hxx>
34 #include <sal/log.hxx>
35 
36 using namespace com::sun::star;
37 
38 
SwFormat(SwAttrPool & rPool,const sal_Char * pFormatNm,const sal_uInt16 * pWhichRanges,SwFormat * pDrvdFrame,sal_uInt16 nFormatWhich)39 SwFormat::SwFormat( SwAttrPool& rPool, const sal_Char* pFormatNm,
40               const sal_uInt16* pWhichRanges, SwFormat *pDrvdFrame,
41               sal_uInt16 nFormatWhich ) :
42     m_aFormatName( OUString::createFromAscii(pFormatNm) ),
43     m_aSet( rPool, pWhichRanges ),
44     m_nWhichId( nFormatWhich ),
45     m_nPoolFormatId( USHRT_MAX ),
46     m_nPoolHelpId( USHRT_MAX ),
47     m_nPoolHlpFileId( UCHAR_MAX )
48 {
49     m_bAutoUpdateFormat = false; // LAYER_IMPL
50     m_bAutoFormat = true;
51     m_bFormatInDTOR = m_bHidden = false;
52 
53     if( pDrvdFrame )
54     {
55         pDrvdFrame->Add(this);
56         m_aSet.SetParent( &pDrvdFrame->m_aSet );
57     }
58 }
59 
SwFormat(SwAttrPool & rPool,const OUString & rFormatNm,const sal_uInt16 * pWhichRanges,SwFormat * pDrvdFrame,sal_uInt16 nFormatWhich)60 SwFormat::SwFormat( SwAttrPool& rPool, const OUString& rFormatNm,
61               const sal_uInt16* pWhichRanges, SwFormat* pDrvdFrame,
62               sal_uInt16 nFormatWhich ) :
63     m_aFormatName( rFormatNm ),
64     m_aSet( rPool, pWhichRanges ),
65     m_nWhichId( nFormatWhich ),
66     m_nPoolFormatId( USHRT_MAX ),
67     m_nPoolHelpId( USHRT_MAX ),
68     m_nPoolHlpFileId( UCHAR_MAX )
69 {
70     m_bAutoUpdateFormat = false; // LAYER_IMPL
71     m_bAutoFormat = true;
72     m_bFormatInDTOR = m_bHidden = false;
73 
74     if( pDrvdFrame )
75     {
76         pDrvdFrame->Add(this);
77         m_aSet.SetParent( &pDrvdFrame->m_aSet );
78     }
79 }
80 
SwFormat(const SwFormat & rFormat)81 SwFormat::SwFormat( const SwFormat& rFormat ) :
82     m_aFormatName( rFormat.m_aFormatName ),
83     m_aSet( rFormat.m_aSet ),
84     m_nWhichId( rFormat.m_nWhichId ),
85     m_nPoolFormatId( rFormat.GetPoolFormatId() ),
86     m_nPoolHelpId( rFormat.GetPoolHelpId() ),
87     m_nPoolHlpFileId( rFormat.GetPoolHlpFileId() )
88 {
89     m_bFormatInDTOR = false; // LAYER_IMPL
90     m_bAutoFormat = rFormat.m_bAutoFormat;
91     m_bHidden = rFormat.m_bHidden;
92     m_bAutoUpdateFormat = rFormat.m_bAutoUpdateFormat;
93 
94     if( auto pDerived = rFormat.DerivedFrom() )
95     {
96         pDerived->Add(this);
97         m_aSet.SetParent( &pDerived->m_aSet );
98     }
99     // a few special treatments for attributes
100     m_aSet.SetModifyAtAttr( this );
101 }
102 
operator =(const SwFormat & rFormat)103 SwFormat &SwFormat::operator=(const SwFormat& rFormat)
104 {
105     if(this == &rFormat)
106         return *this;
107 
108     m_nWhichId = rFormat.m_nWhichId;
109     m_nPoolFormatId = rFormat.GetPoolFormatId();
110     m_nPoolHelpId = rFormat.GetPoolHelpId();
111     m_nPoolHlpFileId = rFormat.GetPoolHlpFileId();
112 
113     if ( IsInCache() )
114     {
115         SwFrame::GetCache().Delete( this );
116         SetInCache( false );
117     }
118     SetInSwFntCache( false );
119 
120     // copy only array with attributes delta
121     SwAttrSet aOld( *m_aSet.GetPool(), m_aSet.GetRanges() ),
122               aNew( *m_aSet.GetPool(), m_aSet.GetRanges() );
123     m_aSet.Intersect_BC( rFormat.m_aSet, &aOld, &aNew );
124     (void)m_aSet.Put_BC( rFormat.m_aSet, &aOld, &aNew );
125 
126     // a few special treatments for attributes
127     m_aSet.SetModifyAtAttr( this );
128 
129     // create PoolItem attribute for Modify
130     if( aOld.Count() )
131     {
132         SwAttrSetChg aChgOld( m_aSet, aOld );
133         SwAttrSetChg aChgNew( m_aSet, aNew );
134         ModifyNotification( &aChgOld, &aChgNew ); // send all modified ones
135     }
136 
137     if(GetRegisteredIn() != rFormat.GetRegisteredIn())
138     {
139         StartListeningToSameModifyAs(rFormat);
140         m_aSet.SetParent( GetRegisteredIn()
141             ? &rFormat.m_aSet
142             : nullptr);
143     }
144 
145     m_bAutoFormat = rFormat.m_bAutoFormat;
146     m_bHidden = rFormat.m_bHidden;
147     m_bAutoUpdateFormat = rFormat.m_bAutoUpdateFormat;
148     return *this;
149 }
150 
SetName(const OUString & rNewName,bool bBroadcast)151 void SwFormat::SetName( const OUString& rNewName, bool bBroadcast )
152 {
153     OSL_ENSURE( !IsDefault(), "SetName: Defaultformat" );
154     if( bBroadcast )
155     {
156         SwStringMsgPoolItem aOld( RES_NAME_CHANGED, m_aFormatName );
157         SwStringMsgPoolItem aNew( RES_NAME_CHANGED, rNewName );
158         m_aFormatName = rNewName;
159         ModifyNotification( &aOld, &aNew );
160     }
161     else
162     {
163         m_aFormatName = rNewName;
164     }
165 }
166 
167 /** Copy attributes
168 
169     This function is called in every Copy-Ctor for copying the attributes.
170     The latter can be only copied as soon as the derived class exists since
171     for setting them the Which() function is called and that has the default
172     value of 0 in the base class and is then overridden by the derived class.
173 
174     If we copy over multiple documents then the new document has to be provided
175     in which <this> is defined. Currently this is important for DropCaps
176     because that contains data that needs to be copied deeply.
177 */
CopyAttrs(const SwFormat & rFormat)178 void SwFormat::CopyAttrs( const SwFormat& rFormat )
179 {
180     // copy only array with attributes delta
181     if ( IsInCache() )
182     {
183         SwFrame::GetCache().Delete( this );
184         SetInCache( false );
185     }
186     SetInSwFntCache( false );
187 
188     // special treatments for some attributes
189     SwAttrSet* pChgSet = const_cast<SwAttrSet*>(&rFormat.m_aSet);
190 
191     // copy only array with attributes delta
192     if( pChgSet->GetPool() != m_aSet.GetPool() )
193         pChgSet->CopyToModify( *this );
194     else
195     {
196         SwAttrSet aOld( *m_aSet.GetPool(), m_aSet.GetRanges() ),
197                   aNew( *m_aSet.GetPool(), m_aSet.GetRanges() );
198 
199         if ( m_aSet.Put_BC( *pChgSet, &aOld, &aNew ) )
200         {
201             // a few special treatments for attributes
202             m_aSet.SetModifyAtAttr( this );
203 
204             SwAttrSetChg aChgOld( m_aSet, aOld );
205             SwAttrSetChg aChgNew( m_aSet, aNew );
206             ModifyNotification( &aChgOld, &aChgNew ); // send all modified ones
207         }
208     }
209 
210     if( pChgSet != &rFormat.m_aSet ) // was a Set created?
211         delete pChgSet;
212 }
213 
~SwFormat()214 SwFormat::~SwFormat()
215 {
216     // This happens at an ObjectDying message. Thus put all dependent
217     // ones on DerivedFrom.
218     if( HasWriterListeners() )
219     {
220         m_bFormatInDTOR = true;
221 
222         SwFormat* pParentFormat = DerivedFrom();
223         if( !pParentFormat )
224         {
225             SAL_WARN(
226                 "sw.core",
227                 "~SwFormat: parent format missing from: " << GetName() );
228         }
229         else
230         {
231             SwFormatChg aOldFormat( this );
232             SwFormatChg aNewFormat( pParentFormat );
233             SwIterator<SwClient,SwFormat> aIter(*this);
234             for(SwClient* pClient = aIter.First(); pClient && pParentFormat; pClient = aIter.Next())
235             {
236                 SAL_INFO("sw.core", "reparenting " << typeid(*pClient).name() << " at " << pClient << " from " << typeid(*this).name() << " at " << this << " to "  << typeid(*pParentFormat).name() << " at " << pParentFormat);
237                 pParentFormat->Add( pClient );
238                 pClient->ModifyNotification( &aOldFormat, &aNewFormat );
239             }
240         }
241     }
242 }
243 
Modify(const SfxPoolItem * pOldValue,const SfxPoolItem * pNewValue)244 void SwFormat::Modify( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue )
245 {
246     bool bContinue = true; // true = pass on to dependent ones
247 
248     sal_uInt16 nWhich = pOldValue ? pOldValue->Which() :
249                     pNewValue ? pNewValue->Which() : 0 ;
250     switch( nWhich )
251     {
252     case 0:     break;          // Which-Id of 0?
253 
254     case RES_OBJECTDYING:
255         if (pNewValue)
256         {
257             // If the dying object is the parent format of this format so
258             // attach this to the parent of the parent
259             SwFormat* pFormat = static_cast<SwFormat*>(static_cast<const SwPtrMsgPoolItem*>(pNewValue)->pObject);
260 
261             // do not move if this is the topmost format
262             if( GetRegisteredIn() && GetRegisteredIn() == pFormat )
263             {
264                 if( pFormat->GetRegisteredIn() )
265                 {
266                     // if parent so register in new parent
267                     pFormat->DerivedFrom()->Add( this );
268                     m_aSet.SetParent( &DerivedFrom()->m_aSet );
269                 }
270                 else
271                 {
272                     // otherwise de-register at least from dying one
273                     EndListeningAll();
274                     m_aSet.SetParent( nullptr );
275                 }
276             }
277         }
278         break;
279     case RES_ATTRSET_CHG:
280         if (pOldValue && pNewValue && static_cast<const SwAttrSetChg*>(pOldValue)->GetTheChgdSet() != &m_aSet)
281         {
282             // pass only those that are not set
283             SwAttrSetChg aOld( *static_cast<const SwAttrSetChg*>(pOldValue) );
284             SwAttrSetChg aNew( *static_cast<const SwAttrSetChg*>(pNewValue) );
285 
286             aOld.GetChgSet()->Differentiate( m_aSet );
287             aNew.GetChgSet()->Differentiate( m_aSet );
288 
289             if( aNew.Count() )
290                 NotifyClients( &aOld, &aNew );
291             bContinue = false;
292         }
293         break;
294     case RES_FMT_CHG:
295         // if the format parent will be moved so register my attribute set at
296         // the new one
297 
298         // skip my own Modify
299         if ( pOldValue && pNewValue &&
300             static_cast<const SwFormatChg*>(pOldValue)->pChangedFormat != this &&
301             static_cast<const SwFormatChg*>(pNewValue)->pChangedFormat == GetRegisteredIn() )
302         {
303             // attach Set to new parent
304             m_aSet.SetParent( DerivedFrom() ? &DerivedFrom()->m_aSet : nullptr );
305         }
306         break;
307     default:
308         {
309             // attribute is defined in this format
310             if( SfxItemState::SET == m_aSet.GetItemState( nWhich, false ))
311             {
312                 // DropCaps might come into this block
313                 OSL_ENSURE( RES_PARATR_DROP == nWhich, "Modify was sent without sender" );
314                 bContinue = false;
315             }
316         }
317     }
318 
319     if( bContinue )
320     {
321         // walk over all dependent formats
322         NotifyClients( pOldValue, pNewValue );
323     }
324 }
325 
SetDerivedFrom(SwFormat * pDerFrom)326 bool SwFormat::SetDerivedFrom(SwFormat *pDerFrom)
327 {
328     if ( pDerFrom )
329     {
330         const SwFormat* pFormat = pDerFrom;
331         while ( pFormat != nullptr )
332         {
333             if ( pFormat == this )
334                 return false;
335 
336             pFormat=pFormat->DerivedFrom();
337         }
338     }
339     else
340     {
341         // nothing provided, search for Dflt format
342         pDerFrom = this;
343         while ( pDerFrom->DerivedFrom() )
344             pDerFrom = pDerFrom->DerivedFrom();
345     }
346     if ( (pDerFrom == DerivedFrom()) || (pDerFrom == this) )
347         return false;
348 
349     assert(    Which()==pDerFrom->Which()
350             || (Which()==RES_CONDTXTFMTCOLL && pDerFrom->Which()==RES_TXTFMTCOLL)
351             || (Which()==RES_TXTFMTCOLL && pDerFrom->Which()==RES_CONDTXTFMTCOLL)
352             || (Which()==RES_FLYFRMFMT && pDerFrom->Which()==RES_FRMFMT)
353             );
354 
355     if ( IsInCache() )
356     {
357         SwFrame::GetCache().Delete( this );
358         SetInCache( false );
359     }
360     SetInSwFntCache( false );
361 
362     pDerFrom->Add( this );
363     m_aSet.SetParent( &pDerFrom->m_aSet );
364 
365     SwFormatChg aOldFormat( this );
366     SwFormatChg aNewFormat( this );
367     ModifyNotification( &aOldFormat, &aNewFormat );
368 
369     return true;
370 }
371 
supportsFullDrawingLayerFillAttributeSet() const372 bool SwFormat::supportsFullDrawingLayerFillAttributeSet() const
373 {
374     return false;
375 }
376 
GetFormatAttr(sal_uInt16 nWhich,bool bInParents) const377 const SfxPoolItem& SwFormat::GetFormatAttr( sal_uInt16 nWhich, bool bInParents ) const
378 {
379     if (RES_BACKGROUND == nWhich && supportsFullDrawingLayerFillAttributeSet())
380     {
381         // FALLBACKBREAKHERE should not be used; instead use [XATTR_FILL_FIRST .. XATTR_FILL_LAST]
382         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)");
383         static std::shared_ptr<SvxBrushItem> aSvxBrushItem; //(std::make_shared<SvxBrushItem>(RES_BACKGROUND));
384 
385         // fill the local static SvxBrushItem from the current ItemSet so that
386         // the fill attributes [XATTR_FILL_FIRST .. XATTR_FILL_LAST] are used
387         // as good as possible to create a fallback representation and return that
388         aSvxBrushItem = getSvxBrushItemFromSourceSet(m_aSet, RES_BACKGROUND, bInParents);
389 
390         return *aSvxBrushItem;
391     }
392 
393     return m_aSet.Get( nWhich, bInParents );
394 }
395 
GetItemState(sal_uInt16 nWhich,bool bSrchInParent,const SfxPoolItem ** ppItem) const396 SfxItemState SwFormat::GetItemState( sal_uInt16 nWhich, bool bSrchInParent, const SfxPoolItem **ppItem ) const
397 {
398     if (RES_BACKGROUND == nWhich && supportsFullDrawingLayerFillAttributeSet())
399     {
400         // FALLBACKBREAKHERE should not be used; instead use [XATTR_FILL_FIRST .. XATTR_FILL_LAST]
401         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)");
402         const drawinglayer::attribute::SdrAllFillAttributesHelperPtr aFill = getSdrAllFillAttributesHelper();
403 
404         // check if the new fill attributes are used
405         if(aFill.get() && aFill->isUsed())
406         {
407             // if yes, fill the local SvxBrushItem using the new fill attributes
408             // as good as possible to have an instance for the pointer to point
409             // to and return as state that it is set
410             static std::shared_ptr<SvxBrushItem> aSvxBrushItem; //(RES_BACKGROUND);
411 
412             aSvxBrushItem = getSvxBrushItemFromSourceSet(m_aSet, RES_BACKGROUND, bSrchInParent);
413             if( ppItem )
414                 *ppItem = aSvxBrushItem.get();
415 
416             return SfxItemState::SET;
417         }
418 
419         // if not, reset pointer and return SfxItemState::DEFAULT to signal that
420         // the item is not set
421         if( ppItem )
422             *ppItem = nullptr;
423 
424         return SfxItemState::DEFAULT;
425     }
426 
427     return m_aSet.GetItemState( nWhich, bSrchInParent, ppItem );
428 }
429 
GetBackgroundState(std::shared_ptr<SvxBrushItem> & rItem) const430 SfxItemState SwFormat::GetBackgroundState(std::shared_ptr<SvxBrushItem>& rItem) const
431 {
432     if (supportsFullDrawingLayerFillAttributeSet())
433     {
434         // FALLBACKBREAKHERE should not be used; instead use [XATTR_FILL_FIRST .. XATTR_FILL_LAST]
435         const drawinglayer::attribute::SdrAllFillAttributesHelperPtr aFill = getSdrAllFillAttributesHelper();
436 
437         // check if the new fill attributes are used
438         if(aFill.get() && aFill->isUsed())
439         {
440             // if yes, fill the local SvxBrushItem using the new fill attributes
441             // as good as possible to have an instance for the pointer to point
442             // to and return as state that it is set
443             rItem = getSvxBrushItemFromSourceSet(m_aSet, RES_BACKGROUND);
444             return SfxItemState::SET;
445         }
446 
447         // if not return SfxItemState::DEFAULT to signal that the item is not set
448         return SfxItemState::DEFAULT;
449     }
450 
451     const SfxPoolItem* pItem = nullptr;
452     SfxItemState eRet = m_aSet.GetItemState(RES_BACKGROUND, true, &pItem);
453     if (pItem)
454         rItem.reset(static_cast<SvxBrushItem*>(pItem->Clone()));
455     return eRet;
456 }
457 
SetFormatAttr(const SfxPoolItem & rAttr)458 bool SwFormat::SetFormatAttr( const SfxPoolItem& rAttr )
459 {
460     if ( IsInCache() || IsInSwFntCache() )
461     {
462         const sal_uInt16 nWhich = rAttr.Which();
463         CheckCaching( nWhich );
464     }
465 
466     bool bRet = false;
467 
468     if (RES_BACKGROUND == rAttr.Which() && supportsFullDrawingLayerFillAttributeSet())
469     {
470         // FALLBACKBREAKHERE should not be used; instead use [XATTR_FILL_FIRST .. XATTR_FILL_LAST]
471         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)");
472         SfxItemSet aTempSet(*m_aSet.GetPool(), svl::Items<XATTR_FILL_FIRST, XATTR_FILL_LAST>{});
473         const SvxBrushItem& rSource = static_cast< const SvxBrushItem& >(rAttr);
474 
475         // fill a local ItemSet with the attributes corresponding as good as possible
476         // to the new fill properties [XATTR_FILL_FIRST .. XATTR_FILL_LAST] and set these
477         // as ItemSet
478         setSvxBrushItemAsFillAttributesToTargetSet(rSource, aTempSet);
479 
480         if(IsModifyLocked())
481         {
482             bRet = m_aSet.Put( aTempSet );
483             if( bRet )
484             {
485                 m_aSet.SetModifyAtAttr( this );
486             }
487         }
488         else
489         {
490             SwAttrSet aOld(*m_aSet.GetPool(), m_aSet.GetRanges()), aNew(*m_aSet.GetPool(), m_aSet.GetRanges());
491 
492             bRet = m_aSet.Put_BC(aTempSet, &aOld, &aNew);
493 
494             if(bRet)
495             {
496                 m_aSet.SetModifyAtAttr(this);
497 
498                 SwAttrSetChg aChgOld(m_aSet, aOld);
499                 SwAttrSetChg aChgNew(m_aSet, aNew);
500 
501                 ModifyNotification(&aChgOld, &aChgNew);
502             }
503         }
504 
505         return bRet;
506     }
507 
508     // if Modify is locked then no modifications will be sent;
509     // but call Modify always for FrameFormats
510     const sal_uInt16 nFormatWhich = Which();
511     if( IsModifyLocked() ||
512         ( !HasWriterListeners() &&
513           (RES_GRFFMTCOLL == nFormatWhich  ||
514            RES_TXTFMTCOLL == nFormatWhich ) ) )
515     {
516         bRet = nullptr != m_aSet.Put( rAttr );
517         if( bRet )
518             m_aSet.SetModifyAtAttr( this );
519         // #i71574#
520         if ( nFormatWhich == RES_TXTFMTCOLL && rAttr.Which() == RES_PARATR_NUMRULE )
521         {
522             TextFormatCollFunc::CheckTextFormatCollForDeletionOfAssignmentToOutlineStyle( this );
523         }
524     }
525     else
526     {
527         // copy only array with attributes delta
528         SwAttrSet aOld( *m_aSet.GetPool(), m_aSet.GetRanges() ),
529                   aNew( *m_aSet.GetPool(), m_aSet.GetRanges() );
530 
531         bRet = m_aSet.Put_BC( rAttr, &aOld, &aNew );
532         if( bRet )
533         {
534             // some special treatments for attributes
535             m_aSet.SetModifyAtAttr( this );
536 
537             SwAttrSetChg aChgOld( m_aSet, aOld );
538             SwAttrSetChg aChgNew( m_aSet, aNew );
539             ModifyNotification( &aChgOld, &aChgNew ); // send all modified ones
540         }
541     }
542     return bRet;
543 }
544 
SetFormatAttr(const SfxItemSet & rSet)545 bool SwFormat::SetFormatAttr( const SfxItemSet& rSet )
546 {
547     if( !rSet.Count() )
548         return false;
549 
550     if ( IsInCache() )
551     {
552         SwFrame::GetCache().Delete( this );
553         SetInCache( false );
554     }
555     SetInSwFntCache( false );
556 
557     bool bRet = false;
558 
559     // Use local copy to be able to apply needed changes, e.g. call
560     // CheckForUniqueItemForLineFillNameOrIndex which is needed for NameOrIndex stuff
561     SfxItemSet aTempSet(rSet);
562 
563     // Need to check for unique item for DrawingLayer items of type NameOrIndex
564     // and evtl. correct that item to ensure unique names for that type. This call may
565     // modify/correct entries inside of the given SfxItemSet
566     if(GetDoc())
567     {
568         GetDoc()->CheckForUniqueItemForLineFillNameOrIndex(aTempSet);
569     }
570 
571     if (supportsFullDrawingLayerFillAttributeSet())
572     {
573         const SfxPoolItem* pSource = nullptr;
574 
575         if(SfxItemState::SET == aTempSet.GetItemState(RES_BACKGROUND, false, &pSource))
576         {
577             // FALLBACKBREAKHERE should not be used; instead use [XATTR_FILL_FIRST .. XATTR_FILL_LAST]
578             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)");
579 
580             // copy all items to be set anyways to a local ItemSet with is also prepared for the new
581             // fill attribute ranges [XATTR_FILL_FIRST .. XATTR_FILL_LAST]. Add the attributes
582             // corresponding as good as possible to the new fill properties and set the whole ItemSet
583             const SvxBrushItem& rSource(static_cast< const SvxBrushItem& >(*pSource));
584             setSvxBrushItemAsFillAttributesToTargetSet(rSource, aTempSet);
585 
586             if(IsModifyLocked())
587             {
588                 bRet = m_aSet.Put( aTempSet );
589                 if( bRet )
590                 {
591                     m_aSet.SetModifyAtAttr( this );
592                 }
593             }
594             else
595             {
596                 SwAttrSet aOld(*m_aSet.GetPool(), m_aSet.GetRanges()), aNew(*m_aSet.GetPool(), m_aSet.GetRanges());
597 
598                 bRet = m_aSet.Put_BC(aTempSet, &aOld, &aNew);
599 
600                 if(bRet)
601                 {
602                     m_aSet.SetModifyAtAttr(this);
603 
604                     SwAttrSetChg aChgOld(m_aSet, aOld);
605                     SwAttrSetChg aChgNew(m_aSet, aNew);
606 
607                     ModifyNotification(&aChgOld, &aChgNew);
608                 }
609             }
610 
611             return bRet;
612         }
613     }
614 
615     // if Modify is locked then no modifications will be sent;
616     // but call Modify always for FrameFormats
617     const sal_uInt16 nFormatWhich = Which();
618     if ( IsModifyLocked() ||
619          ( !HasWriterListeners() &&
620            ( RES_GRFFMTCOLL == nFormatWhich ||
621              RES_TXTFMTCOLL == nFormatWhich ) ) )
622     {
623         bRet = m_aSet.Put( aTempSet );
624         if( bRet )
625             m_aSet.SetModifyAtAttr( this );
626         // #i71574#
627         if ( nFormatWhich == RES_TXTFMTCOLL )
628         {
629             TextFormatCollFunc::CheckTextFormatCollForDeletionOfAssignmentToOutlineStyle( this );
630         }
631     }
632     else
633     {
634         SwAttrSet aOld( *m_aSet.GetPool(), m_aSet.GetRanges() ),
635                   aNew( *m_aSet.GetPool(), m_aSet.GetRanges() );
636         bRet = m_aSet.Put_BC( aTempSet, &aOld, &aNew );
637         if( bRet )
638         {
639             // some special treatments for attributes
640             m_aSet.SetModifyAtAttr( this );
641             SwAttrSetChg aChgOld( m_aSet, aOld );
642             SwAttrSetChg aChgNew( m_aSet, aNew );
643             ModifyNotification( &aChgOld, &aChgNew ); // send all modified ones
644         }
645     }
646     return bRet;
647 }
648 
649 // remove Hint using nWhich from array with delta
ResetFormatAttr(sal_uInt16 nWhich1,sal_uInt16 nWhich2)650 bool SwFormat::ResetFormatAttr( sal_uInt16 nWhich1, sal_uInt16 nWhich2 )
651 {
652     if( !m_aSet.Count() )
653         return false;
654 
655     if( !nWhich2 || nWhich2 < nWhich1 )
656         nWhich2 = nWhich1; // then set to 1st ID, only this item
657 
658     if ( IsInCache() || IsInSwFntCache() )
659     {
660         for( sal_uInt16 n = nWhich1; n < nWhich2; ++n )
661             CheckCaching( n );
662     }
663 
664     // if Modify is locked then no modifications will be sent
665     if( IsModifyLocked() )
666         return 0 != (( nWhich2 == nWhich1 )
667                      ? m_aSet.ClearItem( nWhich1 )
668                      : m_aSet.ClearItem_BC( nWhich1, nWhich2 ));
669 
670     SwAttrSet aOld( *m_aSet.GetPool(), m_aSet.GetRanges() ),
671               aNew( *m_aSet.GetPool(), m_aSet.GetRanges() );
672     bool bRet = 0 != m_aSet.ClearItem_BC( nWhich1, nWhich2, &aOld, &aNew );
673     if( bRet )
674     {
675         SwAttrSetChg aChgOld( m_aSet, aOld );
676         SwAttrSetChg aChgNew( m_aSet, aNew );
677         ModifyNotification( &aChgOld, &aChgNew ); // send all modified ones
678     }
679     return bRet;
680 }
681 
682 // #i73790#
ResetAllFormatAttr()683 sal_uInt16 SwFormat::ResetAllFormatAttr()
684 {
685     if( !m_aSet.Count() )
686         return 0;
687 
688     if ( IsInCache() )
689     {
690         SwFrame::GetCache().Delete( this );
691         SetInCache( false );
692     }
693     SetInSwFntCache( false );
694 
695     // if Modify is locked then no modifications will be sent
696     if( IsModifyLocked() )
697         return m_aSet.ClearItem();
698 
699     SwAttrSet aOld( *m_aSet.GetPool(), m_aSet.GetRanges() ),
700               aNew( *m_aSet.GetPool(), m_aSet.GetRanges() );
701     bool bRet = 0 != m_aSet.ClearItem_BC( 0, &aOld, &aNew );
702     if( bRet )
703     {
704         SwAttrSetChg aChgOld( m_aSet, aOld );
705         SwAttrSetChg aChgNew( m_aSet, aNew );
706         ModifyNotification( &aChgOld, &aChgNew ); // send all modified ones
707     }
708     return aNew.Count();
709 }
710 
DelDiffs(const SfxItemSet & rSet)711 void SwFormat::DelDiffs( const SfxItemSet& rSet )
712 {
713     if( !m_aSet.Count() )
714         return;
715 
716     if ( IsInCache() )
717     {
718         SwFrame::GetCache().Delete( this );
719         SetInCache( false );
720     }
721     SetInSwFntCache( false );
722 
723     // if Modify is locked then no modifications will be sent
724     if( IsModifyLocked() )
725     {
726         m_aSet.Intersect( rSet );
727         return;
728     }
729 
730     SwAttrSet aOld( *m_aSet.GetPool(), m_aSet.GetRanges() ),
731               aNew( *m_aSet.GetPool(), m_aSet.GetRanges() );
732     bool bRet = 0 != m_aSet.Intersect_BC( rSet, &aOld, &aNew );
733     if( bRet )
734     {
735         SwAttrSetChg aChgOld( m_aSet, aOld );
736         SwAttrSetChg aChgNew( m_aSet, aNew );
737         ModifyNotification( &aChgOld, &aChgNew ); // send all modified ones
738     }
739 }
740 
741 /** SwFormat::IsBackgroundTransparent
742 
743     Virtual method to determine, if background of format is transparent.
744     Default implementation returns false. Thus, subclasses have to override
745     method, if the specific subclass can have a transparent background.
746 
747     @return false, default implementation
748 */
IsBackgroundTransparent() const749 bool SwFormat::IsBackgroundTransparent() const
750 {
751     return false;
752 }
753 
754 /*
755  * Document Interface Access
756  */
getIDocumentSettingAccess() const757 const IDocumentSettingAccess& SwFormat::getIDocumentSettingAccess() const { return GetDoc()->GetDocumentSettingManager(); }
getIDocumentDrawModelAccess() const758 const IDocumentDrawModelAccess& SwFormat::getIDocumentDrawModelAccess() const { return GetDoc()->getIDocumentDrawModelAccess(); }
getIDocumentDrawModelAccess()759 IDocumentDrawModelAccess& SwFormat::getIDocumentDrawModelAccess() { return GetDoc()->getIDocumentDrawModelAccess(); }
getIDocumentLayoutAccess() const760 const IDocumentLayoutAccess& SwFormat::getIDocumentLayoutAccess() const { return GetDoc()->getIDocumentLayoutAccess(); }
getIDocumentLayoutAccess()761 IDocumentLayoutAccess& SwFormat::getIDocumentLayoutAccess() { return GetDoc()->getIDocumentLayoutAccess(); }
getIDocumentTimerAccess()762 IDocumentTimerAccess& SwFormat::getIDocumentTimerAccess() { return GetDoc()->getIDocumentTimerAccess(); }
getIDocumentFieldsAccess()763 IDocumentFieldsAccess& SwFormat::getIDocumentFieldsAccess() { return GetDoc()->getIDocumentFieldsAccess(); }
getIDocumentChartDataProviderAccess()764 IDocumentChartDataProviderAccess& SwFormat::getIDocumentChartDataProviderAccess() { return GetDoc()->getIDocumentChartDataProviderAccess(); }
765 
GetGrabBagItem(uno::Any & rVal) const766 void SwFormat::GetGrabBagItem(uno::Any& rVal) const
767 {
768     if (m_pGrabBagItem.get())
769         m_pGrabBagItem->QueryValue(rVal);
770     else
771         rVal <<= uno::Sequence<beans::PropertyValue>();
772 }
773 
SetGrabBagItem(const uno::Any & rVal)774 void SwFormat::SetGrabBagItem(const uno::Any& rVal)
775 {
776     if (!m_pGrabBagItem.get())
777         m_pGrabBagItem.reset(new SfxGrabBagItem);
778 
779     m_pGrabBagItem->PutValue(rVal, 0);
780 }
781 
makeBackgroundBrushItem(bool bInP) const782 std::shared_ptr<SvxBrushItem> SwFormat::makeBackgroundBrushItem(bool bInP) const
783 {
784     if (supportsFullDrawingLayerFillAttributeSet())
785     {
786         // FALLBACKBREAKHERE should not be used; instead use [XATTR_FILL_FIRST .. XATTR_FILL_LAST]
787         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)");
788 
789         // fill the local static SvxBrushItem from the current ItemSet so that
790         // the fill attributes [XATTR_FILL_FIRST .. XATTR_FILL_LAST] are used
791         // as good as possible to create a fallback representation and return that
792         return getSvxBrushItemFromSourceSet(m_aSet, RES_BACKGROUND, bInP);
793     }
794 
795     return std::shared_ptr<SvxBrushItem>(static_cast<SvxBrushItem*>(m_aSet.GetBackground(bInP).Clone()));
796 }
797 
getSdrAllFillAttributesHelper() const798 drawinglayer::attribute::SdrAllFillAttributesHelperPtr SwFormat::getSdrAllFillAttributesHelper() const
799 {
800     return drawinglayer::attribute::SdrAllFillAttributesHelperPtr();
801 }
802 
803 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
804