/src/libreoffice/svl/source/items/itempool.cxx
Line | Count | Source |
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 <svl/itempool.hxx> |
21 | | #include <svl/setitem.hxx> |
22 | | |
23 | | #include <string.h> |
24 | | #include <libxml/xmlwriter.h> |
25 | | |
26 | | #include <osl/diagnose.h> |
27 | | #include <sal/log.hxx> |
28 | | #include <svl/SfxBroadcaster.hxx> |
29 | | #include <svl/hint.hxx> |
30 | | #include <svl/itemset.hxx> |
31 | | #include <tools/debug.hxx> |
32 | | #include <tools/mapunit.hxx> |
33 | | |
34 | | #include <cassert> |
35 | | #include <vector> |
36 | | |
37 | | // WhichIDs that need to set SFX_ITEMINFOFLAG_SUPPORT_SURROGATE in SfxItemInfo |
38 | | // to true to allow a register of all items of that type/with that WhichID |
39 | | // to be accessible using SfxItemPool::GetItemSurrogates. Created by |
40 | | // grepping for 'GetItemSurrogates' usages & interpreting. Some |
41 | | // are double, more may be necessary. There is a SAL_INFO("svl.items", ...) |
42 | | // in SfxItemPool::GetItemSurrogates that will give hints on missing flags. |
43 | | // |
44 | | // due to SwTable::UpdateFields |
45 | | // due to SwCursorShell::GotoNxtPrvTableFormula |
46 | | // due to DocumentFieldsManager::UpdateTableFields |
47 | | // due to SwTable::GatherFormulas |
48 | | // RES_BOXATR_FORMULA ok |
49 | | // due to SwContentTree::EditEntry |
50 | | // due to SwDoc::FindINetAttr |
51 | | // due to SwUndoResetAttr::RedoImpl |
52 | | // due to SwContentTree::EditEntry |
53 | | // due to SwContentTree::BringEntryToAttention |
54 | | // RES_TXTATR_REFMARK ok |
55 | | // due to ImpEditEngine::WriteRTF |
56 | | // due to ScDocument::UpdateFontCharSet() |
57 | | // due to ScXMLFontAutoStylePool_Impl |
58 | | // due to SdXImpressDocument::getPropertyValue |
59 | | // due to Writer::AddFontItems_ |
60 | | // EE_CHAR_FONTINFO ok |
61 | | // due to ImpEditEngine::WriteRTF |
62 | | // due to ScXMLFontAutoStylePool_Impl |
63 | | // due to SdXImpressDocument::getPropertyValue |
64 | | // due to Writer::AddFontItems_ |
65 | | // EE_CHAR_FONTINFO_CJK ok |
66 | | // due to ImpEditEngine::WriteRTF |
67 | | // due to ScXMLFontAutoStylePool_Impl |
68 | | // due to SdXImpressDocument::getPropertyValue |
69 | | // due to Writer::AddFontItems_ |
70 | | // EE_CHAR_FONTINFO_CTL ok |
71 | | // due to ImpEditEngine::WriteRTF |
72 | | // EE_CHAR_COLOR ok |
73 | | // due to ScDocumentPool::StyleDeleted |
74 | | // due to ScDocument::UpdateFontCharSet() |
75 | | // due to ScXMLFontAutoStylePool_Impl |
76 | | // ATTR_FONT ok |
77 | | // due to OptimizeHasAttrib |
78 | | // ATTR_ROTATE_VALUE ok |
79 | | // due to ScDocument::GetDocColors() |
80 | | // ATTR_BACKGROUND ok |
81 | | // ATTR_FONT_COLOR ok |
82 | | // due to ScXMLExport::CollectUserDefinedNamespaces |
83 | | // ATTR_USERDEF ok |
84 | | // due to ScXMLExport::CollectUserDefinedNamespaces |
85 | | // due to SwXMLExport::exportDoc |
86 | | // EE_PARA_XMLATTRIBS ok |
87 | | // due to ScXMLExport::CollectUserDefinedNamespaces |
88 | | // due to SwXMLExport::exportDoc |
89 | | // EE_CHAR_XMLATTRIBS ok |
90 | | // due to ScXMLExport::CollectUserDefinedNamespaces |
91 | | // due to SwXMLExport::exportDoc |
92 | | // SDRATTR_XMLATTRIBUTES ok |
93 | | // due to ScXMLFontAutoStylePool_Impl |
94 | | // ATTR_CJK_FONT ok |
95 | | // ATTR_CTL_FONT ok |
96 | | // ATTR_PAGE_HEADERLEFT ok |
97 | | // ATTR_PAGE_FOOTERLEFT ok |
98 | | // ATTR_PAGE_HEADERRIGHT ok |
99 | | // ATTR_PAGE_FOOTERRIGHT ok |
100 | | // ATTR_PAGE_HEADERFIRST ok |
101 | | // ATTR_PAGE_FOOTERFIRST ok |
102 | | // due to ScCellShell::ExecuteEdit |
103 | | // due to ScTabViewShell::CreateRefDialogController |
104 | | // SCITEM_CONDFORMATDLGDATA ok |
105 | | // due to SdDrawDocument::UpdatePageRelativeURLs |
106 | | // EE_FEATURE_FIELD ok |
107 | | // due to SvxUnoMarkerTable::replaceByName |
108 | | // due to SvxShape::setPropertyValueImpl/SvxShape::SetFillAttribute |
109 | | // due to XLineStartItem::checkForUniqueItem |
110 | | // XATTR_LINESTART ok |
111 | | // due to SvxUnoMarkerTable::replaceByName |
112 | | // due to SvxShape::setPropertyValueImpl/SvxShape::SetFillAttribute |
113 | | // due to XLineStartItem::checkForUniqueItem |
114 | | // XATTR_LINEEND ok |
115 | | // due to SvxUnoNameItemTable |
116 | | // due to SvxShape::setPropertyValueImpl/SvxShape::SetFillAttribute |
117 | | // due to NameOrIndex::CheckNamedItem all derived from NameOrIndex |
118 | | // XATTR_FILLBITMAP ok |
119 | | // due to SvxUnoNameItemTable |
120 | | // due to SvxShape::setPropertyValueImpl/SvxShape::SetFillAttribute |
121 | | // XATTR_LINEDASH ok |
122 | | // due to SvxUnoNameItemTable |
123 | | // due to SvxShape::setPropertyValueImpl/SvxShape::SetFillAttribute |
124 | | // due to NameOrIndex::CheckNamedItem all derived from NameOrIndex |
125 | | // XATTR_FILLGRADIENT ok |
126 | | // due to SvxUnoNameItemTable |
127 | | // due to SvxShape::setPropertyValueImpl/SvxShape::SetFillAttribute |
128 | | // XATTR_FILLHATCH ok |
129 | | // due to SvxUnoNameItemTable |
130 | | // due to SvxShape::setPropertyValueImpl/SvxShape::SetFillAttribute |
131 | | // XATTR_FILLFLOATTRANSPARENCE ok |
132 | | // due to NamespaceIteratorImpl |
133 | | // -> needs to be evaluated |
134 | | // due to SwCursorShell::GotoNxtPrvTOXMark |
135 | | // due to SwDoc::GetTOIKeys |
136 | | // RES_TXTATR_TOXMARK ok |
137 | | // due to SwDoc::GetRefMark |
138 | | // due to SwDoc::CallEvent |
139 | | // due to SwURLStateChanged::Notify |
140 | | // due to SwHTMLWriter::CollectLinkTargets |
141 | | // due to MSWordExportBase::CollectOutlineBookmarks |
142 | | // RES_TXTATR_INETFMT ok |
143 | | // due to SwDoc::GetAllUsedDB |
144 | | // due to lcl_FindInputField |
145 | | // due to SwViewShell::IsAnyFieldInDoc |
146 | | // RES_TXTATR_FIELD ok |
147 | | // due to SwDoc::GetAllUsedDB |
148 | | // due to lcl_FindInputField |
149 | | // due to SwViewShell::IsAnyFieldInDoc |
150 | | // RES_TXTATR_INPUTFIELD ok |
151 | | // due to SwDoc::SetDefault |
152 | | // RES_PARATR_TABSTOP ok |
153 | | // due to SwDoc::GetDocColors() |
154 | | // due to RtfExport::OutColorTable |
155 | | // RES_CHRATR_COLOR ok |
156 | | // due to SwDoc::GetDocColors() |
157 | | // RES_CHRATR_HIGHLIGHT ok |
158 | | // due to SwDoc::GetDocColors() |
159 | | // RES_BACKGROUND ok |
160 | | // due to SwNode::FindPageDesc |
161 | | // due to SwPageNumberFieldType::ChangeExpansion |
162 | | // due to SwFrame::GetVirtPageNum |
163 | | // RES_PAGEDESC ok |
164 | | // due to SwAutoStylesEnumImpl:: |
165 | | // RES_TXTATR_CJK_RUBY ok |
166 | | // due to SwHTMLWriter::CollectLinkTargets |
167 | | // due to MSWordExportBase::CollectOutlineBookmarks |
168 | | // RES_URL |
169 | | // due to RtfExport::OutColorTable |
170 | | // RES_CHRATR_UNDERLINE ok |
171 | | // RES_CHRATR_OVERLINE ok |
172 | | // RES_CHRATR_BACKGROUND ok |
173 | | // RES_SHADOW ok |
174 | | // RES_BOX ok |
175 | | // RES_CHRATR_BOX ok |
176 | | // XATTR_FILLCOLOR ok |
177 | | // due to wwFontHelper::InitFontTable |
178 | | // due to SwXMLFontAutoStylePool_Impl::SwXMLFontAutoStylePool_Impl |
179 | | // RES_CHRATR_FONT ok |
180 | | // due to wwFontHelper::InitFontTable |
181 | | // due to SwXMLFontAutoStylePool_Impl::SwXMLFontAutoStylePool_Impl |
182 | | // RES_CHRATR_CJK_FONT ok |
183 | | // due to wwFontHelper::InitFontTable |
184 | | // due to SwXMLFontAutoStylePool_Impl::SwXMLFontAutoStylePool_Impl |
185 | | // RES_CHRATR_CTL_FONT |
186 | | // due to SwXMLExport::exportDoc |
187 | | // RES_UNKNOWNATR_CONTAINER ok |
188 | | // RES_TXTATR_UNKNOWN_CONTAINER ok |
189 | | |
190 | | ItemInfoUser::ItemInfoUser(const ItemInfo& rItemInfo, const SfxItemPool& rItemPool, const SfxPoolItem& rItem, bool bPassingOwnership) |
191 | 4.94M | : ItemInfo(rItemInfo) |
192 | 4.94M | , m_pItem(implCreateItemEntry(rItemPool, &rItem, bPassingOwnership)) |
193 | 4.94M | { |
194 | 4.94M | } |
195 | | |
196 | | ItemInfoUser::~ItemInfoUser() |
197 | 4.94M | { |
198 | 4.94M | implCleanupItemEntry(m_pItem); |
199 | 4.94M | } |
200 | | |
201 | | const SlotIDToWhichIDMap& ItemInfoPackage::getSlotIDToWhichIDMap() const |
202 | 982k | { |
203 | 982k | if (maSlotIDToWhichIDMap.empty()) |
204 | 102 | { |
205 | | // will be filled only once per office runtime |
206 | 9.01k | for (size_t a(0); a < size(); a++) |
207 | 8.91k | { |
208 | 8.91k | const ItemInfoStatic& rCandidate(getItemInfoStatic(a)); |
209 | 8.91k | if (0 != rCandidate.getSlotID()) |
210 | 3.80k | { |
211 | | #ifdef DBG_UTIL |
212 | | if (maSlotIDToWhichIDMap.contains(rCandidate.getSlotID())) |
213 | | assert(false && "ITEM: SlotID used double in ItemInfoPackage (!)"); |
214 | | #endif |
215 | 3.80k | maSlotIDToWhichIDMap[rCandidate.getSlotID()] = rCandidate.getWhich(); |
216 | 3.80k | } |
217 | 8.91k | } |
218 | 102 | } |
219 | | |
220 | 982k | return maSlotIDToWhichIDMap; |
221 | 982k | } |
222 | | |
223 | | const ItemInfo& ItemInfoPackage::getExistingItemInfo(size_t /*nIndex*/) |
224 | 0 | { |
225 | 0 | static ItemInfoStatic EMPTY(0, nullptr, 0, 0); |
226 | 0 | return EMPTY; |
227 | 0 | } |
228 | | |
229 | | void SfxItemPool::registerItemInfoPackage( |
230 | | ItemInfoPackage& rPackage, |
231 | | const std::function<SfxPoolItem*(sal_uInt16)>& rCallback) |
232 | 982k | { |
233 | 982k | assert(maItemInfos.empty() && "ITEM: registering more than one ItemInfoPackage per Pool is not allowed (!)"); |
234 | | |
235 | | // we know the size :-) |
236 | 982k | maItemInfos.reserve(rPackage.size()); |
237 | | |
238 | | // loop over ItemInfoPackage and add ptrs to provided ItemInfos |
239 | 100M | for(size_t a(0); a < rPackage.size(); a++) |
240 | 99.6M | { |
241 | | // get ItemInfo entry, maybe StaticDefault or DynamicDefault |
242 | 99.6M | const ItemInfo& rItemInfo(rPackage.getItemInfo(a, *this)); |
243 | | |
244 | 99.6M | if (nullptr != rItemInfo.getItem()) |
245 | 99.6M | { |
246 | | // if it has an item, use it, done |
247 | 99.6M | maItemInfos.push_back(&rItemInfo); |
248 | 99.6M | continue; |
249 | 99.6M | } |
250 | | |
251 | | // if not, use the callback to create a DynamicDefault. This |
252 | | // *has* to be supported then by the caller |
253 | 0 | SfxPoolItem* pDynamicItem(rCallback(rItemInfo.getWhich())); |
254 | 0 | assert(nullptr != pDynamicItem); |
255 | 0 | maItemInfos.push_back(new ItemInfoDynamic(rItemInfo, pDynamicItem)); |
256 | 0 | } |
257 | | |
258 | | // use infos to fill local variables |
259 | 982k | mnStart = maItemInfos.front()->getWhich(); |
260 | 982k | mnEnd = maItemInfos.back()->getWhich(); |
261 | | |
262 | | // set mapper for fast SlotIDToWhichID conversion |
263 | 982k | mpSlotIDToWhichIDMap = &rPackage.getSlotIDToWhichIDMap(); |
264 | | |
265 | | #ifdef DBG_UTIL |
266 | | for (size_t a(1); a < maItemInfos.size(); a++) |
267 | | if (maItemInfos[a-1]->getWhich() + 1 != maItemInfos[a]->getWhich()) |
268 | | assert(false && "ITEM: Order is wrong (!)"); |
269 | | #endif |
270 | 982k | } |
271 | | |
272 | | const ItemInfo* SfxItemPool::impCheckItemInfoForClone(const ItemInfo* pInfo) |
273 | 0 | { |
274 | 0 | const SfxPoolItem* pItem(pInfo->getItem()); |
275 | 0 | assert(nullptr != pItem && "ITEM: Missing Item in ItemInfo (!)"); |
276 | |
|
277 | 0 | if (pItem->isStaticDefault()) |
278 | | // noting to do, not ref-counted |
279 | 0 | return pInfo; |
280 | | |
281 | 0 | if (pItem->isDynamicDefault()) |
282 | 0 | { |
283 | | // need to clone to new Pool as DynamicDefault, owned by the Pool |
284 | | // and not shared. Mainly SfxSetItems. Not RefCounted |
285 | 0 | return new ItemInfoDynamic(*pInfo, pItem->Clone(this)); |
286 | 0 | } |
287 | | |
288 | | // all Items else that can be in the Pool are UserDefaults. These |
289 | | // are RefCounted, so use implCreateItemEntry to increase reference |
290 | 0 | return new ItemInfoUser(*pInfo, *this, *pItem); |
291 | 0 | } |
292 | | |
293 | | void SfxItemPool::impClearUserDefault(const userItemInfos::iterator& rHit) |
294 | 4.49M | { |
295 | 4.49M | if (rHit == maUserItemInfos.end()) |
296 | | // does not exist |
297 | 0 | return; |
298 | | |
299 | | // get ItemInfo and Item, HAS to be a UserDefault |
300 | 4.49M | const sal_uInt16 nIndex(GetIndex_Impl(rHit->first)); |
301 | 4.49M | const ItemInfo* pInfo(maItemInfos[nIndex]); |
302 | 4.49M | assert(nullptr != pInfo && "ITEM: access error to Defaults in Pool (!)"); |
303 | | |
304 | | // restore original entry using the remembered one |
305 | 4.49M | maItemInfos[nIndex] = rHit->second; |
306 | | |
307 | | // free Item, delete ItemInfo |
308 | 4.49M | delete pInfo; |
309 | 4.49M | } |
310 | | |
311 | | void SfxItemPool::impCreateUserDefault(const SfxPoolItem& rItem) |
312 | 4.49M | { |
313 | 4.49M | const sal_uInt16 nWhich(rItem.Which()); |
314 | | |
315 | | // make sure by an assert check that none exists |
316 | 4.49M | assert(maUserItemInfos.end() == maUserItemInfos.find(nWhich)); |
317 | | |
318 | 4.49M | const sal_uInt16 nIndex(GetIndex_Impl(nWhich)); |
319 | 4.49M | const ItemInfo* pInfo(maItemInfos[nIndex]); |
320 | 4.49M | assert(nullptr != pInfo && "ITEM: access error to Defaults in Pool (!)"); |
321 | | |
322 | | // safe original ItemInfo in UserItemInfos |
323 | 4.49M | maUserItemInfos.insert({nWhich, pInfo}); |
324 | | |
325 | | // create new Item by using implCreateItemEntry and new ItemInfo |
326 | 4.49M | maItemInfos[nIndex] = new ItemInfoUser(*pInfo, *this, rItem); |
327 | 4.49M | } |
328 | | |
329 | | void SfxItemPool::cleanupItemInfos() |
330 | 981k | { |
331 | | // reset all UserDefaultItems & restore original maItemInfos |
332 | 5.47M | while (!maUserItemInfos.empty()) |
333 | 4.49M | { |
334 | | // get next candidate, cleanup UseDefault and remove data |
335 | 4.49M | userItemInfos::iterator aHit(maUserItemInfos.begin()); |
336 | 4.49M | impClearUserDefault(aHit); |
337 | 4.49M | maUserItemInfos.erase(aHit); |
338 | 4.49M | } |
339 | | |
340 | | // delete DynamicDefaults in maItemInfos, these only exist |
341 | | // for Pool lifetime since they are Pool-dependent. There should |
342 | | // be NO MORE UserDefaults after cleanup above |
343 | 981k | for (auto& rInfo : maItemInfos) |
344 | 99.6M | { |
345 | 99.6M | if (rInfo->getItem()->isDynamicDefault()) |
346 | 1.37M | { |
347 | | // the whole ItemInfo is owned by the pool, so |
348 | | // delete the Item and the ItemInfo (in that order :-) |
349 | 1.37M | delete rInfo; |
350 | 1.37M | } |
351 | | #ifdef DBG_UTIL |
352 | | // since there should be NO MORE UserDefaults the item |
353 | | // then *has* to be StaticDefault - check that |
354 | | else if (!rInfo->getItem()->isStaticDefault()) |
355 | | assert(false && "ITEM: Error in UserDefault handling (!)"); |
356 | | #endif |
357 | 99.6M | } |
358 | 981k | } |
359 | | |
360 | | void SfxItemPool::registerItemSet(SfxItemSet& rSet) |
361 | 17.9M | { |
362 | 17.9M | registeredSfxItemSets& rTarget(GetMasterPool()->maRegisteredSfxItemSets); |
363 | | #ifdef DBG_UTIL |
364 | | const size_t nBefore(rTarget.size()); |
365 | | #endif |
366 | 17.9M | rTarget.insert(&rSet); |
367 | | #ifdef DBG_UTIL |
368 | | const size_t nAfter(rTarget.size()); |
369 | | if (nBefore + 1 != nAfter) |
370 | | { |
371 | | SAL_WARN("svl.items", "SfxItemPool::registerItemSet: ItemSet was already registered (!)"); |
372 | | } |
373 | | #endif |
374 | 17.9M | } |
375 | | |
376 | | void SfxItemPool::unregisterItemSet(SfxItemSet& rSet) |
377 | 17.9M | { |
378 | 17.9M | registeredSfxItemSets& rTarget(GetMasterPool()->maRegisteredSfxItemSets); |
379 | | #ifdef DBG_UTIL |
380 | | const size_t nBefore(rTarget.size()); |
381 | | #endif |
382 | 17.9M | rTarget.erase(&rSet); |
383 | | #ifdef DBG_UTIL |
384 | | const size_t nAfter(rTarget.size()); |
385 | | if (nBefore != nAfter + 1) |
386 | | { |
387 | | SAL_WARN("svl.items", "SfxItemPool::unregisterItemSet: ItemSet was not registered (!)"); |
388 | | } |
389 | | #endif |
390 | 17.9M | } |
391 | | |
392 | | void SfxItemPool::registerPoolItemHolder(SfxPoolItemHolder& rHolder) |
393 | 7.09M | { |
394 | 7.09M | registeredSfxPoolItemHolders& rTarget(GetMasterPool()->maRegisteredSfxPoolItemHolders); |
395 | | #ifdef DBG_UTIL |
396 | | const size_t nBefore(rTarget.size()); |
397 | | #endif |
398 | 7.09M | rTarget.insert(&rHolder); |
399 | | #ifdef DBG_UTIL |
400 | | const size_t nAfter(rTarget.size()); |
401 | | if (nBefore + 1 != nAfter) |
402 | | { |
403 | | SAL_WARN("svl.items", "SfxItemPool::registerPoolItemHolder: SfxPoolItemHolder was already registered (!)"); |
404 | | } |
405 | | #endif |
406 | 7.09M | if (rHolder.is() && rHolder.getItem()->isNameOrIndex()) |
407 | 0 | registerNameOrIndex(*rHolder.getItem()); |
408 | 7.09M | } |
409 | | |
410 | | void SfxItemPool::unregisterPoolItemHolder(SfxPoolItemHolder& rHolder) |
411 | 7.09M | { |
412 | 7.09M | registeredSfxPoolItemHolders& rTarget(GetMasterPool()->maRegisteredSfxPoolItemHolders); |
413 | | #ifdef DBG_UTIL |
414 | | const size_t nBefore(rTarget.size()); |
415 | | #endif |
416 | 7.09M | rTarget.erase(&rHolder); |
417 | | #ifdef DBG_UTIL |
418 | | const size_t nAfter(rTarget.size()); |
419 | | if (nBefore != nAfter + 1) |
420 | | { |
421 | | SAL_WARN("svl.items", "SfxItemPool::unregisterPoolItemHolder: SfxPoolItemHolder was not registered (!)"); |
422 | | } |
423 | | #endif |
424 | 7.09M | if (rHolder.is() && rHolder.getItem()->isNameOrIndex()) |
425 | 0 | unregisterNameOrIndex(*rHolder.getItem()); |
426 | 7.09M | } |
427 | | |
428 | | void SfxItemPool::registerNameOrIndex(const SfxPoolItem& rItem) |
429 | 4.02M | { |
430 | 4.02M | assert(rItem.isNameOrIndex() && "ITEM: only Items derived from NameOrIndex supported for this mechanism (!)"); |
431 | 4.02M | NameOrIndexContent& rTarget(GetMasterPool()->maRegisteredNameOrIndex[rItem.ItemType()]); |
432 | 4.02M | NameOrIndexContent::iterator aHit(rTarget.find(&rItem)); |
433 | 4.02M | if (aHit == rTarget.end()) |
434 | 989k | rTarget.insert(std::pair<const SfxPoolItem*, sal_uInt32>(&rItem, 0)); |
435 | 3.03M | else |
436 | 3.03M | aHit->second++; |
437 | 4.02M | } |
438 | | |
439 | | void SfxItemPool::unregisterNameOrIndex(const SfxPoolItem& rItem) |
440 | 4.02M | { |
441 | 4.02M | assert(rItem.isNameOrIndex() && "ITEM: only Items derived from NameOrIndex supported for this mechanism (!)"); |
442 | 4.02M | NameOrIndexContent& rTarget(GetMasterPool()->maRegisteredNameOrIndex[rItem.ItemType()]); |
443 | 4.02M | NameOrIndexContent::iterator aHit(rTarget.find(&rItem)); |
444 | 4.02M | assert(aHit != rTarget.end() && "ITEM: malformed order of buffered NameOrIndex Items, entry *expected* (!)"); |
445 | 4.02M | if (0 == aHit->second) |
446 | 989k | rTarget.erase(aHit); |
447 | 3.03M | else |
448 | 3.03M | aHit->second--; |
449 | 4.02M | } |
450 | | |
451 | | SfxItemPool* SfxItemPool::getTargetPool(sal_uInt16 nWhich) const |
452 | 3.43G | { |
453 | 3.43G | if (IsInRange(nWhich)) |
454 | 2.56G | return const_cast<SfxItemPool*>(this); |
455 | 867M | if (mpSecondary) |
456 | 867M | return mpSecondary->getTargetPool(nWhich); |
457 | 15.7k | return nullptr; |
458 | 867M | } |
459 | | |
460 | | bool SfxItemPool::CheckItemInfoFlag(sal_uInt16 nWhich, sal_uInt16 nMask) const |
461 | 1.63G | { |
462 | 1.63G | SfxItemPool* pTarget(getTargetPool(nWhich)); |
463 | 1.63G | if (nullptr == pTarget) |
464 | 15.7k | return false; |
465 | | |
466 | 1.63G | if (!pTarget->maItemInfos.empty()) |
467 | 1.63G | { |
468 | 1.63G | const sal_uInt16 nIndex(pTarget->GetIndex_Impl(nWhich)); |
469 | 1.63G | const ItemInfo* pInfo(pTarget->maItemInfos[nIndex]); |
470 | 1.63G | assert(nullptr != pInfo); |
471 | 1.63G | return pInfo->getItemInfoFlags() & nMask; |
472 | 1.63G | } |
473 | | |
474 | 0 | return pTarget->CheckItemInfoFlag_Impl(pTarget->GetIndex_Impl(nWhich), nMask); |
475 | 1.63G | } |
476 | | |
477 | | SfxBroadcaster& SfxItemPool::BC() |
478 | 0 | { |
479 | 0 | return aBC; |
480 | 0 | } |
481 | | |
482 | | /** |
483 | | * This is the regular ctor to be used for this class. |
484 | | * An SfxItemPool instance is initialized, which can manage Items in the |
485 | | * range from 'nStartWhich' to 'nEndWhich'. |
486 | | * |
487 | | * For every one of these WhichIds a static Default must be present in the |
488 | | * 'pDefaults' array. They start with an SfxPoolItem (with the WhichId |
489 | | * 'nStartWhich'), are sorted by WhichId and consecutively stored. |
490 | | * |
491 | | * 'pItemInfos' is a USHORT array arranged in the same way, which holds |
492 | | * SlotIds and Flags. These SlotIds can be 0, if the affected Items are |
493 | | * exclusively used in the Core. |
494 | | * The flags allow for e.g. enabling value sharing (poolable). |
495 | | * |
496 | | * If the Pool is supposed to hold SfxSetItems, the ctor cannot yet contain |
497 | | * static Defaults. This needs to be done afterwards, using |
498 | | * @see SfxItemPool::SetPoolDefaults(std::vector<SfxPoolItem*>*). |
499 | | * |
500 | | * @see SfxItemPool::SetPoolDefaults(std::vector<SfxPoolItem*>*) |
501 | | * @see SfxItemPool::ReleasePoolDefaults(std::vector<SfxPoolItem*>*,bool) |
502 | | * @see SfxItemPool::ReleasePoolDefaults(bool) |
503 | | */ |
504 | | SfxItemPool::SfxItemPool(const OUString& rName) /* Pool name to identify in the file format */ |
505 | 982k | : salhelper::SimpleReferenceObject() |
506 | 982k | , aBC() |
507 | 982k | , aName(rName) |
508 | 982k | , mpMaster(this) |
509 | 982k | , mpSecondary() |
510 | 982k | , mnStart(0) |
511 | 982k | , mnEnd(0) |
512 | 982k | , eDefMetric(MapUnit::MapCM) |
513 | 982k | , maRegisteredSfxItemSets() |
514 | 982k | , maRegisteredSfxPoolItemHolders() |
515 | 982k | , maRegisteredNameOrIndex() |
516 | 982k | , mbShutdownHintSent(false) |
517 | 982k | , maItemInfos() |
518 | 982k | , maUserItemInfos() |
519 | 982k | , mpSlotIDToWhichIDMap(nullptr) |
520 | 982k | { |
521 | 982k | eDefMetric = MapUnit::MapTwip; |
522 | 982k | } |
523 | | |
524 | | /** |
525 | | * Copy ctor |
526 | | * |
527 | | * @see SfxItemPool::Clone() const |
528 | | */ |
529 | | SfxItemPool::SfxItemPool(const SfxItemPool& rPool) // Copy from this instance |
530 | 0 | : salhelper::SimpleReferenceObject() |
531 | 0 | , aBC() |
532 | 0 | , aName(rPool.aName) |
533 | 0 | , mpMaster(this) |
534 | 0 | , mpSecondary() |
535 | 0 | , maPoolRanges() |
536 | 0 | , mnStart(rPool.mnStart) |
537 | 0 | , mnEnd(rPool.mnEnd) |
538 | 0 | , eDefMetric(MapUnit::MapCM) |
539 | 0 | , maRegisteredSfxItemSets() |
540 | 0 | , maRegisteredSfxPoolItemHolders() |
541 | 0 | , maRegisteredNameOrIndex() |
542 | 0 | , mbShutdownHintSent(false) |
543 | 0 | , maItemInfos(rPool.maItemInfos) |
544 | 0 | , maUserItemInfos(rPool.maUserItemInfos) |
545 | 0 | , mpSlotIDToWhichIDMap(rPool.mpSlotIDToWhichIDMap) |
546 | 0 | { |
547 | | // DynamicDefaults and UserDefaults need to be cloned for the new Pool |
548 | 0 | for (itemInfoVector::iterator aInfo(maItemInfos.begin()); aInfo != maItemInfos.end(); aInfo++) |
549 | 0 | *aInfo = impCheckItemInfoForClone(*aInfo); |
550 | | |
551 | | // DynamicDefaults need to be cloned for the new Pool (no UserDefaults in UserItemInfos) |
552 | 0 | for (auto& rUserItem : maUserItemInfos) |
553 | 0 | rUserItem.second = impCheckItemInfoForClone(rUserItem.second); |
554 | |
|
555 | 0 | eDefMetric = rPool.eDefMetric; |
556 | | |
557 | | // Repair linkage |
558 | 0 | if ( rPool.mpSecondary ) |
559 | 0 | SetSecondaryPool( rPool.mpSecondary->Clone().get() ); |
560 | 0 | } |
561 | | |
562 | | SfxItemPool::~SfxItemPool() |
563 | 981k | { |
564 | | // cleanup UserDefaults & delete owned DynamicDefaults |
565 | 981k | cleanupItemInfos(); |
566 | | |
567 | | // Need to send ShutdownHint? |
568 | 981k | sendShutdownHint(); |
569 | | |
570 | 981k | if (mpMaster != nullptr && mpMaster != this) |
571 | 0 | { |
572 | | // This condition indicates an error. |
573 | | // A mpMaster->SetSecondaryPool(...) call should have been made |
574 | | // earlier to prevent this. At this point we can only try to |
575 | | // prevent a crash later on. |
576 | 0 | DBG_ASSERT( mpMaster == this, "destroying active Secondary-Pool" ); |
577 | 0 | if (mpMaster->mpSecondary == this) |
578 | 0 | mpMaster->mpSecondary = nullptr; |
579 | 0 | } |
580 | 981k | } |
581 | | |
582 | | void SfxItemPool::SetSecondaryPool( SfxItemPool *pPool ) |
583 | 1.28M | { |
584 | | // Reset Master in attached Pools |
585 | 1.28M | if ( mpSecondary ) |
586 | 268k | { |
587 | 268k | mpSecondary->mpMaster = mpSecondary.get(); |
588 | 365k | for ( SfxItemPool *p = mpSecondary->mpSecondary.get(); p; p = p->mpSecondary.get() ) |
589 | 96.6k | p->mpMaster = mpSecondary.get(); |
590 | 268k | } |
591 | | |
592 | | // Set Master of new Secondary Pools |
593 | 1.28M | DBG_ASSERT( !pPool || pPool->mpMaster == pPool, "Secondary is present in two Pools" ); |
594 | 1.28M | SfxItemPool *pNewMaster = GetMasterPool() ? mpMaster : this; |
595 | 1.57M | for ( SfxItemPool *p = pPool; p; p = p->mpSecondary.get() ) |
596 | 288k | p->mpMaster = pNewMaster; |
597 | | |
598 | | // Remember new Secondary Pool |
599 | 1.28M | mpSecondary = pPool; |
600 | 1.28M | } |
601 | | |
602 | | MapUnit SfxItemPool::GetMetric( sal_uInt16 ) const |
603 | 26.8M | { |
604 | 26.8M | return eDefMetric; |
605 | 26.8M | } |
606 | | |
607 | | void SfxItemPool::SetDefaultMetric( MapUnit eNewMetric ) |
608 | 383k | { |
609 | | // assert((pImpl->eDefMetric == eNewMetric || !pImpl->maPoolRanges) && "pool already frozen, cannot change metric"); |
610 | 383k | eDefMetric = eNewMetric; |
611 | 383k | } |
612 | | |
613 | | bool SfxItemPool::GetPresentation |
614 | | ( |
615 | | const SfxPoolItem& rItem, |
616 | | MapUnit eMetric, |
617 | | OUString& rText, |
618 | | const IntlWrapper& rIntlWrapper |
619 | | ) const |
620 | 0 | { |
621 | 0 | return rItem.GetPresentation( |
622 | 0 | SfxItemPresentation::Complete, GetMetric(rItem.Which()), eMetric, rText, rIntlWrapper ); |
623 | 0 | } |
624 | | |
625 | | rtl::Reference<SfxItemPool> SfxItemPool::Clone() const |
626 | 0 | { |
627 | 0 | return new SfxItemPool( *this ); |
628 | 0 | } |
629 | | |
630 | | void SfxItemPool::sendShutdownHint() |
631 | 1.39M | { |
632 | | // Already sent? |
633 | 1.39M | if (mbShutdownHintSent) |
634 | 415k | return; |
635 | | |
636 | 981k | mbShutdownHintSent = true; |
637 | | |
638 | | // Inform e.g. running Requests |
639 | 981k | aBC.Broadcast( SfxHint( SfxHintId::Dying ) ); |
640 | 981k | maPoolRanges.reset(); |
641 | 981k | } |
642 | | |
643 | | void SfxItemPool::SetUserDefaultItem(const SfxPoolItem& rItem) |
644 | 6.45M | { |
645 | 6.45M | SfxItemPool* pTarget(getTargetPool(rItem.Which())); |
646 | 6.45M | if (nullptr == pTarget) |
647 | 6.45M | assert(false && "unknown WhichId - cannot set pool default"); |
648 | | |
649 | 6.45M | const sal_uInt16 nWhich(rItem.Which()); |
650 | 6.45M | userItemInfos::iterator aHit(pTarget->maUserItemInfos.find(nWhich)); |
651 | | |
652 | 6.45M | if (aHit == pTarget->maUserItemInfos.end()) |
653 | 4.49M | { |
654 | | // UserDefault does not exist, create needed entries to safe |
655 | | // original ItemInfo in UserItemInfos and set new, owned |
656 | | // ItemInfo containing an owned clone of the Item in ItemInfos |
657 | 4.49M | pTarget->impCreateUserDefault(rItem); |
658 | 4.49M | return; |
659 | 4.49M | } |
660 | | |
661 | | // UserDefault does exist, check and evtl. replace |
662 | 1.95M | const sal_uInt16 nIndex(pTarget->GetIndex_Impl(nWhich)); |
663 | 1.95M | const ItemInfo* pInfo(pTarget->maItemInfos[nIndex]); |
664 | 1.95M | assert(nullptr != pInfo && "ITEM: access error to Defaults in Pool (!)"); |
665 | 1.95M | const SfxPoolItem* pItem(pInfo->getItem()); |
666 | 1.95M | assert(nullptr != pItem && "ITEM: access error to Defaults in Pool (!)"); |
667 | | |
668 | | // nothing to do if equal, so check |
669 | 1.95M | if (SfxPoolItem::areSame(pItem, &rItem)) |
670 | 1.50M | return; |
671 | | |
672 | | // need to exchange existing instance and free current one |
673 | 447k | pTarget->maItemInfos[nIndex] = new ItemInfoUser(*pInfo, *pTarget, rItem); |
674 | 447k | delete pInfo; |
675 | 447k | } |
676 | | |
677 | | const SfxPoolItem* SfxItemPool::GetUserDefaultItem( sal_uInt16 nWhich ) const |
678 | 5.50M | { |
679 | 5.50M | SfxItemPool* pTarget(getTargetPool(nWhich)); |
680 | 5.50M | if (nullptr == pTarget) |
681 | 0 | { |
682 | 0 | assert(false && "unknown WhichId - cannot get pool default"); |
683 | 0 | return nullptr; |
684 | 0 | } |
685 | | |
686 | 5.50M | userItemInfos::iterator aHit(pTarget->maUserItemInfos.find(nWhich)); |
687 | | |
688 | 5.50M | if (aHit == pTarget->maUserItemInfos.end()) |
689 | | // no default item |
690 | 5.34M | return nullptr; |
691 | | |
692 | 166k | const sal_uInt16 nIndex(pTarget->GetIndex_Impl(nWhich)); |
693 | 166k | const ItemInfo* pInfo(pTarget->maItemInfos[nIndex]); |
694 | 166k | assert(nullptr != pInfo && "ITEM: access error to Defaults in Pool (!)"); |
695 | 166k | const SfxPoolItem* pItem(pInfo->getItem()); |
696 | 166k | assert(nullptr != pItem && "ITEM: access error to Defaults in Pool (!)"); |
697 | 166k | return pItem; |
698 | 5.50M | } |
699 | | |
700 | | /** |
701 | | * Resets the default of the given WhichId back to the static Default. |
702 | | * If a pool default exists, it is removed. |
703 | | */ |
704 | | void SfxItemPool::ResetUserDefaultItem( sal_uInt16 nWhich ) |
705 | 0 | { |
706 | 0 | SfxItemPool* pTarget(getTargetPool(nWhich)); |
707 | 0 | if (nullptr == pTarget) |
708 | 0 | assert(false && "unknown WhichId - cannot reset pool default"); |
709 | |
|
710 | 0 | userItemInfos::iterator aHit(pTarget->maUserItemInfos.find(nWhich)); |
711 | |
|
712 | 0 | if (aHit != pTarget->maUserItemInfos.end()) |
713 | 0 | { |
714 | | // clear entry, cleanup, restore previous data |
715 | 0 | pTarget->impClearUserDefault(aHit); |
716 | | |
717 | | // remove remembered data |
718 | 0 | pTarget->maUserItemInfos.erase(aHit); |
719 | 0 | } |
720 | 0 | } |
721 | | |
722 | | const SfxPoolItem& SfxItemPool::GetUserOrPoolDefaultItem( sal_uInt16 nWhich ) const |
723 | 917M | { |
724 | 917M | SfxItemPool* pTarget(getTargetPool(nWhich)); |
725 | 917M | if (nullptr == pTarget) |
726 | 917M | assert(!"unknown which - don't ask me for defaults"); |
727 | | |
728 | 917M | const sal_uInt16 nIndex(pTarget->GetIndex_Impl(nWhich)); |
729 | 917M | const ItemInfo* pInfo(pTarget->maItemInfos[nIndex]); |
730 | 917M | assert(nullptr != pInfo && "ITEM: access error to Defaults in Pool (!)"); |
731 | 917M | const SfxPoolItem* pItem(pInfo->getItem()); |
732 | 917M | assert(nullptr != pItem && "ITEM: access error to Defaults in Pool (!)"); |
733 | 917M | return *pItem; |
734 | 917M | } |
735 | | |
736 | | /* get the last pool by following the GetSecondaryPool chain */ |
737 | | SfxItemPool* SfxItemPool::GetLastPoolInChain() |
738 | 77.0k | { |
739 | 77.0k | SfxItemPool* pLast(this); |
740 | | |
741 | 77.0k | while(pLast->GetSecondaryPool()) |
742 | 0 | pLast = pLast->GetSecondaryPool(); |
743 | | |
744 | 77.0k | return pLast; |
745 | 77.0k | } |
746 | | |
747 | | const WhichRangesContainer& SfxItemPool::GetMergedIdRanges() const |
748 | 3.73M | { |
749 | 3.73M | if (maPoolRanges.empty()) |
750 | 169k | { |
751 | | // Merge all ranges, keeping them sorted |
752 | 585k | for (const SfxItemPool* pPool = this; pPool; pPool = pPool->mpSecondary.get()) |
753 | 415k | maPoolRanges = maPoolRanges.MergeRange(pPool->mnStart, pPool->mnEnd); |
754 | 169k | } |
755 | | |
756 | 3.73M | return maPoolRanges; |
757 | 3.73M | } |
758 | | |
759 | | const SfxPoolItem* SfxItemPool::GetPoolDefaultItem(sal_uInt16 nWhich) const |
760 | 4.11M | { |
761 | 4.11M | SfxItemPool* pTarget(getTargetPool(nWhich)); |
762 | 4.11M | if (nullptr == pTarget) |
763 | 4.11M | assert(false && "unknown WhichId - cannot resolve surrogate"); |
764 | | |
765 | 4.11M | const sal_uInt16 nIndex(pTarget->GetIndex_Impl(nWhich)); |
766 | 4.11M | userItemInfos::iterator aHit(pTarget->maUserItemInfos.find(nWhich)); |
767 | | |
768 | 4.11M | if (aHit != pTarget->maUserItemInfos.end()) |
769 | 0 | { |
770 | | // If it is a UserDefault Item, check saved ItemInfo and use |
771 | | // Item from there |
772 | 0 | assert(aHit != pTarget->maUserItemInfos.end() && "ITEM: Error in UserDefault handling (!)"); |
773 | 0 | return aHit->second->getItem(); |
774 | 0 | } |
775 | | |
776 | 4.11M | const ItemInfo* pInfo(pTarget->maItemInfos[nIndex]); |
777 | 4.11M | assert(nullptr != pInfo && "ITEM: access error to Defaults in Pool (!)"); |
778 | 4.11M | const SfxPoolItem* pItem(pInfo->getItem()); |
779 | 4.11M | assert(nullptr != pItem && "ITEM: access error to Defaults in Pool (!)"); |
780 | 4.11M | return pItem; |
781 | 4.11M | } |
782 | | |
783 | | namespace |
784 | | { |
785 | | class SurrogateData_ItemSet : public SfxItemPool::SurrogateData |
786 | | { |
787 | | const SfxPoolItem* mpItem; |
788 | | SfxItemSet* mpSet; |
789 | | |
790 | | public: |
791 | | SurrogateData_ItemSet(const SfxPoolItem& rItem, SfxItemSet& rSet) |
792 | 3.50k | : SfxItemPool::SurrogateData() |
793 | 3.50k | , mpItem(&rItem) |
794 | 3.50k | , mpSet(&rSet) |
795 | 3.50k | { |
796 | 3.50k | } |
797 | | |
798 | 2.12k | SurrogateData_ItemSet(const SurrogateData_ItemSet&) = default; |
799 | | |
800 | | virtual const SfxPoolItem& getItem() const override |
801 | 2.14k | { |
802 | 2.14k | return *mpItem; |
803 | 2.14k | } |
804 | | |
805 | | virtual const SfxPoolItem* setItem(std::unique_ptr<SfxPoolItem> aNew) override |
806 | 1.56k | { |
807 | 1.56k | return mpSet->Put(std::unique_ptr<SfxPoolItem>(aNew.release())); |
808 | 1.56k | } |
809 | | }; |
810 | | |
811 | | class SurrogateData_ItemHolder : public SfxItemPool::SurrogateData |
812 | | { |
813 | | SfxPoolItemHolder* mpHolder; |
814 | | |
815 | | public: |
816 | | SurrogateData_ItemHolder(SfxPoolItemHolder& rHolder) |
817 | 0 | : SfxItemPool::SurrogateData() |
818 | 0 | , mpHolder(&rHolder) |
819 | 0 | { |
820 | 0 | } |
821 | | |
822 | 0 | SurrogateData_ItemHolder(const SurrogateData_ItemHolder&) = default; |
823 | | |
824 | | virtual const SfxPoolItem& getItem() const override |
825 | 0 | { |
826 | 0 | return *mpHolder->getItem(); |
827 | 0 | } |
828 | | |
829 | | virtual const SfxPoolItem* setItem(std::unique_ptr<SfxPoolItem> aNew) override |
830 | 0 | { |
831 | 0 | *mpHolder = SfxPoolItemHolder(mpHolder->getPool(), aNew.release(), true); |
832 | 0 | return mpHolder->getItem(); |
833 | 0 | } |
834 | | }; |
835 | | } |
836 | | |
837 | | void SfxItemPool::iterateItemSurrogates( |
838 | | sal_uInt16 nWhich, |
839 | | const std::function<bool(SurrogateData& rCand)>& rItemCallback) const |
840 | 1.56k | { |
841 | | // 1st source for surrogates |
842 | 1.56k | const registeredSfxItemSets& rSets(GetMasterPool()->maRegisteredSfxItemSets); |
843 | | |
844 | 1.56k | if(!rSets.empty()) |
845 | 1.56k | { |
846 | 1.56k | const SfxPoolItem* pItem(nullptr); |
847 | 1.56k | std::vector<SurrogateData_ItemSet> aEntries; |
848 | | |
849 | | // NOTE: this collects the callback data in a preparing run. This |
850 | | // is by purpose, else any write change may change the iterators |
851 | | // used at registeredSfxItemSets. I tied with direct feed and |
852 | | // that worked most of the time, but failed for ItemHolders due |
853 | | // to these being changed and being re-registered. I have avoided |
854 | | // this in SfxPoolItemHolder::operator=, but it's just a question |
855 | | // that in some scenario someone replaces an Item even with a |
856 | | // different type/WhichID that this will then break/crash |
857 | 1.56k | for (const auto& rCand : rSets) |
858 | 50.7k | if (SfxItemState::SET == rCand->GetItemState(nWhich, false, &pItem)) |
859 | 3.50k | aEntries.emplace_back(*pItem, *rCand); |
860 | | |
861 | 1.56k | if (!aEntries.empty()) |
862 | 1.56k | for (auto& rCand : aEntries) |
863 | 2.14k | if (!rItemCallback(rCand)) |
864 | 1.56k | return; |
865 | 1.56k | } |
866 | | |
867 | | // 2nd source for surrogates |
868 | 0 | const registeredSfxPoolItemHolders& rHolders(GetMasterPool()->maRegisteredSfxPoolItemHolders); |
869 | |
|
870 | 0 | if (!rHolders.empty()) |
871 | 0 | { |
872 | 0 | std::vector<SurrogateData_ItemHolder> aEntries; |
873 | | |
874 | | // NOTE: same as above, look there |
875 | 0 | for (auto& rCand : rHolders) |
876 | 0 | if (rCand->Which() == nWhich && nullptr != rCand->getItem()) |
877 | 0 | aEntries.emplace_back(*rCand); |
878 | |
|
879 | 0 | if (!aEntries.empty()) |
880 | 0 | for (auto& rCand : aEntries) |
881 | 0 | if (!rItemCallback(rCand)) |
882 | 0 | return; |
883 | 0 | } |
884 | 0 | } |
885 | | |
886 | | ItemSurrogates SfxItemPool::GetItemSurrogatesForItem(SfxItemType eItemType) const |
887 | 264k | { |
888 | 264k | ItemSurrogates aTarget; |
889 | 264k | const registeredNameOrIndex& rRegistered(GetMasterPool()->maRegisteredNameOrIndex); |
890 | 264k | registeredNameOrIndex::const_iterator aHit(rRegistered.find(eItemType)); |
891 | 264k | if (aHit != rRegistered.end()) |
892 | 215k | { |
893 | 215k | aTarget.reserve(aHit->second.size()); |
894 | 215k | for (const auto& entry : aHit->second) |
895 | 897k | aTarget.push_back(entry.first); |
896 | 215k | } |
897 | 264k | return aTarget; |
898 | 264k | } |
899 | | |
900 | | ItemSurrogates SfxItemPool::GetItemSurrogatesForItem(const SfxPoolItem& rItem) const |
901 | 128k | { |
902 | 128k | assert(rItem.isNameOrIndex() && "ITEM: only Items derived from NameOrIndex supported for this mechanism (!)"); |
903 | 128k | return GetItemSurrogatesForItem(rItem.ItemType()); |
904 | 128k | } |
905 | | |
906 | | ItemSurrogates SfxItemPool::GetItemSurrogates(sal_uInt16 nWhich) const |
907 | 1.94k | { |
908 | 1.94k | if (0 == nWhich) |
909 | 0 | return {}; |
910 | | |
911 | | // NOTE: This is pre-collected, in this case mainly to |
912 | | // remove all double listings of SfxPoolItems which can |
913 | | // of course be referenced multiple times in multiple |
914 | | // ItemSets/ItemHolders. It comes handy that |
915 | | // std::unordered_set does this by definition |
916 | 1.94k | std::unordered_set<const SfxPoolItem*> aNewSurrogates; |
917 | | |
918 | | // 1st source for surrogates |
919 | 1.94k | const registeredSfxItemSets& rSets(GetMasterPool()->maRegisteredSfxItemSets); |
920 | 1.94k | const SfxPoolItem* pItem(nullptr); |
921 | 1.94k | for (const auto& rCand : rSets) |
922 | 48.9k | if (SfxItemState::SET == rCand->GetItemState(nWhich, false, &pItem)) |
923 | 8.12k | aNewSurrogates.insert(pItem); |
924 | | |
925 | | // 2nd source for surrogates |
926 | 1.94k | const registeredSfxPoolItemHolders& rHolders(GetMasterPool()->maRegisteredSfxPoolItemHolders); |
927 | 1.94k | for (const auto& rCand : rHolders) |
928 | 21.9k | if (rCand->Which() == nWhich && nullptr != rCand->getItem()) |
929 | 0 | aNewSurrogates.insert(rCand->getItem()); |
930 | | |
931 | 1.94k | return ItemSurrogates(aNewSurrogates.begin(), aNewSurrogates.end()); |
932 | 1.94k | } |
933 | | |
934 | | sal_uInt16 SfxItemPool::GetWhichIDFromSlotID(sal_uInt16 nSlotId, bool bDeep) const |
935 | 351M | { |
936 | 351M | if (!IsSlot(nSlotId)) |
937 | 147M | return nSlotId; |
938 | | |
939 | 204M | if (nullptr != mpSlotIDToWhichIDMap) |
940 | 204M | { |
941 | | // use the static global translation table -> near linear access time |
942 | 204M | SlotIDToWhichIDMap::const_iterator aHit(mpSlotIDToWhichIDMap->find(nSlotId)); |
943 | 204M | if (aHit != mpSlotIDToWhichIDMap->end()) |
944 | 1.14M | return aHit->second; |
945 | 204M | } |
946 | | |
947 | 202M | if (mpSecondary && bDeep) |
948 | 12.3M | return mpSecondary->GetWhichIDFromSlotID(nSlotId); |
949 | | |
950 | 190M | return nSlotId; |
951 | 202M | } |
952 | | |
953 | | |
954 | | sal_uInt16 SfxItemPool::GetSlotId(sal_uInt16 nWhich) const |
955 | 1.98M | { |
956 | 1.98M | if (!IsWhich(nWhich)) |
957 | 0 | return nWhich; |
958 | | |
959 | 1.98M | SfxItemPool* pTarget(getTargetPool(nWhich)); |
960 | 1.98M | if (nullptr == pTarget) |
961 | 1.98M | assert(false && "unknown WhichId - cannot get slot-id"); |
962 | | |
963 | 1.98M | const sal_uInt16 nIndex(pTarget->GetIndex_Impl(nWhich)); |
964 | 1.98M | const ItemInfo* pInfo(pTarget->maItemInfos[nIndex]); |
965 | 1.98M | assert(nullptr != pInfo && "ITEM: access error to Defaults in Pool (!)"); |
966 | 1.98M | const sal_uInt16 nSID(pInfo->getSlotID()); |
967 | 1.98M | return (0 != nSID) ? nSID : nWhich; |
968 | 1.98M | } |
969 | | |
970 | | |
971 | | sal_uInt16 SfxItemPool::GetTrueWhichIDFromSlotID( sal_uInt16 nSlotId, bool bDeep ) const |
972 | 2.20M | { |
973 | 2.20M | if (!IsSlot(nSlotId)) |
974 | 0 | return 0; |
975 | | |
976 | 2.20M | if (nullptr != mpSlotIDToWhichIDMap) |
977 | 2.20M | { |
978 | | // use the static global translation table -> near linear access time |
979 | 2.20M | SlotIDToWhichIDMap::const_iterator aHit(mpSlotIDToWhichIDMap->find(nSlotId)); |
980 | 2.20M | if (aHit != mpSlotIDToWhichIDMap->end()) |
981 | 1.98M | return aHit->second; |
982 | 2.20M | } |
983 | | |
984 | 229k | if (mpSecondary && bDeep) |
985 | 0 | return mpSecondary->GetTrueWhichIDFromSlotID(nSlotId); |
986 | | |
987 | 229k | return 0; |
988 | 229k | } |
989 | | |
990 | | |
991 | | sal_uInt16 SfxItemPool::GetTrueSlotId( sal_uInt16 nWhich ) const |
992 | 986k | { |
993 | 986k | if (!IsWhich(nWhich)) |
994 | 0 | return 0; |
995 | | |
996 | 986k | SfxItemPool* pTarget(getTargetPool(nWhich)); |
997 | 986k | if (nullptr == pTarget) |
998 | 986k | assert(false && "unknown WhichId - cannot get slot-id"); |
999 | | |
1000 | 986k | const sal_uInt16 nIndex(pTarget->GetIndex_Impl(nWhich)); |
1001 | 986k | const ItemInfo* pInfo(pTarget->maItemInfos[nIndex]); |
1002 | | assert(nullptr != pInfo && "ITEM: access error to Defaults in Pool (!)"); |
1003 | 986k | return pInfo->getSlotID(); |
1004 | 986k | } |
1005 | | |
1006 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |