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