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>
26 #include <comphelper/sequence.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 
36 using namespace ::com::sun::star;
37 using namespace ::cppu;
38 
39 namespace
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(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 
60 SvxUnoNameItemTable::SvxUnoNameItemTable( SdrModel* pModel, sal_uInt16 nWhich, sal_uInt8 nMemberId ) throw()
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  if( mpModel )
73  dispose();
74 }
75 
76 bool SvxUnoNameItemTable::isValid( const NameOrIndex* pItem ) const
77 {
78  return pItem && !pItem->GetName().isEmpty();
79 }
80 
82 {
83  maItemSetVector.clear();
84 }
85 
86 void SvxUnoNameItemTable::Notify( SfxBroadcaster&, const SfxHint& rHint ) throw()
87 {
88  if (rHint.GetId() != SfxHintId::ThisIsAnSdrHint)
89  return;
90  const SdrHint* pSdrHint = static_cast<const SdrHint*>(&rHint);
91  if( SdrHintKind::ModelCleared == pSdrHint->GetKind() )
92  dispose();
93 }
94 
95 sal_Bool SAL_CALL SvxUnoNameItemTable::supportsService( const OUString& ServiceName )
96 {
97  return cppu::supportsService(this, ServiceName);
98 }
99 
100 void SvxUnoNameItemTable::ImplInsertByName( const OUString& aName, const uno::Any& aElement )
101 {
102  maItemSetVector.push_back( std::make_unique< SfxItemSet >( *mpModelPool, std::initializer_list<SfxItemSet::Pair>{{mnWhich, mnWhich}} ) );
103 
104  std::unique_ptr<NameOrIndex> xNewItem(createItem());
105  xNewItem->SetName(aName);
106  xNewItem->PutValue(aElement, mnMemberId);
107  xNewItem->SetWhich(mnWhich);
108  maItemSetVector.back()->Put(*xNewItem);
109 }
110 
111 // XNameContainer
112 void SAL_CALL SvxUnoNameItemTable::insertByName( const OUString& aApiName, const uno::Any& aElement )
113 {
114  SolarMutexGuard aGuard;
115  comphelper::ProfileZone aZone("SvxUnoNameItemTable::insertByName");
116 
117  if( hasByName( aApiName ) )
118  throw container::ElementExistException();
119 
120  OUString aName = SvxUnogetInternalNameForItem(mnWhich, aApiName);
121 
122  ImplInsertByName( aName, aElement );
123 }
124 
125 
126 void SAL_CALL SvxUnoNameItemTable::removeByName( const OUString& aApiName )
127 {
128  SolarMutexGuard aGuard;
129  comphelper::ProfileZone aZone("SvxUnoNameItemTable::removeByName");
130 
131  // a little quickfix for 2.0 to let applications clear api
132  // created items that are not used
133  if ( aApiName == "~clear~" )
134  {
135  dispose();
136  return;
137  }
138 
139  OUString sName = SvxUnogetInternalNameForItem(mnWhich, aApiName);
140 
141  auto aIter = std::find_if(maItemSetVector.begin(), maItemSetVector.end(),
142  [&](const std::unique_ptr<SfxItemSet>& rpItem) {
143  const NameOrIndex *pItem = static_cast<const NameOrIndex *>(&(rpItem->Get( mnWhich ) ));
144  return sName == pItem->GetName();
145  });
146  if (aIter != maItemSetVector.end())
147  {
148  maItemSetVector.erase( aIter );
149  return;
150  }
151 
152  if (!hasByName(sName))
153  throw container::NoSuchElementException();
154 }
155 
156 // XNameReplace
157 void SAL_CALL SvxUnoNameItemTable::replaceByName( const OUString& aApiName, const uno::Any& aElement )
158 {
159  SolarMutexGuard aGuard;
160 
161  OUString aName = SvxUnogetInternalNameForItem(mnWhich, aApiName);
162 
163  auto aIter = std::find_if(maItemSetVector.begin(), maItemSetVector.end(),
164  [&](const std::unique_ptr<SfxItemSet>& rpItem) {
165  const NameOrIndex *pItem = static_cast<const NameOrIndex *>(&(rpItem->Get( mnWhich ) ));
166  return aName == pItem->GetName();
167  });
168  if (aIter != maItemSetVector.end())
169  {
170  std::unique_ptr<NameOrIndex> xNewItem(createItem());
171  xNewItem->SetName(aName);
172  if (!xNewItem->PutValue(aElement, mnMemberId) || !isValid(xNewItem.get()))
173  throw lang::IllegalArgumentException();
174  (*aIter)->Put(*xNewItem);
175  return;
176  }
177 
178  // if it is not in our own sets, modify the pool!
179  bool bFound = false;
180 
181  if (mpModelPool)
182  {
183  NameOrIndex aSample(mnWhich, aName);
184  for (const SfxPoolItem* pNameOrIndex : mpModelPool->FindItemSurrogate(mnWhich, aSample))
185  if (isValid(static_cast<const NameOrIndex*>(pNameOrIndex)))
186  {
187  const_cast<SfxPoolItem*>(pNameOrIndex)->PutValue( aElement, mnMemberId );
188  bFound = true;
189  }
190  }
191 
192  if( !bFound )
193  throw container::NoSuchElementException();
194 
195  ImplInsertByName( aName, aElement );
196 
197  if( !hasByName( aName ) )
198  throw container::NoSuchElementException();
199 }
200 
201 // XNameAccess
202 uno::Any SAL_CALL SvxUnoNameItemTable::getByName( const OUString& aApiName )
203 {
204  SolarMutexGuard aGuard;
205  comphelper::ProfileZone aZone("SvxUnoNameItemTable::getByName");
206 
207  OUString aName = SvxUnogetInternalNameForItem(mnWhich, aApiName);
208 
209  if (mpModelPool && !aName.isEmpty())
210  {
211  SampleItem aSample(mnWhich, aName);
212  for (const SfxPoolItem* pFindItem : mpModelPool->FindItemSurrogate(mnWhich, aSample))
213  if (isValid(static_cast<const NameOrIndex*>(pFindItem)))
214  {
215  uno::Any aAny;
216  pFindItem->QueryValue( aAny, mnMemberId );
217  return aAny;
218  }
219  }
220 
221  throw container::NoSuchElementException();
222 }
223 
224 uno::Sequence< OUString > SAL_CALL SvxUnoNameItemTable::getElementNames( )
225 {
226  SolarMutexGuard aGuard;
227 
228  std::set< OUString > aNameSet;
229 
230 
231  if (mpModelPool)
232  for (const SfxPoolItem* pItem : mpModelPool->GetItemSurrogates(mnWhich))
233  {
234  const NameOrIndex *pNameOrIndex = static_cast<const NameOrIndex*>(pItem);
235 
236  if( !isValid( pNameOrIndex ) )
237  continue;
238 
239  OUString aApiName = SvxUnogetApiNameForItem(mnWhich, pNameOrIndex->GetName());
240  aNameSet.insert(aApiName);
241  }
242 
243  return comphelper::containerToSequence(aNameSet);
244 }
245 
246 sal_Bool SAL_CALL SvxUnoNameItemTable::hasByName( const OUString& aApiName )
247 {
248  SolarMutexGuard aGuard;
249 
250  OUString aName = SvxUnogetInternalNameForItem(mnWhich, aApiName);
251 
252  if (aName.isEmpty())
253  return false;
254 
255  if (!mpModelPool)
256  return false;
257 
258  SampleItem aSample(mnWhich, aName);
259  for (const SfxPoolItem* pFindItem : mpModelPool->FindItemSurrogate(mnWhich, aSample))
260  if (isValid(static_cast<const NameOrIndex*>(pFindItem)))
261  return true;
262  return false;
263 }
264 
266 {
267  SolarMutexGuard aGuard;
268 
269  if (mpModelPool)
270  for (const SfxPoolItem* pItem : mpModelPool->GetItemSurrogates(mnWhich))
271  {
272  const NameOrIndex *pNameOrIndex = static_cast<const NameOrIndex*>(pItem);
273 
274  if( isValid( pNameOrIndex ) )
275  return true;
276  }
277 
278  return false;
279 }
280 
281 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SfxItemPool * mpModelPool
SdrHintKind GetKind() const
Definition: svdmodel.hxx:124
std::vector< const SfxPoolItem * > FindItemSurrogate(sal_uInt16 nWhich, SfxPoolItem const &rNeedle) const
virtual NameOrIndex * createItem() const =0
virtual void SAL_CALL insertByName(const OUString &aName, const css::uno::Any &aElement) override
ItemPoolVector maItemSetVector
virtual bool isValid(const NameOrIndex *pItem) const
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:1952
virtual void SAL_CALL removeByName(const OUString &Name) override
void ImplInsertByName(const OUString &aName, const css::uno::Any &aElement)
sal_Int32 GetPalIndex() const
Definition: xit.hxx:55
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
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:1985
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
virtual void SAL_CALL replaceByName(const OUString &aName, const css::uno::Any &aElement) override
virtual css::uno::Sequence< OUString > SAL_CALL getElementNames() override
OUString sName
virtual css::uno::Any SAL_CALL getByName(const OUString &aName) override
SvxUnoNameItemTable(SdrModel *pModel, sal_uInt16 nWhich, sal_uInt8 nMemberId)
unsigned char sal_Bool
virtual ~SvxUnoNameItemTable() override
virtual sal_Bool SAL_CALL hasElements() override
virtual sal_Bool SAL_CALL hasByName(const OUString &aName) override
virtual bool operator==(const SfxPoolItem &rItem) const override
Definition: xattr.cxx:112
unsigned char sal_uInt8
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
OUString aName
Item2Range GetItemSurrogates(sal_uInt16 nWhich) const
void EndListening(SfxBroadcaster &rBroadcaster, bool bRemoveAllDuplicates=false)
OUString const & GetName() const
Definition: xit.hxx:52
void dispose()
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override