1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <sal/config.h>
29 #include <svl/svldllapi.h>
30 #include <svl/poolitem.hxx>
31 #include <svl/typedwhich.hxx>
32 #include <svl/whichranges.hxx>
36 class SAL_WARN_UNUSED SVL_DLLPUBLIC SfxItemSet
38 friend class SfxItemIter
;
39 friend class SfxWhichIter
;
41 SfxItemPool
* m_pPool
; ///< pool that stores the items
42 const SfxItemSet
* m_pParent
; ///< derivation
43 SfxPoolItem
const** m_ppItems
; ///< pointer to array of items, we allocate and free this unless m_bItemsFixed==true
44 WhichRangesContainer m_pWhichRanges
; ///< array of Which Ranges
45 sal_uInt16 m_nCount
; ///< number of items
46 bool m_bItemsFixed
; ///< true if this is a SfxItemSetFixed object
48 friend class SfxItemPoolCache
;
49 friend class SfxAllItemSet
;
52 SVL_DLLPRIVATE
void RecreateRanges_Impl(const WhichRangesContainer
& pNewRanges
);
55 SfxPoolItem
const** GetItems_Impl() const { return m_ppItems
; }
58 const SfxItemSet
& operator=(const SfxItemSet
&) = delete;
61 // Notification-Callback
62 virtual void Changed( const SfxPoolItem
& rOld
, const SfxPoolItem
& rNew
);
64 void PutDirect(const SfxPoolItem
&rItem
);
66 virtual const SfxPoolItem
* PutImpl( const SfxPoolItem
&, sal_uInt16 nWhich
, bool bPassingOwnership
);
68 /** special constructor for SfxAllItemSet */
69 enum class SfxAllItemSetFlag
{ Flag
};
70 SfxItemSet( SfxItemPool
&, SfxAllItemSetFlag
);
71 /** special constructor for SfxItemSetFixed */
72 SfxItemSet( SfxItemPool
&, WhichRangesContainer
&& ranges
, SfxPoolItem
const ** ppItems
);
75 SfxItemSet( const SfxItemSet
& );
76 SfxItemSet( SfxItemSet
&& ) noexcept
;
77 SfxItemSet( SfxItemPool
& );
78 SfxItemSet( SfxItemPool
&, WhichRangesContainer ranges
);
80 SfxItemSet( SfxItemPool
& rPool
, sal_uInt16 nWhichStart
, sal_uInt16 nWhichEnd
)
81 : SfxItemSet(rPool
, WhichRangesContainer(nWhichStart
, nWhichEnd
)) {}
83 template<sal_uInt16
... WIDs
>
84 SfxItemSet(SfxItemPool
& pool
, svl::Items_t
<WIDs
...> wids
)
85 : SfxItemSet(pool
, WhichRangesContainer(wids
)) {}
87 virtual ~SfxItemSet();
89 virtual std::unique_ptr
<SfxItemSet
> Clone(bool bItems
= true, SfxItemPool
*pToPool
= nullptr) const;
90 /** note that this only works if you know for sure that you are dealing with an SfxItemSet
91 and not one of it's subclasses. */
92 SfxItemSet
CloneAsValue(bool bItems
= true, SfxItemPool
*pToPool
= nullptr) const;
94 // Get number of items
95 sal_uInt16
Count() const { return m_nCount
; }
96 sal_uInt16
TotalCount() const;
98 const SfxPoolItem
& Get( sal_uInt16 nWhich
, bool bSrchInParent
= true ) const;
100 const T
& Get( TypedWhichId
<T
> nWhich
, bool bSrchInParent
= true ) const
102 return static_cast<const T
&>(Get(sal_uInt16(nWhich
), bSrchInParent
));
105 /** This method eases accessing single Items in the SfxItemSet.
107 @param nId SlotId or the Item's WhichId
108 @param bSearchInParent also search in parent ItemSets
109 @returns 0 if the ItemSet does not contain an Item with the Id 'nWhich'
111 const SfxPoolItem
* GetItem(sal_uInt16 nWhich
, bool bSearchInParent
= true) const;
113 /// Templatized version of GetItem() to directly return the correct type.
114 template<class T
> const T
* GetItem(sal_uInt16 nWhich
, bool bSearchInParent
= true) const
116 const SfxPoolItem
* pItem
= GetItem(nWhich
, bSearchInParent
);
117 const T
* pCastedItem
= dynamic_cast<const T
*>(pItem
);
119 assert(!pItem
|| pCastedItem
); // if it exists, must have the correct type
122 template<class T
> const T
* GetItem( TypedWhichId
<T
> nWhich
, bool bSearchInParent
= true ) const
124 return GetItem
<T
>(sal_uInt16(nWhich
), bSearchInParent
);
128 /// Templatized static version of GetItem() to directly return the correct type if the SfxItemSet is available.
129 template<class T
> static const T
* GetItem(const SfxItemSet
* pItemSet
, sal_uInt16 nWhich
, bool bSearchInParent
)
132 return pItemSet
->GetItem
<T
>(nWhich
, bSearchInParent
);
137 static const T
* GetItem(const SfxItemSet
* pItemSet
, TypedWhichId
<T
> nWhich
,
138 bool bSearchInParent
)
140 return GetItem
<T
>(pItemSet
, static_cast<sal_uInt16
>(nWhich
), bSearchInParent
);
143 sal_uInt16
GetWhichByPos(sal_uInt16 nPos
) const;
145 SfxItemState
GetItemState( sal_uInt16 nWhich
,
146 bool bSrchInParent
= true,
147 const SfxPoolItem
**ppItem
= nullptr ) const;
150 SfxItemState
GetItemState( TypedWhichId
<T
> nWhich
,
151 bool bSrchInParent
= true,
152 const T
**ppItem
= nullptr ) const
153 { return GetItemState(sal_uInt16(nWhich
), bSrchInParent
, reinterpret_cast<SfxPoolItem
const**>(ppItem
)); }
155 /// Templatized version of GetItemState() to directly return the correct type.
157 const T
* GetItemIfSet( TypedWhichId
<T
> nWhich
,
158 bool bSrchInParent
= true ) const
160 const SfxPoolItem
* pItem
= nullptr;
161 if( SfxItemState::SET
== GetItemState(sal_uInt16(nWhich
), bSrchInParent
, &pItem
) )
162 return static_cast<const T
*>(pItem
);
166 bool HasItem(sal_uInt16 nWhich
, const SfxPoolItem
** ppItem
= nullptr) const;
168 bool HasItem(TypedWhichId
<T
> nWhich
, const T
** ppItem
= nullptr) const
169 { return HasItem(sal_uInt16(nWhich
), reinterpret_cast<const SfxPoolItem
**>(ppItem
)); }
171 void DisableItem(sal_uInt16 nWhich
);
172 void InvalidateItem( sal_uInt16 nWhich
);
173 sal_uInt16
ClearItem( sal_uInt16 nWhich
= 0);
174 void ClearInvalidItems();
175 void InvalidateAllItems(); // HACK(via nWhich = 0) ???
177 inline void SetParent( const SfxItemSet
* pNew
);
179 // add, delete items, work on items
181 const SfxPoolItem
* Put( const SfxPoolItem
& rItem
, sal_uInt16 nWhich
)
182 { return PutImpl(rItem
, nWhich
, /*bPassingOwnership*/false); }
183 const SfxPoolItem
* Put( std::unique_ptr
<SfxPoolItem
> xItem
, sal_uInt16 nWhich
)
184 { return PutImpl(*xItem
.release(), nWhich
, /*bPassingOwnership*/true); }
185 const SfxPoolItem
* Put( const SfxPoolItem
& rItem
)
186 { return Put(rItem
, rItem
.Which()); }
187 const SfxPoolItem
* Put( std::unique_ptr
<SfxPoolItem
> xItem
)
188 { auto nWhich
= xItem
->Which(); return Put(std::move(xItem
), nWhich
); }
189 bool Put( const SfxItemSet
&,
190 bool bInvalidAsDefault
= true );
191 void PutExtended( const SfxItemSet
&,
192 SfxItemState eDontCareAs
,
193 SfxItemState eDefaultAs
);
195 bool Set( const SfxItemSet
&, bool bDeep
= true );
197 void Intersect( const SfxItemSet
& rSet
);
198 void MergeValues( const SfxItemSet
& rSet
);
199 void Differentiate( const SfxItemSet
& rSet
);
200 void MergeValue( const SfxPoolItem
& rItem
, bool bOverwriteDefaults
= false );
202 SfxItemPool
* GetPool() const { return m_pPool
; }
203 const WhichRangesContainer
& GetRanges() const { return m_pWhichRanges
; }
204 void SetRanges( const WhichRangesContainer
& );
205 void SetRanges( WhichRangesContainer
&& );
206 void MergeRange( sal_uInt16 nFrom
, sal_uInt16 nTo
);
207 const SfxItemSet
* GetParent() const { return m_pParent
; }
209 bool operator==(const SfxItemSet
&) const;
211 /** Compare possibly ignoring SfxItemPool pointer.
213 This can be used to compare the content of two SfxItemSet even if they
214 don't share the same pool. EditTextObject::Equals(...,false) uses this
215 which is needed in ScGlobal::EETextObjEqual() for
216 ScPageHFItem::operator==()
219 if <FALSE/> ignore SfxItemPool pointer,
220 if <TRUE/> compare also SfxItemPool pointer (identical to operator==())
222 bool Equals(const SfxItemSet
&, bool bComparePool
) const;
224 void dumpAsXml(xmlTextWriterPtr pWriter
) const;
227 sal_uInt16
ClearSingleItemImpl( sal_uInt16 nWhich
, std::optional
<sal_uInt16
> oItemOffsetHint
);
228 sal_uInt16
ClearAllItemsImpl();
229 SfxItemState
GetItemStateImpl( sal_uInt16 nWhich
,
231 const SfxPoolItem
**ppItem
,
232 std::optional
<sal_uInt16
> oItemsOffsetHint
) const;
235 inline void SfxItemSet::SetParent( const SfxItemSet
* pNew
)
240 class SVL_DLLPUBLIC SfxAllItemSet final
: public SfxItemSet
242 // Handles all Ranges. Ranges are automatically modified by putting items.
246 SfxAllItemSet( SfxItemPool
&rPool
);
247 SfxAllItemSet( const SfxItemSet
& );
248 SfxAllItemSet( const SfxAllItemSet
& );
250 virtual std::unique_ptr
<SfxItemSet
> Clone( bool bItems
= true, SfxItemPool
*pToPool
= nullptr ) const override
;
252 virtual const SfxPoolItem
* PutImpl( const SfxPoolItem
&, sal_uInt16 nWhich
, bool bPassingOwnership
) override
;
256 namespace svl::detail
259 * Determines the number of sal_uInt16s in a container of pairs of
260 * sal_uInt16s, each representing a range of sal_uInt16s, and total capacity of the ranges.
262 template <sal_uInt16 WID1
, sal_uInt16 WID2
, sal_uInt16
... Rest
>
263 static constexpr sal_uInt16
CountRanges1()
265 sal_uInt16 nCapacity
= rangeSize(WID1
, WID2
);
266 if constexpr (sizeof...(Rest
) > 0)
267 nCapacity
+= CountRanges1
<Rest
...>();
271 // Allocate the items array inside the object, to reduce allocation cost.
273 template<sal_uInt16
... WIDs
>
274 class SfxItemSetFixed
: public SfxItemSet
277 SfxItemSetFixed( SfxItemPool
& rPool
)
278 : SfxItemSet(rPool
, WhichRangesContainer(svl::Items_t
<WIDs
...>{}), m_aItems
) {}
280 static constexpr sal_uInt16 NITEMS
= svl::detail::CountRanges1
<WIDs
...>();
281 const SfxPoolItem
* m_aItems
[NITEMS
] = {};
284 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */