LibreOffice Module svx (master) 1
UnoNameItemTable.cxx
Go to the documentation of this file.
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
21#include <set>
22
23#include <svl/itempool.hxx>
24#include <svl/itemset.hxx>
28
29#include <svx/svdmodel.hxx>
30#include "UnoNameItemTable.hxx"
31#include <vcl/svapp.hxx>
32
33#include <svx/unoapi.hxx>
34#include <memory>
35
36using namespace ::com::sun::star;
37using namespace ::cppu;
38
39namespace
40{
41 // We need to override operator== here and specifically bypass the assert
42 // in SfxPoolItem::operator== in order to make the FindItemSurrogate call
43 // in SvxUnoNameItemTable::hasByName safe.
44 class SampleItem : public NameOrIndex
45 {
46 public:
47 SampleItem(sal_uInt16 nWhich, const OUString& rName) : NameOrIndex(TypedWhichId<NameOrIndex>(nWhich), rName) {}
48
49 bool operator==(const SfxPoolItem& rCmp) const
50 {
51 assert(dynamic_cast<const NameOrIndex*>(&rCmp) && "comparing different pool item subclasses");
52 auto const & rOther = static_cast<const NameOrIndex&>(rCmp);
53 return GetName() == rOther.GetName() && GetPalIndex() == rOther.GetPalIndex();
54 }
55 };
56
57}
58
59
60SvxUnoNameItemTable::SvxUnoNameItemTable( SdrModel* pModel, sal_uInt16 nWhich, sal_uInt8 nMemberId ) noexcept
61: mpModel( pModel ),
62 mpModelPool( pModel ? &pModel->GetItemPool() : nullptr ),
63 mnWhich( nWhich ), mnMemberId( nMemberId )
64{
65 if( pModel )
66 StartListening( *pModel );
67}
68
70{
71 SolarMutexGuard aGuard;
72
73 if( mpModel )
75 dispose();
76}
77
78bool SvxUnoNameItemTable::isValid( const NameOrIndex* pItem ) const
79{
80 return pItem && !pItem->GetName().isEmpty();
81}
82
84{
85 maItemSetVector.clear();
86}
87
88void SvxUnoNameItemTable::Notify( SfxBroadcaster&, const SfxHint& rHint ) noexcept
89{
90 if (rHint.GetId() != SfxHintId::ThisIsAnSdrHint)
91 return;
92 const SdrHint* pSdrHint = static_cast<const SdrHint*>(&rHint);
93 if( SdrHintKind::ModelCleared == pSdrHint->GetKind() )
94 dispose();
95}
96
97sal_Bool SAL_CALL SvxUnoNameItemTable::supportsService( const OUString& ServiceName )
98{
100}
101
102void SvxUnoNameItemTable::ImplInsertByName( const OUString& aName, const uno::Any& aElement )
103{
104 maItemSetVector.push_back( std::make_unique< SfxItemSet >( *mpModelPool, mnWhich, mnWhich ) );
105
106 std::unique_ptr<NameOrIndex> xNewItem(createItem());
107 xNewItem->SetName(aName);
108 xNewItem->PutValue(aElement, mnMemberId);
109 xNewItem->SetWhich(mnWhich);
110 maItemSetVector.back()->Put(std::move(xNewItem));
111}
112
113// XNameContainer
114void SAL_CALL SvxUnoNameItemTable::insertByName( const OUString& aApiName, const uno::Any& aElement )
115{
116 SolarMutexGuard aGuard;
117 comphelper::ProfileZone aZone("SvxUnoNameItemTable::insertByName");
118
119 if( hasByName( aApiName ) )
120 throw container::ElementExistException();
121
122 OUString aName = SvxUnogetInternalNameForItem(mnWhich, aApiName);
123
124 ImplInsertByName( aName, aElement );
125}
126
128{
129 SolarMutexGuard aGuard;
130 // drop all items that are owned by this service and not the document
131 // (i.e. they are unused)
132 dispose();
133}
134
135void SAL_CALL SvxUnoNameItemTable::removeByName( const OUString& aApiName )
136{
137 SolarMutexGuard aGuard;
138 comphelper::ProfileZone aZone("SvxUnoNameItemTable::removeByName");
139
140 OUString sName = SvxUnogetInternalNameForItem(mnWhich, aApiName);
141
142 auto aIter = std::find_if(maItemSetVector.begin(), maItemSetVector.end(),
143 [&](const std::unique_ptr<SfxItemSet>& rpItem) {
144 const NameOrIndex *pItem = static_cast<const NameOrIndex *>(&(rpItem->Get( mnWhich ) ));
145 return sName == pItem->GetName();
146 });
147 if (aIter != maItemSetVector.end())
148 {
149 maItemSetVector.erase( aIter );
150 return;
151 }
152
153 if (!hasByName(sName))
154 throw container::NoSuchElementException();
155}
156
157// XNameReplace
158void SAL_CALL SvxUnoNameItemTable::replaceByName( const OUString& aApiName, const uno::Any& aElement )
159{
160 SolarMutexGuard aGuard;
161
162 OUString aName = SvxUnogetInternalNameForItem(mnWhich, aApiName);
163
164 auto aIter = std::find_if(maItemSetVector.begin(), maItemSetVector.end(),
165 [&](const std::unique_ptr<SfxItemSet>& rpItem) {
166 const NameOrIndex *pItem = static_cast<const NameOrIndex *>(&(rpItem->Get( mnWhich ) ));
167 return aName == pItem->GetName();
168 });
169 if (aIter != maItemSetVector.end())
170 {
171 std::unique_ptr<NameOrIndex> xNewItem(createItem());
172 xNewItem->SetName(aName);
173 if (!xNewItem->PutValue(aElement, mnMemberId) || !isValid(xNewItem.get()))
174 throw lang::IllegalArgumentException();
175 (*aIter)->Put(std::move(xNewItem));
176 return;
177 }
178
179 // if it is not in our own sets, modify the pool!
180 bool bFound = false;
181
182 if (mpModelPool)
183 {
184 SampleItem aSample(mnWhich, aName);
185 for (const SfxPoolItem* pNameOrIndex : mpModelPool->FindItemSurrogate(mnWhich, aSample))
186 if (isValid(static_cast<const NameOrIndex*>(pNameOrIndex)))
187 {
188 const_cast<SfxPoolItem*>(pNameOrIndex)->PutValue( aElement, mnMemberId );
189 bFound = true;
190 }
191 }
192
193 if( !bFound )
194 throw container::NoSuchElementException();
195
196 ImplInsertByName( aName, aElement );
197
198 if( !hasByName( aName ) )
199 throw container::NoSuchElementException();
200}
201
202// XNameAccess
203uno::Any SAL_CALL SvxUnoNameItemTable::getByName( const OUString& aApiName )
204{
205 SolarMutexGuard aGuard;
206 comphelper::ProfileZone aZone("SvxUnoNameItemTable::getByName");
207
208 OUString aName = SvxUnogetInternalNameForItem(mnWhich, aApiName);
209
210 if (mpModelPool && !aName.isEmpty())
211 {
212 SampleItem aSample(mnWhich, aName);
213 for (const SfxPoolItem* pFindItem : mpModelPool->FindItemSurrogate(mnWhich, aSample))
214 if (isValid(static_cast<const NameOrIndex*>(pFindItem)))
215 {
216 uno::Any aAny;
217 pFindItem->QueryValue( aAny, mnMemberId );
218 return aAny;
219 }
220 }
221
222 throw container::NoSuchElementException();
223}
224
225uno::Sequence< OUString > SAL_CALL SvxUnoNameItemTable::getElementNames( )
226{
227 SolarMutexGuard aGuard;
228
229 std::set< OUString > aNameSet;
230
231
232 if (mpModelPool)
233 for (const SfxPoolItem* pItem : mpModelPool->GetItemSurrogates(mnWhich))
234 {
235 const NameOrIndex *pNameOrIndex = static_cast<const NameOrIndex*>(pItem);
236
237 if( !isValid( pNameOrIndex ) )
238 continue;
239
240 OUString aApiName = SvxUnogetApiNameForItem(mnWhich, pNameOrIndex->GetName());
241 aNameSet.insert(aApiName);
242 }
243
244 return comphelper::containerToSequence(aNameSet);
245}
246
247sal_Bool SAL_CALL SvxUnoNameItemTable::hasByName( const OUString& aApiName )
248{
249 SolarMutexGuard aGuard;
250
251 OUString aName = SvxUnogetInternalNameForItem(mnWhich, aApiName);
252
253 if (aName.isEmpty())
254 return false;
255
256 if (!mpModelPool)
257 return false;
258
259 SampleItem aSample(mnWhich, aName);
260 for (const SfxPoolItem* pFindItem : mpModelPool->FindItemSurrogate(mnWhich, aSample))
261 if (isValid(static_cast<const NameOrIndex*>(pFindItem)))
262 return true;
263 return false;
264}
265
267{
268 SolarMutexGuard aGuard;
269
270 if (mpModelPool)
271 for (const SfxPoolItem* pItem : mpModelPool->GetItemSurrogates(mnWhich))
272 {
273 const NameOrIndex *pNameOrIndex = static_cast<const NameOrIndex*>(pItem);
274
275 if( isValid( pNameOrIndex ) )
276 return true;
277 }
278
279 return false;
280}
281
282/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual bool operator==(const SfxPoolItem &rItem) const override
Definition: xattr.cxx:116
OUString const & GetName() const
Definition: xit.hxx:53
sal_Int32 GetPalIndex() const
Definition: xit.hxx:56
SdrHintKind GetKind() const
Definition: svdmodel.hxx:132
Item2Range GetItemSurrogates(sal_uInt16 nWhich) const
std::vector< const SfxPoolItem * > FindItemSurrogate(sal_uInt16 nWhich, SfxPoolItem const &rNeedle) const
void EndListening(SfxBroadcaster &rBroadcaster, bool bRemoveAllDuplicates=false)
virtual css::uno::Any SAL_CALL getByName(const OUString &aName) override
virtual bool isValid(const NameOrIndex *pItem) const
virtual NameOrIndex * createItem() const =0
virtual void SAL_CALL removeByName(const OUString &Name) override
ItemPoolVector maItemSetVector
vector contains all items that were created by this service and will keep them alive even if nothing ...
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
virtual void SAL_CALL cancel() override
virtual void SAL_CALL insertByName(const OUString &aName, const css::uno::Any &aElement) override
virtual sal_Bool SAL_CALL hasByName(const OUString &aName) override
void ImplInsertByName(const OUString &aName, const css::uno::Any &aElement)
virtual ~SvxUnoNameItemTable() noexcept override
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) noexcept override
virtual sal_Bool SAL_CALL hasElements() override
virtual css::uno::Sequence< OUString > SAL_CALL getElementNames() override
SvxUnoNameItemTable(SdrModel *pModel, sal_uInt16 nWhich, sal_uInt8 nMemberId) noexcept
virtual void SAL_CALL replaceByName(const OUString &aName, const css::uno::Any &aElement) override
SfxItemPool * mpModelPool
OUString sName
OUString aName
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
void dispose()
unsigned char sal_uInt8
unsigned char sal_Bool
OUString SvxUnogetApiNameForItem(const sal_uInt16 nWhich, const OUString &rInternalName)
if the given name is a predefined name for the current language it is replaced by the corresponding a...
Definition: unoprov.cxx:1984
OUString SvxUnogetInternalNameForItem(const sal_uInt16 nWhich, const OUString &rApiName)
if the given name is a predefined api name it is replaced by the predefined name for the current lang...
Definition: unoprov.cxx:2017