Line data Source code
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 : #include <svl/itempool.hxx>
23 : #include <svl/itemset.hxx>
24 : #include <svl/style.hxx>
25 : #include <comphelper/stl_types.hxx>
26 :
27 : #include <svx/svdmodel.hxx>
28 : #include "UnoNameItemTable.hxx"
29 : #include <osl/mutex.hxx>
30 : #include <vcl/svapp.hxx>
31 :
32 : #include "svx/unoapi.hxx"
33 :
34 : using namespace ::com::sun::star;
35 : using namespace ::rtl;
36 : using namespace ::cppu;
37 :
38 235 : SvxUnoNameItemTable::SvxUnoNameItemTable( SdrModel* pModel, sal_uInt16 nWhich, sal_uInt8 nMemberId ) throw()
39 : : mpModel( pModel ),
40 : mpModelPool( pModel ? &pModel->GetItemPool() : NULL ),
41 235 : mnWhich( nWhich ), mnMemberId( nMemberId )
42 : {
43 235 : if( pModel )
44 235 : StartListening( *pModel );
45 235 : }
46 :
47 470 : SvxUnoNameItemTable::~SvxUnoNameItemTable() throw()
48 : {
49 235 : if( mpModel )
50 235 : EndListening( *mpModel );
51 235 : dispose();
52 235 : }
53 :
54 52 : bool SvxUnoNameItemTable::isValid( const NameOrIndex* pItem ) const
55 : {
56 52 : return pItem && (pItem->GetName().Len() != 0);
57 : }
58 :
59 470 : void SvxUnoNameItemTable::dispose()
60 : {
61 470 : ItemPoolVector::iterator aIter = maItemSetVector.begin();
62 470 : const ItemPoolVector::iterator aEnd = maItemSetVector.end();
63 :
64 950 : while( aIter != aEnd )
65 : {
66 10 : delete (*aIter++);
67 : }
68 :
69 470 : maItemSetVector.clear();
70 470 : }
71 :
72 19704 : void SvxUnoNameItemTable::Notify( SfxBroadcaster&, const SfxHint& rHint ) throw()
73 : {
74 19704 : const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint );
75 :
76 19704 : if( pSdrHint && HINT_MODELCLEARED == pSdrHint->GetKind() )
77 225 : dispose();
78 19704 : }
79 :
80 0 : sal_Bool SAL_CALL SvxUnoNameItemTable::supportsService( const OUString& ServiceName ) throw(uno::RuntimeException)
81 : {
82 0 : uno::Sequence< OUString > aSNL( getSupportedServiceNames() );
83 0 : const OUString * pArray = aSNL.getConstArray();
84 :
85 0 : for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
86 0 : if( pArray[i] == ServiceName )
87 0 : return sal_True;
88 :
89 0 : return sal_False;
90 : }
91 :
92 10 : void SAL_CALL SvxUnoNameItemTable::ImplInsertByName( const OUString& aName, const uno::Any& aElement )
93 : {
94 10 : SfxItemSet* mpInSet = new SfxItemSet( *mpModelPool, mnWhich, mnWhich );
95 10 : maItemSetVector.push_back( mpInSet );
96 :
97 10 : NameOrIndex* pNewItem = createItem();
98 10 : pNewItem->SetName( String( aName ) );
99 10 : pNewItem->PutValue( aElement, mnMemberId );
100 10 : mpInSet->Put( *pNewItem, mnWhich );
101 10 : delete pNewItem;
102 10 : }
103 :
104 : // XNameContainer
105 10 : void SAL_CALL SvxUnoNameItemTable::insertByName( const OUString& aApiName, const uno::Any& aElement )
106 : throw( lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, uno::RuntimeException )
107 : {
108 10 : SolarMutexGuard aGuard;
109 :
110 10 : if( hasByName( aApiName ) )
111 0 : throw container::ElementExistException();
112 :
113 10 : OUString aName = SvxUnogetInternalNameForItem(mnWhich, aApiName);
114 :
115 10 : ImplInsertByName( aName, aElement );
116 10 : }
117 :
118 :
119 :
120 10 : void SAL_CALL SvxUnoNameItemTable::removeByName( const OUString& aApiName )
121 : throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
122 : {
123 10 : SolarMutexGuard aGuard;
124 :
125 : // a little quickfix for 2.0 to let applications clear api
126 : // created items that are not used
127 10 : if ( aApiName == "~clear~" )
128 : {
129 10 : dispose();
130 : return;
131 : }
132 :
133 0 : OUString sName = SvxUnogetInternalNameForItem(mnWhich, aApiName);
134 :
135 0 : ItemPoolVector::iterator aIter = maItemSetVector.begin();
136 0 : const ItemPoolVector::iterator aEnd = maItemSetVector.end();
137 :
138 : NameOrIndex *pItem;
139 :
140 0 : while( aIter != aEnd )
141 : {
142 0 : pItem = (NameOrIndex *)&((*aIter)->Get( mnWhich ) );
143 0 : if (sName.equals(pItem->GetName()))
144 : {
145 0 : delete (*aIter);
146 0 : maItemSetVector.erase( aIter );
147 : return;
148 : }
149 0 : ++aIter;
150 : }
151 :
152 0 : if (!hasByName(sName))
153 0 : throw container::NoSuchElementException();
154 : }
155 :
156 : // XNameReplace
157 0 : void SAL_CALL SvxUnoNameItemTable::replaceByName( const OUString& aApiName, const uno::Any& aElement )
158 : throw( lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException )
159 : {
160 0 : SolarMutexGuard aGuard;
161 :
162 0 : OUString aName = SvxUnogetInternalNameForItem(mnWhich, aApiName);
163 :
164 0 : ItemPoolVector::iterator aIter = maItemSetVector.begin();
165 0 : const ItemPoolVector::iterator aEnd = maItemSetVector.end();
166 :
167 : NameOrIndex *pItem;
168 :
169 0 : while( aIter != aEnd )
170 : {
171 0 : pItem = (NameOrIndex *)&((*aIter)->Get( mnWhich ) );
172 0 : if (aName.equals(pItem->GetName()))
173 : {
174 0 : NameOrIndex* pNewItem = createItem();
175 0 : pNewItem->SetName(aName);
176 0 : if( !pNewItem->PutValue( aElement, mnMemberId ) || !isValid( pNewItem ) )
177 0 : throw lang::IllegalArgumentException();
178 :
179 0 : (*aIter)->Put( *pNewItem );
180 0 : return;
181 : }
182 0 : ++aIter;
183 : }
184 :
185 : // if it is not in our own sets, modify the pool!
186 0 : sal_Bool bFound = sal_False;
187 :
188 : sal_uInt32 nSurrogate;
189 0 : sal_uInt32 nCount = mpModelPool ? mpModelPool->GetItemCount2( mnWhich ) : 0;
190 0 : for( nSurrogate = 0; nSurrogate < nCount; nSurrogate++ )
191 : {
192 0 : pItem = (NameOrIndex*)mpModelPool->GetItem2( mnWhich, nSurrogate);
193 0 : if (pItem && aName.equals(pItem->GetName()))
194 : {
195 0 : pItem->PutValue( aElement, mnMemberId );
196 0 : bFound = sal_True;
197 0 : break;
198 : }
199 : }
200 :
201 0 : if( bFound )
202 0 : ImplInsertByName( aName, aElement );
203 : else
204 0 : throw container::NoSuchElementException();
205 :
206 0 : if( !hasByName( aName ) )
207 0 : throw container::NoSuchElementException();
208 : }
209 :
210 : // XNameAccess
211 0 : uno::Any SAL_CALL SvxUnoNameItemTable::getByName( const OUString& aApiName )
212 : throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
213 : {
214 0 : SolarMutexGuard aGuard;
215 :
216 0 : OUString aName = SvxUnogetInternalNameForItem(mnWhich, aApiName);
217 :
218 0 : uno::Any aAny;
219 :
220 0 : if (mpModelPool && !aName.isEmpty())
221 : {
222 : NameOrIndex *pItem;
223 : sal_uInt32 nSurrogate;
224 :
225 0 : sal_uInt32 nSurrogateCount = mpModelPool ? mpModelPool->GetItemCount2( mnWhich ) : 0;
226 0 : for( nSurrogate = 0; nSurrogate < nSurrogateCount; nSurrogate++ )
227 : {
228 0 : pItem = (NameOrIndex*)mpModelPool->GetItem2( mnWhich, nSurrogate );
229 :
230 0 : if (isValid(pItem) && aName.equals(pItem->GetName()))
231 : {
232 0 : pItem->QueryValue( aAny, mnMemberId );
233 0 : return aAny;
234 : }
235 : }
236 : }
237 :
238 0 : throw container::NoSuchElementException();
239 : }
240 :
241 0 : uno::Sequence< OUString > SAL_CALL SvxUnoNameItemTable::getElementNames( )
242 : throw( uno::RuntimeException )
243 : {
244 0 : SolarMutexGuard aGuard;
245 :
246 0 : std::set< OUString, comphelper::UStringLess > aNameSet;
247 :
248 : NameOrIndex *pItem;
249 :
250 0 : const sal_uInt32 nSurrogateCount = mpModelPool ? mpModelPool->GetItemCount2( mnWhich ) : 0;
251 : sal_uInt32 nSurrogate;
252 0 : for( nSurrogate = 0; nSurrogate < nSurrogateCount; nSurrogate++ )
253 : {
254 0 : pItem = (NameOrIndex*)mpModelPool->GetItem2( mnWhich, nSurrogate );
255 :
256 0 : if( !isValid( pItem ) )
257 0 : continue;
258 :
259 0 : OUString aApiName = SvxUnogetApiNameForItem(mnWhich, pItem->GetName());
260 0 : aNameSet.insert(aApiName);
261 0 : }
262 :
263 0 : uno::Sequence< OUString > aSeq( aNameSet.size() );
264 0 : OUString* pNames = aSeq.getArray();
265 :
266 0 : std::set< OUString, comphelper::UStringLess >::iterator aIter( aNameSet.begin() );
267 0 : const std::set< OUString, comphelper::UStringLess >::iterator aEnd( aNameSet.end() );
268 :
269 0 : while( aIter != aEnd )
270 : {
271 0 : *pNames++ = *aIter++;
272 : }
273 :
274 0 : return aSeq;
275 : }
276 :
277 20 : sal_Bool SAL_CALL SvxUnoNameItemTable::hasByName( const OUString& aApiName )
278 : throw( uno::RuntimeException )
279 : {
280 20 : SolarMutexGuard aGuard;
281 :
282 20 : OUString aName = SvxUnogetInternalNameForItem(mnWhich, aApiName);
283 :
284 20 : if (aName.isEmpty())
285 0 : return sal_False;
286 :
287 : sal_uInt32 nSurrogate;
288 :
289 : const NameOrIndex *pItem;
290 :
291 20 : sal_uInt32 nCount = mpModelPool ? mpModelPool->GetItemCount2( mnWhich ) : 0;
292 72 : for( nSurrogate = 0; nSurrogate < nCount; nSurrogate++ )
293 : {
294 52 : pItem = (NameOrIndex*)mpModelPool->GetItem2( mnWhich, nSurrogate );
295 52 : if (isValid(pItem) && aName.equals(pItem->GetName()))
296 0 : return sal_True;
297 : }
298 :
299 20 : return sal_False;
300 : }
301 :
302 20 : sal_Bool SAL_CALL SvxUnoNameItemTable::hasElements( )
303 : throw( uno::RuntimeException )
304 : {
305 20 : SolarMutexGuard aGuard;
306 :
307 : const NameOrIndex *pItem;
308 :
309 : sal_uInt32 nSurrogate;
310 20 : const sal_uInt32 nSurrogateCount = mpModelPool ? mpModelPool->GetItemCount2( mnWhich ) : 0;
311 20 : for( nSurrogate = 0; nSurrogate < nSurrogateCount; nSurrogate++ )
312 : {
313 0 : pItem = (NameOrIndex*)mpModelPool->GetItem2( mnWhich, nSurrogate );
314 :
315 0 : if( isValid( pItem ) )
316 0 : return sal_True;
317 : }
318 :
319 20 : return sal_False;
320 : }
321 :
322 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|