1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26
27 #include <set>
28 #include <svl/itempool.hxx>
29 #include <svl/itemset.hxx>
30 #include <svl/style.hxx>
31 #include <comphelper/stl_types.hxx>
32
33 #include <svx/svdmodel.hxx>
34 #include "UnoNameItemTable.hxx"
35 #include <vos/mutex.hxx>
36 #include <vcl/svapp.hxx>
37
38 #include "svx/unoapi.hxx"
39
40 using namespace ::com::sun::star;
41 using namespace ::rtl;
42 using namespace ::cppu;
43 using namespace ::vos;
44
SvxUnoNameItemTable(SdrModel * pModel,sal_uInt16 nWhich,sal_uInt8 nMemberId)45 SvxUnoNameItemTable::SvxUnoNameItemTable( SdrModel* pModel, sal_uInt16 nWhich, sal_uInt8 nMemberId ) throw()
46 : mpModel( pModel ),
47 mpModelPool( pModel ? &pModel->GetItemPool() : NULL ),
48 mnWhich( nWhich ), mnMemberId( nMemberId )
49 {
50 if( pModel )
51 StartListening( *pModel );
52 }
53
~SvxUnoNameItemTable()54 SvxUnoNameItemTable::~SvxUnoNameItemTable() throw()
55 {
56 if( mpModel )
57 EndListening( *mpModel );
58 dispose();
59 }
60
isValid(const NameOrIndex * pItem) const61 bool SvxUnoNameItemTable::isValid( const NameOrIndex* pItem ) const
62 {
63 return pItem && (pItem->GetName().Len() != 0);
64 }
65
dispose()66 void SvxUnoNameItemTable::dispose()
67 {
68 ItemPoolVector::iterator aIter = maItemSetVector.begin();
69 const ItemPoolVector::iterator aEnd = maItemSetVector.end();
70
71 while( aIter != aEnd )
72 {
73 delete (*aIter++);
74 }
75
76 maItemSetVector.clear();
77 }
78
Notify(SfxBroadcaster &,const SfxHint & rHint)79 void SvxUnoNameItemTable::Notify( SfxBroadcaster&, const SfxHint& rHint ) throw()
80 {
81 const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint );
82
83 if( pSdrHint && HINT_MODELCLEARED == pSdrHint->GetKind() )
84 dispose();
85 }
86
supportsService(const OUString & ServiceName)87 sal_Bool SAL_CALL SvxUnoNameItemTable::supportsService( const OUString& ServiceName ) throw(uno::RuntimeException)
88 {
89 uno::Sequence< OUString > aSNL( getSupportedServiceNames() );
90 const OUString * pArray = aSNL.getConstArray();
91
92 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
93 if( pArray[i] == ServiceName )
94 return sal_True;
95
96 return sal_False;
97 }
98
ImplInsertByName(const OUString & aName,const uno::Any & aElement)99 void SAL_CALL SvxUnoNameItemTable::ImplInsertByName( const OUString& aName, const uno::Any& aElement )
100 {
101 SfxItemSet* mpInSet = new SfxItemSet( *mpModelPool, mnWhich, mnWhich );
102 maItemSetVector.push_back( mpInSet );
103
104 NameOrIndex* pNewItem = createItem();
105 pNewItem->SetName( String( aName ) );
106 pNewItem->PutValue( aElement, mnMemberId );
107 mpInSet->Put( *pNewItem, mnWhich );
108 delete pNewItem;
109 }
110
111 // XNameContainer
insertByName(const OUString & aApiName,const uno::Any & aElement)112 void SAL_CALL SvxUnoNameItemTable::insertByName( const OUString& aApiName, const uno::Any& aElement )
113 throw( lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, uno::RuntimeException )
114 {
115 OGuard aGuard( Application::GetSolarMutex() );
116
117 if( hasByName( aApiName ) )
118 throw container::ElementExistException();
119
120 String aName;
121 SvxUnogetInternalNameForItem( mnWhich, aApiName, aName );
122
123 ImplInsertByName( aName, aElement );
124 }
125
126
127
removeByName(const OUString & aApiName)128 void SAL_CALL SvxUnoNameItemTable::removeByName( const OUString& aApiName )
129 throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
130 {
131 OGuard aGuard( Application::GetSolarMutex() );
132
133 // a little quickfix for 2.0 to let applications clear api
134 // created items that are not used
135 if( aApiName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("~clear~") ) )
136 {
137 dispose();
138 return;
139 }
140
141 String Name;
142 SvxUnogetInternalNameForItem( mnWhich, aApiName, Name );
143
144 ItemPoolVector::iterator aIter = maItemSetVector.begin();
145 const ItemPoolVector::iterator aEnd = maItemSetVector.end();
146
147 NameOrIndex *pItem;
148 const String aSearchName( Name );
149
150 while( aIter != aEnd )
151 {
152 pItem = (NameOrIndex *)&((*aIter)->Get( mnWhich ) );
153 if( pItem->GetName() == aSearchName )
154 {
155 delete (*aIter);
156 maItemSetVector.erase( aIter );
157 return;
158 }
159 aIter++;
160 }
161
162 if( !hasByName( Name ) )
163 throw container::NoSuchElementException();
164 }
165
166 // XNameReplace
replaceByName(const OUString & aApiName,const uno::Any & aElement)167 void SAL_CALL SvxUnoNameItemTable::replaceByName( const OUString& aApiName, const uno::Any& aElement )
168 throw( lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException )
169 {
170 OGuard aGuard( Application::GetSolarMutex() );
171
172 String aName;
173 SvxUnogetInternalNameForItem( mnWhich, aApiName, aName );
174
175 ItemPoolVector::iterator aIter = maItemSetVector.begin();
176 const ItemPoolVector::iterator aEnd = maItemSetVector.end();
177
178 NameOrIndex *pItem;
179 const String aSearchName( aName );
180
181 while( aIter != aEnd )
182 {
183 pItem = (NameOrIndex *)&((*aIter)->Get( mnWhich ) );
184 if( pItem->GetName() == aSearchName )
185 {
186 NameOrIndex* pNewItem = createItem();
187 pNewItem->SetName( aSearchName );
188 if( !pNewItem->PutValue( aElement, mnMemberId ) || !isValid( pNewItem ) )
189 throw lang::IllegalArgumentException();
190
191 (*aIter)->Put( *pNewItem );
192 return;
193 }
194 aIter++;
195 }
196
197 // if it is not in our own sets, modify the pool!
198 sal_Bool bFound = sal_False;
199
200 sal_uInt32 nSurrogate;
201 sal_uInt32 nCount = mpModelPool ? mpModelPool->GetItemCount2( mnWhich ) : 0;
202 for( nSurrogate = 0; nSurrogate < nCount; nSurrogate++ )
203 {
204 pItem = (NameOrIndex*)mpModelPool->GetItem2( mnWhich, nSurrogate);
205 if( pItem && pItem->GetName() == aSearchName )
206 {
207 pItem->PutValue( aElement, mnMemberId );
208 bFound = sal_True;
209 break;
210 }
211 }
212
213 if( bFound )
214 ImplInsertByName( aName, aElement );
215 else
216 throw container::NoSuchElementException();
217
218 if( !hasByName( aName ) )
219 throw container::NoSuchElementException();
220 }
221
222 // XNameAccess
getByName(const OUString & aApiName)223 uno::Any SAL_CALL SvxUnoNameItemTable::getByName( const OUString& aApiName )
224 throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
225 {
226 OGuard aGuard( Application::GetSolarMutex() );
227
228 String aName;
229 SvxUnogetInternalNameForItem( mnWhich, aApiName, aName );
230
231 uno::Any aAny;
232
233 if( mpModelPool && aName.Len() != 0 )
234 {
235 const String aSearchName( aName );
236 NameOrIndex *pItem;
237 sal_uInt32 nSurrogate;
238
239 sal_uInt32 nSurrogateCount = mpModelPool ? mpModelPool->GetItemCount2( mnWhich ) : 0;
240 for( nSurrogate = 0; nSurrogate < nSurrogateCount; nSurrogate++ )
241 {
242 pItem = (NameOrIndex*)mpModelPool->GetItem2( mnWhich, nSurrogate );
243
244 if( isValid( pItem ) && (pItem->GetName() == aSearchName) )
245 {
246 pItem->QueryValue( aAny, mnMemberId );
247 return aAny;
248 }
249 }
250 }
251
252 throw container::NoSuchElementException();
253 }
254
getElementNames()255 uno::Sequence< OUString > SAL_CALL SvxUnoNameItemTable::getElementNames( )
256 throw( uno::RuntimeException )
257 {
258 OGuard aGuard( Application::GetSolarMutex() );
259
260 std::set< OUString, comphelper::UStringLess > aNameSet;
261
262 NameOrIndex *pItem;
263 OUString aApiName;
264
265 const sal_uInt32 nSurrogateCount = mpModelPool ? mpModelPool->GetItemCount2( mnWhich ) : 0;
266 sal_uInt32 nSurrogate;
267 for( nSurrogate = 0; nSurrogate < nSurrogateCount; nSurrogate++ )
268 {
269 pItem = (NameOrIndex*)mpModelPool->GetItem2( mnWhich, nSurrogate );
270
271 if( !isValid( pItem ) )
272 continue;
273
274 SvxUnogetApiNameForItem( mnWhich, pItem->GetName(), aApiName );
275 aNameSet.insert( aApiName );
276 }
277
278 uno::Sequence< OUString > aSeq( aNameSet.size() );
279 OUString* pNames = aSeq.getArray();
280
281 std::set< OUString, comphelper::UStringLess >::iterator aIter( aNameSet.begin() );
282 const std::set< OUString, comphelper::UStringLess >::iterator aEnd( aNameSet.end() );
283
284 while( aIter != aEnd )
285 {
286 *pNames++ = *aIter++;
287 }
288
289 return aSeq;
290 }
291
hasByName(const OUString & aApiName)292 sal_Bool SAL_CALL SvxUnoNameItemTable::hasByName( const OUString& aApiName )
293 throw( uno::RuntimeException )
294 {
295 OGuard aGuard( Application::GetSolarMutex() );
296
297 String aName;
298 SvxUnogetInternalNameForItem( mnWhich, aApiName, aName );
299
300 if( aName.Len() == 0 )
301 return sal_False;
302
303 const String aSearchName( aName );
304 sal_uInt32 nSurrogate;
305
306 const NameOrIndex *pItem;
307
308 sal_uInt32 nCount = mpModelPool ? mpModelPool->GetItemCount2( mnWhich ) : 0;
309 for( nSurrogate = 0; nSurrogate < nCount; nSurrogate++ )
310 {
311 pItem = (NameOrIndex*)mpModelPool->GetItem2( mnWhich, nSurrogate );
312 if( isValid( pItem ) && (pItem->GetName() == aSearchName) )
313 return sal_True;
314 }
315
316 return sal_False;
317 }
318
hasElements()319 sal_Bool SAL_CALL SvxUnoNameItemTable::hasElements( )
320 throw( uno::RuntimeException )
321 {
322 OGuard aGuard( Application::GetSolarMutex() );
323
324 const NameOrIndex *pItem;
325
326 sal_uInt32 nSurrogate;
327 const sal_uInt32 nSurrogateCount = mpModelPool ? mpModelPool->GetItemCount2( mnWhich ) : 0;
328 for( nSurrogate = 0; nSurrogate < nSurrogateCount; nSurrogate++ )
329 {
330 pItem = (NameOrIndex*)mpModelPool->GetItem2( mnWhich, nSurrogate );
331
332 if( isValid( pItem ) )
333 return sal_True;
334 }
335
336 return sal_False;
337 }
338