workaround segfault in compiler on macos-clang-intel
[LibreOffice.git] / include / svl / itempool.hxx
blob7c3868ca99967098a49a3e391fc34cdb418e9809
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 #pragma once
22 #include <config_options.h>
23 #include <rtl/ref.hxx>
24 #include <svl/poolitem.hxx>
25 #include <svl/svldllapi.h>
26 #include <svl/typedwhich.hxx>
27 #include <svl/whichranges.hxx>
28 #include <memory>
29 #include <vector>
30 #include <unordered_set>
31 #include <unordered_map>
32 #include <o3tl/sorted_vector.hxx>
33 #include <salhelper/simplereferenceobject.hxx>
34 #include <svl/SfxBroadcaster.hxx>
36 // flag definitions to be used for _nItemInfoFlags
37 // in SfxItemInfo
38 #define SFX_ITEMINFOFLAG_NONE 0x0000
40 // Defines if this Item needs to be registered at the pool
41 // to make it accessible for the GetItemSurrogates call. It
42 // will not be included when this flag is not set, but also
43 // needs no registration. There are SAL_INFO calls in the
44 // GetItemSurrogates impl that will mention that
45 #define SFX_ITEMINFOFLAG_SUPPORT_SURROGATE 0x0001
47 class SVL_DLLPUBLIC ItemInfo
49 sal_uInt16 m_nWhich;
50 sal_uInt16 m_nSlotID;
51 sal_uInt16 m_nItemInfoFlags;
53 public:
54 ItemInfo(sal_uInt16 nWhich, sal_uInt16 nSlotID, sal_uInt16 nItemInfoFlags)
55 : m_nWhich(nWhich), m_nSlotID(nSlotID), m_nItemInfoFlags(nItemInfoFlags) {}
56 ItemInfo(const ItemInfo& rIemInfo) = default;
57 virtual ~ItemInfo() = default;
59 sal_uInt16 getWhich() const { return m_nWhich; }
60 virtual const SfxPoolItem* getItem() const = 0;
61 sal_uInt16 getSlotID() const { return m_nSlotID; }
62 sal_uInt16 getItemInfoFlags() const { return m_nItemInfoFlags; }
65 class SVL_DLLPUBLIC ItemInfoStatic : public ItemInfo
67 friend class ItemInfoPackage;
68 void setItem(SfxPoolItem* pItem)
70 if (nullptr != pItem)
71 pItem->setStaticDefault();
72 m_pItem.reset(pItem);
75 std::unique_ptr<const SfxPoolItem> m_pItem;
77 public:
78 ItemInfoStatic(sal_uInt16 nWhich, SfxPoolItem* pItem, sal_uInt16 nSlotID, sal_uInt16 nItemInfoFlags)
79 : ItemInfo(nWhich, nSlotID, nItemInfoFlags)
80 , m_pItem(pItem) { if(nullptr != pItem) pItem->setStaticDefault(); }
82 virtual const SfxPoolItem* getItem() const override { return m_pItem.get(); }
85 class SVL_DLLPUBLIC ItemInfoDynamic : public ItemInfo
87 std::unique_ptr<const SfxPoolItem> m_pItem;
89 public:
90 ItemInfoDynamic(const ItemInfo& rItemInfo, SfxPoolItem* pItem)
91 : ItemInfo(rItemInfo)
92 , m_pItem(pItem) { if(nullptr != pItem) pItem->setDynamicDefault(); }
94 virtual const SfxPoolItem* getItem() const override { return m_pItem.get(); }
97 class UNLESS_MERGELIBS(SVL_DLLPUBLIC) ItemInfoUser : public ItemInfo
99 const SfxPoolItem* m_pItem;
101 public:
102 ItemInfoUser(const ItemInfo& rItemInfo, SfxItemPool& rItemPool, const SfxPoolItem& rItem, bool bPassingOwnership = false);
103 virtual ~ItemInfoUser();
105 virtual const SfxPoolItem* getItem() const override { return m_pItem; }
108 typedef std::unordered_map<sal_uInt16, sal_uInt16> SlotIDToWhichIDMap;
110 class SVL_DLLPUBLIC ItemInfoPackage
112 protected:
113 // this is needed for on-demand creation of static entries in constructors
114 // derived from ItemInfoPackage or implementations of ::getItemInfo(). This
115 // takes ownership of the item
116 static void setItemAtItemInfoStatic(SfxPoolItem* pItem, ItemInfoStatic& rItemInfo) { rItemInfo.setItem(pItem); }
118 private:
119 // mechanism for buffered SlotIDToWhichIDMap
120 virtual const ItemInfoStatic& getItemInfoStatic(size_t nIndex) const = 0;
121 mutable SlotIDToWhichIDMap maSlotIDToWhichIDMap;
123 public:
124 ItemInfoPackage() = default;
125 virtual ~ItemInfoPackage() = default;
127 virtual size_t size() const = 0;
128 virtual const ItemInfo& getItemInfo(size_t nIndex, SfxItemPool& rPool) = 0;
129 virtual const ItemInfo& getExistingItemInfo(size_t /*nIndex*/);
130 const SlotIDToWhichIDMap& getSlotIDToWhichIDMap() const;
133 typedef std::unordered_set<SfxItemSet*> registeredSfxItemSets;
134 class SfxPoolItemHolder;
135 typedef std::unordered_set<SfxPoolItemHolder*> registeredSfxPoolItemHolders;
136 typedef std::vector<const SfxPoolItem*> ItemSurrogates;
137 typedef std::unordered_map<sal_uInt16, const ItemInfo*> userItemInfos;
138 typedef std::vector<const ItemInfo*> itemInfoVector;
140 /** Base class for providers of defaults of SfxPoolItems.
142 * The derived classes hold the concrete (const) instances which are referenced in several places
143 * (usually within a single document).
144 * This helps to lower the amount of calls to lifecycle methods, speeds up comparisons within a document
145 * and facilitates loading and saving of attributes.
147 class SVL_DLLPUBLIC SfxItemPool : public salhelper::SimpleReferenceObject
149 friend class SfxItemSet;
150 friend class SfxPoolItemHolder;
151 friend class SfxAllItemSet;
153 // allow ItemSetTooling to access
154 friend SfxPoolItem const* implCreateItemEntry(SfxItemPool&, SfxPoolItem const*, bool);
155 friend void implCleanupItemEntry(SfxPoolItem const*);
157 SfxBroadcaster aBC;
158 OUString aName;
159 SfxItemPool* mpMaster;
160 rtl::Reference<SfxItemPool> mpSecondary;
161 mutable WhichRangesContainer maPoolRanges;
162 sal_uInt16 mnStart;
163 sal_uInt16 mnEnd;
164 MapUnit eDefMetric;
166 registeredSfxItemSets maRegisteredSfxItemSets;
167 registeredSfxPoolItemHolders maRegisteredSfxPoolItemHolders;
168 bool mbShutdownHintSent;
170 itemInfoVector maItemInfos;
171 userItemInfos maUserItemInfos;
172 const SlotIDToWhichIDMap* mpSlotIDToWhichIDMap;
174 public:
175 void registerItemInfoPackage(
176 ItemInfoPackage& rPackage,
177 const std::function<SfxPoolItem*(sal_uInt16)>& rCallback = std::function<SfxPoolItem*(sal_uInt16)>());
178 protected:
179 const ItemInfo* impCheckItemInfoForClone(const ItemInfo* pInfo);
180 void impClearUserDefault(userItemInfos::iterator& rHit);
181 void impCreateUserDefault(const SfxPoolItem& rItem);
182 private:
183 void cleanupItemInfos();
185 private:
186 sal_uInt16 GetIndex_Impl(sal_uInt16 nWhich) const
188 if (IsInRange(nWhich))
189 return nWhich - mnStart;
190 assert(false && "missing bounds check before use");
191 return 0;
193 sal_uInt16 GetSize_Impl() const { return mnEnd - mnStart + 1; }
194 SfxItemPool* getTargetPool(sal_uInt16 nWhich) const;
196 // moved to private: use the access methods, e.g. NeedsSurrogateSupport
197 SVL_DLLPRIVATE bool CheckItemInfoFlag(sal_uInt16 nWhich, sal_uInt16 nMask) const;
198 SVL_DLLPRIVATE bool CheckItemInfoFlag_Impl(sal_uInt16 nPos, sal_uInt16 nMask) const
199 { return maItemInfos[nPos]->getItemInfoFlags() & nMask; }
201 void registerItemSet(SfxItemSet& rSet);
202 void unregisterItemSet(SfxItemSet& rSet);
204 void registerPoolItemHolder(SfxPoolItemHolder& rHolder);
205 void unregisterPoolItemHolder(SfxPoolItemHolder& rHolder);
207 public:
208 // for default SfxItemSet::CTOR, set default WhichRanges
209 const WhichRangesContainer& GetMergedIdRanges() const;
211 protected:
212 static inline void AddRef(const SfxPoolItem& rItem);
213 static inline sal_uInt32 ReleaseRef(const SfxPoolItem& rItem, sal_uInt32 n = 1);
215 public:
216 SfxItemPool(const SfxItemPool &rPool);
217 SfxItemPool(const OUString &rName);
218 virtual ~SfxItemPool();
220 SfxBroadcaster& BC();
222 // UserDefaults: Every PoolDefault can be 'overloaded' with a user-defined
223 // default. This is then owned by the pool. The read access is limited
224 // to check the UserDefaults, so it *will* return nullptr if none is set
225 void SetUserDefaultItem( const SfxPoolItem& );
226 const SfxPoolItem* GetUserDefaultItem( sal_uInt16 nWhich ) const;
227 template<class T> const T* GetUserDefaultItem( TypedWhichId<T> nWhich ) const
228 { return static_cast<const T*>(GetUserDefaultItem(sal_uInt16(nWhich))); }
229 void ResetUserDefaultItem( sal_uInt16 nWhich );
231 // PoolDefaults: Owned by the pool. The read access will only return
232 // nullptr if the WhichID asked for is not in the range of the pool,
233 // making the request invalid.
234 const SfxPoolItem * GetPoolDefaultItem(sal_uInt16 nWhich) const;
235 template<class T> const T* GetPoolDefaultItem( TypedWhichId<T> nWhich ) const
236 { return static_cast<const T*>(GetPoolDefaultItem(sal_uInt16(nWhich))); }
238 // UserOrPoolDefaults: Combination of UserDefaults and PoolDefaults.
239 // UserDefaults will be preferred. If none is set for that WhichID,
240 // the PoolDefault will be returned.
241 // Note that read access will return a reference, but this will lead
242 // to an asserted error when the given WhichID is not in the range of
243 // the pool.
244 const SfxPoolItem& GetUserOrPoolDefaultItem( sal_uInt16 nWhich ) const;
245 template<class T> const T& GetUserOrPoolDefaultItem( TypedWhichId<T> nWhich ) const
246 { return static_cast<const T&>(GetUserOrPoolDefaultItem(sal_uInt16(nWhich))); }
248 virtual MapUnit GetMetric( sal_uInt16 nWhich ) const;
249 void SetDefaultMetric( MapUnit eNewMetric );
250 MapUnit GetDefaultMetric() const { return eDefMetric; }
252 /** Request string representation of pool items.
254 This virtual function produces a string representation
255 from the respective SfxItemPool subclass' known SfxPoolItems.
257 Subclasses, please override this method, and handle
258 SfxPoolItems that don't return useful/complete information on
259 SfxPoolItem::GetPresentation()
261 This baseclass yields the unmodified string representation of
262 rItem.
264 @param[in] rItem
265 SfxPoolItem to query the string representation of
267 @param[in] ePresent
268 requested kind of representation - see SfxItemPresentation
270 @param[in] eMetric
271 requested unit of measure of the representation
273 @param[out] rText
274 string representation of 'rItem'
276 @return true if it has a valid string representation
278 virtual bool GetPresentation( const SfxPoolItem& rItem,
279 MapUnit ePresentationMetric,
280 OUString& rText,
281 const IntlWrapper& rIntlWrapper ) const;
282 virtual rtl::Reference<SfxItemPool> Clone() const;
283 const OUString& GetName() const { return aName; }
285 public:
286 // SurrogateData callback helper for iterateItemSurrogates
287 class SurrogateData
289 public:
290 virtual ~SurrogateData() = default;
291 SurrogateData(const SurrogateData&) = default;
292 SurrogateData() = default;
294 // read-access to Item
295 virtual const SfxPoolItem& getItem() const = 0;
297 // write-access when Item needs to be modified
298 virtual const SfxPoolItem* setItem(std::unique_ptr<SfxPoolItem>) = 0;
301 // Iterate using a lambda/callback with read/write access to registered SfxPoolItems.
302 // If you use this (look for current usages) inside the callback you may
303 // return true; // to continue callback (like 'continue')
304 // return false; // to end callbacks (like 'break')
305 void iterateItemSurrogates(
306 sal_uInt16 nWhich,
307 const std::function<bool(SfxItemPool::SurrogateData& rData)>& rItemCallback) const;
309 // Read-only access to registered SfxPoolItems
310 // NOTE: In *no* case use const_cast and change those Items (!)
311 // Read commit text for more information
312 void GetItemSurrogates(ItemSurrogates& rTarget, sal_uInt16 nWhich) const;
314 sal_uInt16 GetFirstWhich() const { return mnStart; }
315 sal_uInt16 GetLastWhich() const { return mnEnd; }
316 bool IsInRange( sal_uInt16 nWhich ) const { return nWhich >= mnStart && nWhich <= mnEnd; }
318 void SetSecondaryPool( SfxItemPool *pPool );
319 SfxItemPool* GetSecondaryPool() const { return mpSecondary.get(); }
320 /* get the last pool by following the GetSecondaryPool chain */
321 SfxItemPool* GetLastPoolInChain();
322 SfxItemPool* GetMasterPool() const { return mpMaster; }
323 void sendShutdownHint();
325 // syntactical sugar: direct call to not have to use the flag define
326 // and make the intention clearer
327 bool NeedsSurrogateSupport(sal_uInt16 nWhich) const
328 { return CheckItemInfoFlag(nWhich, SFX_ITEMINFOFLAG_SUPPORT_SURROGATE); }
330 // tries to translate back from SlotID to WhichID.
331 // If none is defined, return nSlot.
332 // If nSlot is not a SlotID, return nSlot.
333 sal_uInt16 GetWhichIDFromSlotID(sal_uInt16 nSlot, bool bDeep = true) const;
334 template<class T> TypedWhichId<T> GetWhichIDFromSlotID(TypedWhichId<T> nSlot, bool bDeep = true) const
335 { return TypedWhichId<T>(GetWhichIDFromSlotID(sal_uInt16(nSlot), bDeep)); }
337 // get SlotID that may be registered in the SfxItemInfo for
338 // the given WhichID.
339 // If none is defined, return nWhich.
340 // If nWhich is not a WhichID, return nWhich.
341 sal_uInt16 GetSlotId( sal_uInt16 nWhich ) const;
343 // same as GetWhichIDFromSlotID, but returns 0 in error cases, so:
344 // If none is defined, return 0.
345 // If nSlot is not a SlotID, return 0.
346 sal_uInt16 GetTrueWhichIDFromSlotID( sal_uInt16 nSlot, bool bDeep = true ) const;
348 // same as GetSlotId, but returns 0 in error cases, so:
349 // If none is defined, return 0.
350 // If nWhich is not a WhichID, return 0.
351 sal_uInt16 GetTrueSlotId( sal_uInt16 nWhich ) const;
353 static bool IsWhich(sal_uInt16 nId) { return nId && nId <= SFX_WHICH_MAX; }
354 static bool IsSlot(sal_uInt16 nId) { return nId && nId > SFX_WHICH_MAX; }
356 private:
357 const SfxItemPool& operator=(const SfxItemPool &) = delete;
359 //IDs below or equal are Which IDs, IDs above slot IDs
360 static const sal_uInt16 SFX_WHICH_MAX = 4999;
363 // only the pool may manipulate the reference counts
364 inline void SfxItemPool::AddRef(const SfxPoolItem& rItem)
366 rItem.AddRef();
369 // only the pool may manipulate the reference counts
370 inline sal_uInt32 SfxItemPool::ReleaseRef(const SfxPoolItem& rItem, sal_uInt32 n)
372 return rItem.ReleaseRef(n);
375 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */