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 )
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 {
114 OGuard aGuard( Application::GetSolarMutex() );
115
116 if( hasByName( aApiName ) )
117 throw container::ElementExistException();
118
119 String aName;
120 SvxUnogetInternalNameForItem( mnWhich, aApiName, aName );
121
122 ImplInsertByName( aName, aElement );
123 }
124
125
126
removeByName(const OUString & aApiName)127 void SAL_CALL SvxUnoNameItemTable::removeByName( const OUString& aApiName )
128 {
129 OGuard aGuard( Application::GetSolarMutex() );
130
131 // a little quickfix for 2.0 to let applications clear api
132 // created items that are not used
133 if( aApiName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("~clear~") ) )
134 {
135 dispose();
136 return;
137 }
138
139 String Name;
140 SvxUnogetInternalNameForItem( mnWhich, aApiName, Name );
141
142 ItemPoolVector::iterator aIter = maItemSetVector.begin();
143 const ItemPoolVector::iterator aEnd = maItemSetVector.end();
144
145 NameOrIndex *pItem;
146 const String aSearchName( Name );
147
148 while( aIter != aEnd )
149 {
150 pItem = (NameOrIndex *)&((*aIter)->Get( mnWhich ) );
151 if( pItem->GetName() == aSearchName )
152 {
153 delete (*aIter);
154 maItemSetVector.erase( aIter );
155 return;
156 }
157 aIter++;
158 }
159
160 if( !hasByName( Name ) )
161 throw container::NoSuchElementException();
162 }
163
164 // XNameReplace
replaceByName(const OUString & aApiName,const uno::Any & aElement)165 void SAL_CALL SvxUnoNameItemTable::replaceByName( const OUString& aApiName, const uno::Any& aElement )
166 {
167 OGuard aGuard( Application::GetSolarMutex() );
168
169 String aName;
170 SvxUnogetInternalNameForItem( mnWhich, aApiName, aName );
171
172 ItemPoolVector::iterator aIter = maItemSetVector.begin();
173 const ItemPoolVector::iterator aEnd = maItemSetVector.end();
174
175 NameOrIndex *pItem;
176 const String aSearchName( aName );
177
178 while( aIter != aEnd )
179 {
180 pItem = (NameOrIndex *)&((*aIter)->Get( mnWhich ) );
181 if( pItem->GetName() == aSearchName )
182 {
183 NameOrIndex* pNewItem = createItem();
184 pNewItem->SetName( aSearchName );
185 if( !pNewItem->PutValue( aElement, mnMemberId ) || !isValid( pNewItem ) )
186 throw lang::IllegalArgumentException();
187
188 (*aIter)->Put( *pNewItem );
189 return;
190 }
191 aIter++;
192 }
193
194 // if it is not in our own sets, modify the pool!
195 sal_Bool bFound = sal_False;
196
197 sal_uInt32 nSurrogate;
198 sal_uInt32 nCount = mpModelPool ? mpModelPool->GetItemCount2( mnWhich ) : 0;
199 for( nSurrogate = 0; nSurrogate < nCount; nSurrogate++ )
200 {
201 pItem = (NameOrIndex*)mpModelPool->GetItem2( mnWhich, nSurrogate);
202 if( pItem && pItem->GetName() == aSearchName )
203 {
204 pItem->PutValue( aElement, mnMemberId );
205 bFound = sal_True;
206 break;
207 }
208 }
209
210 if( bFound )
211 ImplInsertByName( aName, aElement );
212 else
213 throw container::NoSuchElementException();
214
215 if( !hasByName( aName ) )
216 throw container::NoSuchElementException();
217 }
218
219 // XNameAccess
getByName(const OUString & aApiName)220 uno::Any SAL_CALL SvxUnoNameItemTable::getByName( const OUString& aApiName )
221 {
222 OGuard aGuard( Application::GetSolarMutex() );
223
224 String aName;
225 SvxUnogetInternalNameForItem( mnWhich, aApiName, aName );
226
227 uno::Any aAny;
228
229 if( mpModelPool && aName.Len() != 0 )
230 {
231 const String aSearchName( aName );
232 NameOrIndex *pItem;
233 sal_uInt32 nSurrogate;
234
235 sal_uInt32 nSurrogateCount = mpModelPool ? mpModelPool->GetItemCount2( mnWhich ) : 0;
236 for( nSurrogate = 0; nSurrogate < nSurrogateCount; nSurrogate++ )
237 {
238 pItem = (NameOrIndex*)mpModelPool->GetItem2( mnWhich, nSurrogate );
239
240 if( isValid( pItem ) && (pItem->GetName() == aSearchName) )
241 {
242 pItem->QueryValue( aAny, mnMemberId );
243 return aAny;
244 }
245 }
246 }
247
248 throw container::NoSuchElementException();
249 }
250
getElementNames()251 uno::Sequence< OUString > SAL_CALL SvxUnoNameItemTable::getElementNames( )
252 {
253 OGuard aGuard( Application::GetSolarMutex() );
254
255 std::set< OUString, comphelper::UStringLess > aNameSet;
256
257 NameOrIndex *pItem;
258 OUString aApiName;
259
260 const sal_uInt32 nSurrogateCount = mpModelPool ? mpModelPool->GetItemCount2( mnWhich ) : 0;
261 sal_uInt32 nSurrogate;
262 for( nSurrogate = 0; nSurrogate < nSurrogateCount; nSurrogate++ )
263 {
264 pItem = (NameOrIndex*)mpModelPool->GetItem2( mnWhich, nSurrogate );
265
266 if( !isValid( pItem ) )
267 continue;
268
269 SvxUnogetApiNameForItem( mnWhich, pItem->GetName(), aApiName );
270 aNameSet.insert( aApiName );
271 }
272
273 uno::Sequence< OUString > aSeq( aNameSet.size() );
274 OUString* pNames = aSeq.getArray();
275
276 std::set< OUString, comphelper::UStringLess >::iterator aIter( aNameSet.begin() );
277 const std::set< OUString, comphelper::UStringLess >::iterator aEnd( aNameSet.end() );
278
279 while( aIter != aEnd )
280 {
281 *pNames++ = *aIter++;
282 }
283
284 return aSeq;
285 }
286
hasByName(const OUString & aApiName)287 sal_Bool SAL_CALL SvxUnoNameItemTable::hasByName( const OUString& aApiName )
288 {
289 OGuard aGuard( Application::GetSolarMutex() );
290
291 String aName;
292 SvxUnogetInternalNameForItem( mnWhich, aApiName, aName );
293
294 if( aName.Len() == 0 )
295 return sal_False;
296
297 const String aSearchName( aName );
298 sal_uInt32 nSurrogate;
299
300 const NameOrIndex *pItem;
301
302 sal_uInt32 nCount = mpModelPool ? mpModelPool->GetItemCount2( mnWhich ) : 0;
303 for( nSurrogate = 0; nSurrogate < nCount; nSurrogate++ )
304 {
305 pItem = (NameOrIndex*)mpModelPool->GetItem2( mnWhich, nSurrogate );
306 if( isValid( pItem ) && (pItem->GetName() == aSearchName) )
307 return sal_True;
308 }
309
310 return sal_False;
311 }
312
hasElements()313 sal_Bool SAL_CALL SvxUnoNameItemTable::hasElements( )
314 {
315 OGuard aGuard( Application::GetSolarMutex() );
316
317 const NameOrIndex *pItem;
318
319 sal_uInt32 nSurrogate;
320 const sal_uInt32 nSurrogateCount = mpModelPool ? mpModelPool->GetItemCount2( mnWhich ) : 0;
321 for( nSurrogate = 0; nSurrogate < nSurrogateCount; nSurrogate++ )
322 {
323 pItem = (NameOrIndex*)mpModelPool->GetItem2( mnWhich, nSurrogate );
324
325 if( isValid( pItem ) )
326 return sal_True;
327 }
328
329 return sal_False;
330 }
331