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 #ifndef INCLUDED_SVL_POOLITEM_HXX
21 #define INCLUDED_SVL_POOLITEM_HXX
22
23 #include <sal/config.h>
24
25 #include <memory>
26
27 #include <com/sun/star/uno/Any.hxx>
28 #include <svl/hint.hxx>
29 #include <svl/svldllapi.h>
30 #include <svl/typedwhich.hxx>
31 #include <tools/mapunit.hxx>
32 #include <tools/long.hxx>
33 #include <boost/property_tree/ptree_fwd.hpp>
34
35 class IntlWrapper;
36
37 enum class SfxItemKind : sal_Int8
38 {
39 NONE,
40 DeleteOnIdle,
41 StaticDefault,
42 PoolDefault
43 };
44
45 #define SFX_ITEMS_OLD_MAXREF 0xffef
46 #define SFX_ITEMS_MAXREF 0xfffffffe
47 #define SFX_ITEMS_SPECIAL 0xffffffff
48
49 #define CONVERT_TWIPS 0x80 // Uno conversion for measurement (for MemberId)
50
51 // warning, if there is no boolean inside the any this will always return the value false
Any2Bool(const css::uno::Any & rValue)52 inline bool Any2Bool( const css::uno::Any&rValue )
53 {
54 bool bValue = false;
55 if( !(rValue >>= bValue) )
56 {
57 sal_Int32 nNum = 0;
58 if( rValue >>= nNum )
59 bValue = nNum != 0;
60 }
61
62 return bValue;
63 }
64
65 /*
66 * The values of this enum describe the degree of textual
67 * representation of an item after calling the virtual
68 * method <SfxPoolItem::GetPresentation()const>.
69 */
70 enum class SfxItemPresentation
71 {
72 Nameless,
73 Complete
74 };
75
76 /**
77 * These values have to match the values in the
78 * css::frame::status::ItemState IDL
79 * to be found at offapi/com/sun/star/frame/status/ItemState.idl
80 */
81 enum class SfxItemState {
82
83 /** Specifies an unknown state. */
84 UNKNOWN = 0,
85
86 /** Specifies that the property is currently disabled. */
87 DISABLED = 0x0001,
88
89 /** Specifies that the property is currently in a don't care state.
90 * <br/>
91 * This is normally used if a selection provides more than one state
92 * for a property at the same time.
93 */
94 DONTCARE = 0x0010,
95
96 /** Specifies that the property is currently in a default state. */
97 DEFAULT = 0x0020,
98
99 /** The property has been explicitly set to a given value hence we know
100 * we are not taking the default value.
101 * <br/>
102 * For example, you may want to get the font color and it might either
103 * be the default one or one that has been explicitly set.
104 */
105 SET = 0x0040
106 };
107
108 #define INVALID_POOL_ITEM reinterpret_cast<SfxPoolItem*>(-1)
109
110 class SfxItemPool;
111 class SfxItemSet;
112 typedef struct _xmlTextWriter* xmlTextWriterPtr;
113
114 class SVL_DLLPUBLIC SfxPoolItem
115 {
116 friend class SfxItemPool;
117 friend class SfxItemDisruptor_Impl;
118 friend class SfxItemPoolCache;
119 friend class SfxItemSet;
120 friend class SfxVoidItem;
121
122 mutable sal_uInt32 m_nRefCount;
123 sal_uInt16 m_nWhich;
124 SfxItemKind m_nKind;
125
126 private:
127 inline void SetRefCount(sal_uInt32 n);
128 inline void SetKind( SfxItemKind n );
129 public:
130 inline void AddRef(sal_uInt32 n = 1) const;
131 private:
132 inline sal_uInt32 ReleaseRef(sal_uInt32 n = 1) const;
133
134 protected:
135 explicit SfxPoolItem( sal_uInt16 nWhich = 0 );
SfxPoolItem(const SfxPoolItem & rCopy)136 SfxPoolItem( const SfxPoolItem& rCopy)
137 : SfxPoolItem(rCopy.m_nWhich) {}
138
139 public:
140 virtual ~SfxPoolItem();
141
SetWhich(sal_uInt16 nId)142 void SetWhich( sal_uInt16 nId )
143 {
144 // can only change the Which before we are in a set
145 assert(m_nRefCount==0);
146 m_nWhich = nId;
147 }
Which() const148 sal_uInt16 Which() const { return m_nWhich; }
149 // StaticWhichCast asserts if the TypedWhichId is not matching its type, otherwise it returns a reference.
150 // You can use StaticWhichCast when you are sure about the type at compile time -- like a static_cast.
StaticWhichCast(TypedWhichId<T> nId)151 template<class T> T& StaticWhichCast(TypedWhichId<T> nId)
152 {
153 (void)nId;
154 assert(nId == m_nWhich);
155 assert(dynamic_cast<T*>(this));
156 return *static_cast<T*>(this);
157 }
StaticWhichCast(TypedWhichId<T> nId) const158 template<class T> const T& StaticWhichCast(TypedWhichId<T> nId) const
159 {
160 (void)nId;
161 assert(nId == m_nWhich);
162 assert(dynamic_cast<const T*>(this));
163 return *static_cast<const T*>(this);
164 }
165 // DynamicWhichCast returns nullptr if the TypedWhichId is not matching its type, otherwise it returns a typed pointer.
166 // it asserts if the TypedWhichId matches its Which, but not the RTTI type.
167 // You can use DynamicWhichCast when you are not sure about the type at compile time -- like a dynamic_cast.
DynamicWhichCast(TypedWhichId<T> nId)168 template<class T> T* DynamicWhichCast(TypedWhichId<T> nId)
169 {
170 if(m_nWhich != nId)
171 return nullptr;
172 assert(dynamic_cast<T*>(this));
173 return static_cast<T*>(this);
174 }
DynamicWhichCast(TypedWhichId<T> nId) const175 template<class T> const T* DynamicWhichCast(TypedWhichId<T> nId) const
176 {
177 if(m_nWhich != nId)
178 return nullptr;
179 assert(dynamic_cast<const T*>(this));
180 return static_cast<const T*>(this);
181 }
182 virtual bool operator==( const SfxPoolItem& ) const = 0;
operator !=(const SfxPoolItem & rItem) const183 bool operator!=( const SfxPoolItem& rItem ) const
184 { return !(*this == rItem); }
185
186 // Sorting is only used for faster searching in a pool which contains large quantities
187 // of a single kind of pool item.
operator <(const SfxPoolItem &) const188 virtual bool operator<( const SfxPoolItem& ) const { assert(false); return false; }
IsSortable() const189 virtual bool IsSortable() const { return false; }
190
191 /** @return true if it has a valid string representation */
192 virtual bool GetPresentation( SfxItemPresentation ePresentation,
193 MapUnit eCoreMetric,
194 MapUnit ePresentationMetric,
195 OUString &rText,
196 const IntlWrapper& rIntlWrapper ) const;
197
198 virtual void ScaleMetrics( tools::Long lMult, tools::Long lDiv );
199 virtual bool HasMetrics() const;
200
201 virtual bool QueryValue( css::uno::Any& rVal, sal_uInt8 nMemberId = 0 ) const;
202 virtual bool PutValue( const css::uno::Any& rVal, sal_uInt8 nMemberId );
203
204 virtual SfxPoolItem* Clone( SfxItemPool *pPool = nullptr ) const = 0;
205 // clone and call SetWhich
206 std::unique_ptr<SfxPoolItem> CloneSetWhich( sal_uInt16 nNewWhich ) const;
CloneSetWhich(TypedWhichId<T> nId) const207 template<class T> std::unique_ptr<T> CloneSetWhich( TypedWhichId<T> nId ) const
208 {
209 return std::unique_ptr<T>(static_cast<T*>(CloneSetWhich(sal_uInt16(nId)).release()));
210 }
211
GetRefCount() const212 sal_uInt32 GetRefCount() const { return m_nRefCount; }
GetKind() const213 SfxItemKind GetKind() const { return m_nKind; }
214 virtual void dumpAsXml(xmlTextWriterPtr pWriter) const;
215 virtual boost::property_tree::ptree dumpAsJSON() const;
216
217 /** Only SfxVoidItem shall and must return true for this.
218
219 This avoids costly calls to dynamic_cast<const SfxVoidItem*>()
220 specifically in SfxItemSet::GetItemState()
221 */
222 virtual bool IsVoidItem() const;
223
224 private:
225 SfxPoolItem& operator=( const SfxPoolItem& ) = delete;
226 };
227
SetRefCount(sal_uInt32 n)228 inline void SfxPoolItem::SetRefCount(sal_uInt32 n)
229 {
230 m_nRefCount = n;
231 m_nKind = SfxItemKind::NONE;
232 }
233
SetKind(SfxItemKind n)234 inline void SfxPoolItem::SetKind( SfxItemKind n )
235 {
236 m_nRefCount = SFX_ITEMS_SPECIAL;
237 m_nKind = n;
238 }
239
AddRef(sal_uInt32 n) const240 inline void SfxPoolItem::AddRef(sal_uInt32 n) const
241 {
242 assert(m_nRefCount <= SFX_ITEMS_MAXREF && "AddRef with non-Pool-Item");
243 assert(n <= SFX_ITEMS_MAXREF - m_nRefCount && "AddRef: refcount overflow");
244 m_nRefCount += n;
245 }
246
ReleaseRef(sal_uInt32 n) const247 inline sal_uInt32 SfxPoolItem::ReleaseRef(sal_uInt32 n) const
248 {
249 assert(m_nRefCount <= SFX_ITEMS_MAXREF && "ReleaseRef with non-Pool-Item");
250 assert(n <= m_nRefCount);
251 m_nRefCount -= n;
252 return m_nRefCount;
253 }
254
IsPoolDefaultItem(const SfxPoolItem * pItem)255 inline bool IsPoolDefaultItem(const SfxPoolItem *pItem )
256 {
257 return pItem && pItem->GetKind() == SfxItemKind::PoolDefault;
258 }
259
IsStaticDefaultItem(const SfxPoolItem * pItem)260 inline bool IsStaticDefaultItem(const SfxPoolItem *pItem )
261 {
262 return pItem && pItem->GetKind() == SfxItemKind::StaticDefault;
263 }
264
IsDefaultItem(const SfxPoolItem * pItem)265 inline bool IsDefaultItem( const SfxPoolItem *pItem )
266 {
267 return pItem && (pItem->GetKind() == SfxItemKind::StaticDefault || pItem->GetKind() == SfxItemKind::PoolDefault);
268 }
269
IsPooledItem(const SfxPoolItem * pItem)270 inline bool IsPooledItem( const SfxPoolItem *pItem )
271 {
272 return pItem && pItem->GetRefCount() > 0 && pItem->GetRefCount() <= SFX_ITEMS_MAXREF;
273 }
274
IsInvalidItem(const SfxPoolItem * pItem)275 inline bool IsInvalidItem(const SfxPoolItem *pItem)
276 {
277 return pItem == INVALID_POOL_ITEM;
278 }
279
280 class SVL_DLLPUBLIC SfxVoidItem final: public SfxPoolItem
281 {
282 public:
283 static SfxPoolItem* CreateDefault();
284 explicit SfxVoidItem( sal_uInt16 nWhich );
285 virtual ~SfxVoidItem() override;
286
287 SfxVoidItem(SfxVoidItem const &) = default;
288 SfxVoidItem(SfxVoidItem &&) = default;
289 SfxVoidItem & operator =(SfxVoidItem const &) = delete; // due to SfxPoolItem
290 SfxVoidItem & operator =(SfxVoidItem &&) = delete; // due to SfxPoolItem
291
292 virtual bool operator==( const SfxPoolItem& ) const override;
293
294 virtual bool GetPresentation( SfxItemPresentation ePres,
295 MapUnit eCoreMetric,
296 MapUnit ePresMetric,
297 OUString &rText,
298 const IntlWrapper& ) const override;
299 virtual void dumpAsXml(xmlTextWriterPtr pWriter) const override;
300
301 // create a copy of itself
302 virtual SfxVoidItem* Clone( SfxItemPool *pPool = nullptr ) const override;
303
304 /** Always returns true as this is an SfxVoidItem. */
305 virtual bool IsVoidItem() const override;
306 };
307
308 class SVL_DLLPUBLIC SfxSetItem: public SfxPoolItem
309 {
310 std::unique_ptr<SfxItemSet> pSet;
311
312 SfxSetItem & operator=( const SfxSetItem& ) = delete;
313
314 public:
315 SfxSetItem( sal_uInt16 nWhich, std::unique_ptr<SfxItemSet> &&pSet );
316 SfxSetItem( sal_uInt16 nWhich, const SfxItemSet &rSet );
317 SfxSetItem( const SfxSetItem&, SfxItemPool *pPool = nullptr );
318 virtual ~SfxSetItem() override;
319
320 virtual bool operator==( const SfxPoolItem& ) const override;
321
322 virtual bool GetPresentation( SfxItemPresentation ePres,
323 MapUnit eCoreMetric,
324 MapUnit ePresMetric,
325 OUString &rText,
326 const IntlWrapper& ) const override;
327
328 // create a copy of itself
329 virtual SfxSetItem* Clone( SfxItemPool *pPool = nullptr ) const override = 0;
330
GetItemSet() const331 const SfxItemSet& GetItemSet() const
332 { return *pSet; }
GetItemSet()333 SfxItemSet& GetItemSet()
334 { return *pSet; }
335 };
336
337 class SVL_DLLPUBLIC SfxPoolItemHint final : public SfxHint
338 {
339 SfxPoolItem* pObj;
340 public:
SfxPoolItemHint(SfxPoolItem * Object)341 explicit SfxPoolItemHint( SfxPoolItem* Object ) : pObj(Object) {}
GetObject() const342 SfxPoolItem* GetObject() const { return pObj; }
343 };
344
345 #endif
346
347 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
348