xref: /aoo42x/main/svl/source/items/itemprop.cxx (revision cdf0e10c)
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_svl.hxx"
30 
31 #include <svl/itemprop.hxx>
32 #include <svl/itempool.hxx>
33 #include <svl/itemset.hxx>
34 #include <com/sun/star/beans/PropertyAttribute.hpp>
35 #include <hash_map>
36 /*************************************************************************
37 	UNO III Implementation
38 *************************************************************************/
39 using namespace com::sun::star;
40 using namespace com::sun::star::beans;
41 using namespace com::sun::star::lang;
42 using namespace com::sun::star::uno;
43 
44 /*-- 16.02.2009 10:03:55---------------------------------------------------
45 
46   -----------------------------------------------------------------------*/
47 
48 struct equalOUString
49 {
50   bool operator()(const ::rtl::OUString& r1, const ::rtl::OUString&  r2) const
51   {
52     return r1.equals( r2 );
53   }
54 };
55 
56 typedef ::std::hash_map< ::rtl::OUString,
57                                  SfxItemPropertySimpleEntry,
58                                  ::rtl::OUStringHash,
59                                  equalOUString > SfxItemPropertyHashMap_t;
60 
61 class SfxItemPropertyMap_Impl : public SfxItemPropertyHashMap_t
62 {
63 public:
64     mutable uno::Sequence< beans::Property > m_aPropSeq;
65 
66     SfxItemPropertyMap_Impl(){}
67     SfxItemPropertyMap_Impl( const SfxItemPropertyMap_Impl* pSource );
68 };
69 SfxItemPropertyMap_Impl::SfxItemPropertyMap_Impl( const SfxItemPropertyMap_Impl* pSource )
70 {
71     this->SfxItemPropertyHashMap_t::operator=( *pSource );
72     m_aPropSeq = pSource->m_aPropSeq;
73 }
74 
75 /*-- 16.02.2009 10:03:51---------------------------------------------------
76 
77   -----------------------------------------------------------------------*/
78 SfxItemPropertyMap::SfxItemPropertyMap( const SfxItemPropertyMapEntry* pEntries ) :
79     m_pImpl( new SfxItemPropertyMap_Impl )
80 {
81     while( pEntries->pName )
82     {
83         ::rtl::OUString sEntry(pEntries->pName, pEntries->nNameLen, RTL_TEXTENCODING_ASCII_US );
84         (*m_pImpl) [ sEntry ] = pEntries;
85         ++pEntries;
86     }
87 }
88 /*-- 16.02.2009 12:46:41---------------------------------------------------
89 
90   -----------------------------------------------------------------------*/
91 SfxItemPropertyMap::SfxItemPropertyMap( const SfxItemPropertyMap* pSource ) :
92     m_pImpl( new SfxItemPropertyMap_Impl( pSource->m_pImpl ) )
93 {
94 }
95 /*-- 16.02.2009 10:03:51---------------------------------------------------
96 
97   -----------------------------------------------------------------------*/
98 SfxItemPropertyMap::~SfxItemPropertyMap()
99 {
100     delete m_pImpl;
101 }
102 /*-- 16.02.2009 10:03:51---------------------------------------------------
103 
104   -----------------------------------------------------------------------*/
105 const SfxItemPropertySimpleEntry* SfxItemPropertyMap::getByName( const ::rtl::OUString &rName ) const
106 {
107     SfxItemPropertyHashMap_t::const_iterator aIter = m_pImpl->find(rName);
108     if( aIter == m_pImpl->end() )
109         return 0;
110     return &aIter->second;
111 }
112 
113 /*-- 16.02.2009 10:44:24---------------------------------------------------
114 
115   -----------------------------------------------------------------------*/
116 uno::Sequence<beans::Property> SfxItemPropertyMap::getProperties() const
117 {
118     if( !m_pImpl->m_aPropSeq.getLength() )
119     {
120         m_pImpl->m_aPropSeq.realloc( m_pImpl->size() );
121         beans::Property* pPropArray = m_pImpl->m_aPropSeq.getArray();
122         sal_uInt32 n = 0;
123         SfxItemPropertyHashMap_t::const_iterator aIt = m_pImpl->begin();
124         while( aIt != m_pImpl->end() )
125         //for ( const SfxItemPropertyMap *pMap = _pMap; pMap->pName; ++pMap )
126         {
127             const SfxItemPropertySimpleEntry* pEntry = &(*aIt).second;
128             pPropArray[n].Name = (*aIt).first;
129             pPropArray[n].Handle = pEntry->nWID;
130             if(pEntry->pType)
131                 pPropArray[n].Type = *pEntry->pType;
132             pPropArray[n].Attributes =
133                 sal::static_int_cast< sal_Int16 >(pEntry->nFlags);
134             n++;
135             ++aIt;
136         }
137     }
138 
139     return m_pImpl->m_aPropSeq;
140 }
141 /*-- 16.02.2009 11:04:31---------------------------------------------------
142 
143   -----------------------------------------------------------------------*/
144 beans::Property SfxItemPropertyMap::getPropertyByName( const ::rtl::OUString rName ) const
145     throw( beans::UnknownPropertyException )
146 {
147     SfxItemPropertyHashMap_t::const_iterator aIter = m_pImpl->find(rName);
148     if( aIter == m_pImpl->end() )
149         throw UnknownPropertyException();
150     const SfxItemPropertySimpleEntry* pEntry = &aIter->second;
151     beans::Property aProp;
152     aProp.Name = rName;
153     aProp.Handle = pEntry->nWID;
154     if(pEntry->pType)
155         aProp.Type = *pEntry->pType;
156     aProp.Attributes = sal::static_int_cast< sal_Int16 >(pEntry->nFlags);
157     return aProp;
158 }
159 /*-- 16.02.2009 11:09:16---------------------------------------------------
160 
161   -----------------------------------------------------------------------*/
162 sal_Bool SfxItemPropertyMap::hasPropertyByName( const ::rtl::OUString& rName ) const
163 {
164     SfxItemPropertyHashMap_t::const_iterator aIter = m_pImpl->find(rName);
165     return aIter != m_pImpl->end();
166 }
167 /*-- 16.02.2009 11:25:14---------------------------------------------------
168 
169   -----------------------------------------------------------------------*/
170 void SfxItemPropertyMap::mergeProperties( const uno::Sequence< beans::Property >& rPropSeq )
171 {
172     const beans::Property* pPropArray = rPropSeq.getConstArray();
173     sal_uInt32 nElements = rPropSeq.getLength();
174     for( sal_uInt32 nElement = 0; nElement < nElements; ++nElement )
175     {
176         SfxItemPropertySimpleEntry aTemp(
177             sal::static_int_cast< sal_Int16 >( pPropArray[nElement].Handle ), //nWID
178             &pPropArray[nElement].Type, //pType
179             pPropArray[nElement].Attributes, //nFlags
180             0 ); //nMemberId
181         (*m_pImpl)[pPropArray[nElement].Name] = aTemp;
182     }
183 }
184 /*-- 18.02.2009 12:04:42---------------------------------------------------
185 
186   -----------------------------------------------------------------------*/
187 PropertyEntryVector_t SfxItemPropertyMap::getPropertyEntries() const
188 {
189     PropertyEntryVector_t aRet;
190     aRet.reserve(m_pImpl->size());
191 
192     SfxItemPropertyHashMap_t::const_iterator aIt = m_pImpl->begin();
193     while( aIt != m_pImpl->end() )
194     {
195         const SfxItemPropertySimpleEntry* pEntry = &(*aIt).second;
196         aRet.push_back( SfxItemPropertyNamedEntry( (*aIt).first, * pEntry ) );
197         ++aIt;
198     }
199     return aRet;
200 }
201 /*-- 18.02.2009 15:11:06---------------------------------------------------
202 
203   -----------------------------------------------------------------------*/
204 sal_uInt32 SfxItemPropertyMap::getSize() const
205 {
206     return m_pImpl->size();
207 }
208 /*-- 16.02.2009 13:44:54---------------------------------------------------
209 
210   -----------------------------------------------------------------------*/
211 SfxItemPropertySet::~SfxItemPropertySet()
212 {
213 }
214 /* -----------------------------21.02.00 11:26--------------------------------
215 
216  ---------------------------------------------------------------------------*/
217 sal_Bool SfxItemPropertySet::FillItem(SfxItemSet&, sal_uInt16, sal_Bool) const
218 {
219 	return sal_False;
220 }
221 /* -----------------------------06.06.01 12:32--------------------------------
222 
223  ---------------------------------------------------------------------------*/
224 void SfxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry& rEntry,
225 			const SfxItemSet& rSet, Any& rAny ) const
226 						throw(RuntimeException)
227 {
228     // get the SfxPoolItem
229     const SfxPoolItem* pItem = 0;
230     SfxItemState eState = rSet.GetItemState( rEntry.nWID, sal_True, &pItem );
231     if(SFX_ITEM_SET != eState && SFX_WHICH_MAX > rEntry.nWID )
232         pItem = &rSet.GetPool()->GetDefaultItem(rEntry.nWID);
233     // return item values as uno::Any
234     if(eState >= SFX_ITEM_DEFAULT && pItem)
235     {
236         pItem->QueryValue( rAny, rEntry.nMemberId );
237     }
238     else
239     {
240         SfxItemSet aSet(*rSet.GetPool(), rEntry.nWID, rEntry.nWID);
241         if(FillItem(aSet, rEntry.nWID, sal_True))
242         {
243             const SfxPoolItem& rItem = aSet.Get(rEntry.nWID);
244             rItem.QueryValue( rAny, rEntry.nMemberId );
245         }
246         else if(0 == (rEntry.nFlags & PropertyAttribute::MAYBEVOID))
247             throw RuntimeException();
248     }
249 
250 
251     // convert general SfxEnumItem values to specific values
252     if( rEntry.pType && TypeClass_ENUM == rEntry.pType->getTypeClass() &&
253          rAny.getValueTypeClass() == TypeClass_LONG )
254     {
255         sal_Int32 nTmp = *(sal_Int32*)rAny.getValue();
256         rAny.setValue( &nTmp, *rEntry.pType );
257     }
258 }
259 /* -----------------------------06.06.01 12:32--------------------------------
260 
261  ---------------------------------------------------------------------------*/
262 void SfxItemPropertySet::getPropertyValue( const rtl::OUString &rName,
263 			const SfxItemSet& rSet, Any& rAny ) const
264 						throw(RuntimeException, UnknownPropertyException)
265 {
266     // detect which-id
267     const SfxItemPropertySimpleEntry* pEntry = m_aMap.getByName( rName );
268     if ( !pEntry )
269 		throw UnknownPropertyException();
270     getPropertyValue( *pEntry,rSet, rAny );
271 }
272 /* -----------------------------21.02.00 11:26--------------------------------
273 
274  ---------------------------------------------------------------------------*/
275 Any SfxItemPropertySet::getPropertyValue( const rtl::OUString &rName,
276 			const SfxItemSet& rSet ) const
277 						throw(RuntimeException, UnknownPropertyException)
278 {
279 	Any aVal;
280 	getPropertyValue( rName,rSet, aVal );
281 	return aVal;
282 }
283 /* -----------------------------15.11.00 14:46--------------------------------
284 
285  ---------------------------------------------------------------------------*/
286 void SfxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry& rEntry,
287 											const Any& aVal,
288 											SfxItemSet& rSet ) const
289 											throw(RuntimeException,
290 													IllegalArgumentException)
291 {
292     // get the SfxPoolItem
293     const SfxPoolItem* pItem = 0;
294     SfxPoolItem *pNewItem = 0;
295     SfxItemState eState = rSet.GetItemState( rEntry.nWID, sal_True, &pItem );
296     if(SFX_ITEM_SET != eState && SFX_WHICH_MAX > rEntry.nWID )
297         pItem = &rSet.GetPool()->GetDefaultItem(rEntry.nWID);
298     //maybe there's another way to find an Item
299     if(eState < SFX_ITEM_DEFAULT)
300     {
301         SfxItemSet aSet(*rSet.GetPool(), rEntry.nWID, rEntry.nWID);
302         if(FillItem(aSet, rEntry.nWID, sal_False))
303         {
304             const SfxPoolItem &rItem = aSet.Get(rEntry.nWID);
305             pNewItem = rItem.Clone();
306         }
307     }
308     if(!pNewItem && pItem)
309     {
310         pNewItem = pItem->Clone();
311     }
312     if(pNewItem)
313     {
314         if( !pNewItem->PutValue( aVal, rEntry.nMemberId ) )
315         {
316             DELETEZ(pNewItem);
317             throw IllegalArgumentException();
318         }
319         // apply new item
320         rSet.Put( *pNewItem, rEntry.nWID );
321         delete pNewItem;
322     }
323 }
324 /* -----------------------------21.02.00 11:26--------------------------------
325 
326  ---------------------------------------------------------------------------*/
327 void SfxItemPropertySet::setPropertyValue( const rtl::OUString &rName,
328 											const Any& aVal,
329 											SfxItemSet& rSet ) const
330 											throw(RuntimeException,
331 													IllegalArgumentException,
332 													UnknownPropertyException)
333 {
334     const SfxItemPropertySimpleEntry* pEntry = m_aMap.getByName( rName );
335     if ( !pEntry )
336 	{
337 		throw UnknownPropertyException();
338 	}
339     setPropertyValue(*pEntry, aVal, rSet);
340 }
341 /* -----------------------------21.02.00 11:26--------------------------------
342 
343  ---------------------------------------------------------------------------*/
344 PropertyState SfxItemPropertySet::getPropertyState(const SfxItemPropertySimpleEntry& rEntry, const SfxItemSet& rSet) const
345                                     throw()
346 {
347 	PropertyState eRet = PropertyState_DIRECT_VALUE;
348     sal_uInt16 nWhich = rEntry.nWID;
349 
350 	// item state holen
351 	SfxItemState eState = rSet.GetItemState( nWhich, sal_False );
352 	// item-Wert als UnoAny zurueckgeben
353 	if(eState == SFX_ITEM_DEFAULT)
354 		eRet = PropertyState_DEFAULT_VALUE;
355 	else if(eState < SFX_ITEM_DEFAULT)
356 		eRet = PropertyState_AMBIGUOUS_VALUE;
357 	return eRet;
358 }
359 PropertyState   SfxItemPropertySet::getPropertyState(
360 	const rtl::OUString& rName, const SfxItemSet& rSet) const
361                                     throw(UnknownPropertyException)
362 {
363 	PropertyState eRet = PropertyState_DIRECT_VALUE;
364 
365 	// which-id ermitteln
366     const SfxItemPropertySimpleEntry* pEntry = m_aMap.getByName( rName );
367     if( !pEntry || !pEntry->nWID )
368 	{
369 		throw UnknownPropertyException();
370 	}
371     sal_uInt16 nWhich = pEntry->nWID;
372 
373 	// item holen
374 	const SfxPoolItem* pItem = 0;
375 	SfxItemState eState = rSet.GetItemState( nWhich, sal_False, &pItem );
376 	if(!pItem && nWhich != rSet.GetPool()->GetSlotId(nWhich))
377 		pItem = &rSet.GetPool()->GetDefaultItem(nWhich);
378 	// item-Wert als UnoAny zurueckgeben
379 	if(eState == SFX_ITEM_DEFAULT)
380 		eRet = PropertyState_DEFAULT_VALUE;
381 	else if(eState < SFX_ITEM_DEFAULT)
382 		eRet = PropertyState_AMBIGUOUS_VALUE;
383 	return eRet;
384 }
385 /* -----------------------------21.02.00 11:26--------------------------------
386 
387  ---------------------------------------------------------------------------*/
388 Reference<XPropertySetInfo>
389     SfxItemPropertySet::getPropertySetInfo() const
390 {
391     if( !m_xInfo.is() )
392         m_xInfo = new SfxItemPropertySetInfo( &m_aMap );
393     return m_xInfo;
394 }
395 /*-- 16.02.2009 13:49:25---------------------------------------------------
396 
397   -----------------------------------------------------------------------*/
398 struct SfxItemPropertySetInfo_Impl
399 {
400     SfxItemPropertyMap*         m_pOwnMap;
401 };
402 /*-- 16.02.2009 13:49:24---------------------------------------------------
403 
404   -----------------------------------------------------------------------*/
405 SfxItemPropertySetInfo::SfxItemPropertySetInfo(const SfxItemPropertyMap *pMap ) :
406     m_pImpl( new SfxItemPropertySetInfo_Impl )
407 {
408     m_pImpl->m_pOwnMap = new SfxItemPropertyMap( pMap );
409 }
410 /*-- 16.02.2009 13:49:25---------------------------------------------------
411 
412   -----------------------------------------------------------------------*/
413 SfxItemPropertySetInfo::SfxItemPropertySetInfo(const SfxItemPropertyMapEntry *pEntries ) :
414     m_pImpl( new SfxItemPropertySetInfo_Impl )
415 {
416     m_pImpl->m_pOwnMap = new SfxItemPropertyMap( pEntries );
417 }
418 /* -----------------------------21.02.00 11:09--------------------------------
419 
420  ---------------------------------------------------------------------------*/
421 Sequence< Property > SAL_CALL
422         SfxItemPropertySetInfo::getProperties(  )
423             throw(RuntimeException)
424 {
425     return m_pImpl->m_pOwnMap->getProperties();
426 }
427 /*-- 16.02.2009 13:49:27---------------------------------------------------
428 
429   -----------------------------------------------------------------------*/
430 const SfxItemPropertyMap* SfxItemPropertySetInfo::getMap() const
431 {
432     return m_pImpl->m_pOwnMap;
433 }
434 
435 /*-- 16.02.2009 12:43:36---------------------------------------------------
436 
437   -----------------------------------------------------------------------*/
438 SfxItemPropertySetInfo::~SfxItemPropertySetInfo()
439 {
440     delete m_pImpl->m_pOwnMap;
441     delete m_pImpl;
442 }
443 /* -----------------------------21.02.00 11:27--------------------------------
444 
445  ---------------------------------------------------------------------------*/
446 Property SAL_CALL
447 		SfxItemPropertySetInfo::getPropertyByName( const ::rtl::OUString& rName )
448 			throw(UnknownPropertyException, RuntimeException)
449 {
450     return m_pImpl->m_pOwnMap->getPropertyByName( rName );
451 }
452 /* -----------------------------21.02.00 11:28--------------------------------
453 
454  ---------------------------------------------------------------------------*/
455 sal_Bool SAL_CALL
456 		SfxItemPropertySetInfo::hasPropertyByName( const ::rtl::OUString& rName )
457 			throw(RuntimeException)
458 {
459     return m_pImpl->m_pOwnMap->hasPropertyByName( rName );
460 }
461 /* -----------------------------21.02.00 12:03--------------------------------
462 
463  ---------------------------------------------------------------------------*/
464 SfxExtItemPropertySetInfo::SfxExtItemPropertySetInfo(
465                                 const SfxItemPropertyMapEntry *pMap,
466 								const Sequence<Property>& rPropSeq ) :
467                 aExtMap( pMap )
468 {
469     aExtMap.mergeProperties( rPropSeq );
470 }
471 /*-- 16.02.2009 12:06:49---------------------------------------------------
472 
473   -----------------------------------------------------------------------*/
474 SfxExtItemPropertySetInfo::~SfxExtItemPropertySetInfo()
475 {
476 }
477 /* -----------------------------21.02.00 12:03--------------------------------
478 
479  ---------------------------------------------------------------------------*/
480 Sequence< Property > SAL_CALL
481 		SfxExtItemPropertySetInfo::getProperties(  ) throw(RuntimeException)
482 {
483     return aExtMap.getProperties();
484 }
485 /* -----------------------------21.02.00 12:03--------------------------------
486 
487  ---------------------------------------------------------------------------*/
488 Property SAL_CALL
489 SfxExtItemPropertySetInfo::getPropertyByName( const rtl::OUString& rPropertyName )
490 			throw(UnknownPropertyException, RuntimeException)
491 {
492     return aExtMap.getPropertyByName( rPropertyName );
493 }
494 /* -----------------------------21.02.00 12:03--------------------------------
495 
496  ---------------------------------------------------------------------------*/
497 sal_Bool SAL_CALL
498 SfxExtItemPropertySetInfo::hasPropertyByName( const rtl::OUString& rPropertyName )
499 			throw(RuntimeException)
500 {
501     return aExtMap.hasPropertyByName( rPropertyName );
502 }
503 
504