1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <svl/itemprop.hxx>
22 #include <svl/itempool.hxx>
23 #include <svl/itemset.hxx>
24 #include <com/sun/star/beans/PropertyAttribute.hpp>
25 #include <boost/unordered_map.hpp>
26 /*************************************************************************
27 UNO III Implementation
28 *************************************************************************/
29 using namespace com::sun::star
;
30 using namespace com::sun::star::beans
;
31 using namespace com::sun::star::lang
;
32 using namespace com::sun::star::uno
;
36 bool operator()(const OUString
& r1
, const OUString
& r2
) const
38 return r1
.equals( r2
);
42 typedef ::boost::unordered_map
< OUString
,
43 SfxItemPropertySimpleEntry
,
45 equalOUString
> SfxItemPropertyHashMap_t
;
47 class SfxItemPropertyMap_Impl
: public SfxItemPropertyHashMap_t
50 mutable uno::Sequence
< beans::Property
> m_aPropSeq
;
52 SfxItemPropertyMap_Impl(){}
53 SfxItemPropertyMap_Impl( const SfxItemPropertyMap_Impl
* pSource
);
56 SfxItemPropertyMap_Impl::SfxItemPropertyMap_Impl( const SfxItemPropertyMap_Impl
* pSource
)
58 this->SfxItemPropertyHashMap_t::operator=( *pSource
);
59 m_aPropSeq
= pSource
->m_aPropSeq
;
62 SfxItemPropertyMap::SfxItemPropertyMap( const SfxItemPropertyMapEntry
* pEntries
) :
63 m_pImpl( new SfxItemPropertyMap_Impl
)
65 while( pEntries
->pName
)
67 OUString
sEntry(pEntries
->pName
, pEntries
->nNameLen
, RTL_TEXTENCODING_ASCII_US
);
68 (*m_pImpl
) [ sEntry
] = pEntries
;
73 SfxItemPropertyMap::SfxItemPropertyMap( const SfxItemPropertyMap
& rSource
) :
74 m_pImpl( new SfxItemPropertyMap_Impl( rSource
.m_pImpl
) )
78 SfxItemPropertyMap::~SfxItemPropertyMap()
83 const SfxItemPropertySimpleEntry
* SfxItemPropertyMap::getByName( const OUString
&rName
) const
85 SfxItemPropertyHashMap_t::const_iterator aIter
= m_pImpl
->find(rName
);
86 if( aIter
== m_pImpl
->end() )
88 return &aIter
->second
;
91 uno::Sequence
<beans::Property
> SfxItemPropertyMap::getProperties() const
93 if( !m_pImpl
->m_aPropSeq
.getLength() )
95 m_pImpl
->m_aPropSeq
.realloc( m_pImpl
->size() );
96 beans::Property
* pPropArray
= m_pImpl
->m_aPropSeq
.getArray();
98 SfxItemPropertyHashMap_t::const_iterator aIt
= m_pImpl
->begin();
99 while( aIt
!= m_pImpl
->end() )
100 //for ( const SfxItemPropertyMap *pMap = _pMap; pMap->pName; ++pMap )
102 const SfxItemPropertySimpleEntry
* pEntry
= &(*aIt
).second
;
103 pPropArray
[n
].Name
= (*aIt
).first
;
104 pPropArray
[n
].Handle
= pEntry
->nWID
;
106 pPropArray
[n
].Type
= *pEntry
->pType
;
107 pPropArray
[n
].Attributes
=
108 sal::static_int_cast
< sal_Int16
>(pEntry
->nFlags
);
114 return m_pImpl
->m_aPropSeq
;
117 beans::Property
SfxItemPropertyMap::getPropertyByName( const OUString rName
) const
118 throw( beans::UnknownPropertyException
)
120 SfxItemPropertyHashMap_t::const_iterator aIter
= m_pImpl
->find(rName
);
121 if( aIter
== m_pImpl
->end() )
122 throw UnknownPropertyException();
123 const SfxItemPropertySimpleEntry
* pEntry
= &aIter
->second
;
124 beans::Property aProp
;
126 aProp
.Handle
= pEntry
->nWID
;
128 aProp
.Type
= *pEntry
->pType
;
129 aProp
.Attributes
= sal::static_int_cast
< sal_Int16
>(pEntry
->nFlags
);
133 bool SfxItemPropertyMap::hasPropertyByName( const OUString
& rName
) const
135 SfxItemPropertyHashMap_t::const_iterator aIter
= m_pImpl
->find(rName
);
136 return aIter
!= m_pImpl
->end();
139 void SfxItemPropertyMap::mergeProperties( const uno::Sequence
< beans::Property
>& rPropSeq
)
141 const beans::Property
* pPropArray
= rPropSeq
.getConstArray();
142 sal_uInt32 nElements
= rPropSeq
.getLength();
143 for( sal_uInt32 nElement
= 0; nElement
< nElements
; ++nElement
)
145 SfxItemPropertySimpleEntry
aTemp(
146 sal::static_int_cast
< sal_Int16
>( pPropArray
[nElement
].Handle
), //nWID
147 &pPropArray
[nElement
].Type
, //pType
148 pPropArray
[nElement
].Attributes
, //nFlags
150 (*m_pImpl
)[pPropArray
[nElement
].Name
] = aTemp
;
154 PropertyEntryVector_t
SfxItemPropertyMap::getPropertyEntries() const
156 PropertyEntryVector_t aRet
;
157 aRet
.reserve(m_pImpl
->size());
159 SfxItemPropertyHashMap_t::const_iterator aIt
= m_pImpl
->begin();
160 while( aIt
!= m_pImpl
->end() )
162 const SfxItemPropertySimpleEntry
* pEntry
= &(*aIt
).second
;
163 aRet
.push_back( SfxItemPropertyNamedEntry( (*aIt
).first
, * pEntry
) );
169 sal_uInt32
SfxItemPropertyMap::getSize() const
171 return m_pImpl
->size();
174 SfxItemPropertySet::~SfxItemPropertySet()
178 sal_Bool
SfxItemPropertySet::FillItem(SfxItemSet
&, sal_uInt16
, sal_Bool
) const
183 void SfxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry
& rEntry
,
184 const SfxItemSet
& rSet
, Any
& rAny
) const
185 throw(RuntimeException
)
187 // get the SfxPoolItem
188 const SfxPoolItem
* pItem
= 0;
189 SfxItemState eState
= rSet
.GetItemState( rEntry
.nWID
, sal_True
, &pItem
);
190 if(SFX_ITEM_SET
!= eState
&& SFX_WHICH_MAX
> rEntry
.nWID
)
191 pItem
= &rSet
.GetPool()->GetDefaultItem(rEntry
.nWID
);
192 // return item values as uno::Any
193 if(eState
>= SFX_ITEM_DEFAULT
&& pItem
)
195 pItem
->QueryValue( rAny
, rEntry
.nMemberId
);
199 SfxItemSet
aSet(*rSet
.GetPool(), rEntry
.nWID
, rEntry
.nWID
);
200 if(FillItem(aSet
, rEntry
.nWID
, sal_True
))
202 const SfxPoolItem
& rItem
= aSet
.Get(rEntry
.nWID
);
203 rItem
.QueryValue( rAny
, rEntry
.nMemberId
);
205 else if(0 == (rEntry
.nFlags
& PropertyAttribute::MAYBEVOID
))
206 throw RuntimeException(
207 "Property not found in ItemSet but not MAYBEVOID?", 0);
211 // convert general SfxEnumItem values to specific values
212 if( rEntry
.pType
&& TypeClass_ENUM
== rEntry
.pType
->getTypeClass() &&
213 rAny
.getValueTypeClass() == TypeClass_LONG
)
215 sal_Int32 nTmp
= *(sal_Int32
*)rAny
.getValue();
216 rAny
.setValue( &nTmp
, *rEntry
.pType
);
220 void SfxItemPropertySet::getPropertyValue( const OUString
&rName
,
221 const SfxItemSet
& rSet
, Any
& rAny
) const
222 throw(RuntimeException
, UnknownPropertyException
)
225 const SfxItemPropertySimpleEntry
* pEntry
= m_aMap
.getByName( rName
);
227 throw UnknownPropertyException();
228 getPropertyValue( *pEntry
,rSet
, rAny
);
231 Any
SfxItemPropertySet::getPropertyValue( const OUString
&rName
,
232 const SfxItemSet
& rSet
) const
233 throw(RuntimeException
, UnknownPropertyException
)
236 getPropertyValue( rName
,rSet
, aVal
);
240 void SfxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry
& rEntry
,
242 SfxItemSet
& rSet
) const
243 throw(RuntimeException
,
244 IllegalArgumentException
)
246 // get the SfxPoolItem
247 const SfxPoolItem
* pItem
= 0;
248 SfxPoolItem
*pNewItem
= 0;
249 SfxItemState eState
= rSet
.GetItemState( rEntry
.nWID
, sal_True
, &pItem
);
250 if(SFX_ITEM_SET
!= eState
&& SFX_WHICH_MAX
> rEntry
.nWID
)
251 pItem
= &rSet
.GetPool()->GetDefaultItem(rEntry
.nWID
);
252 //maybe there's another way to find an Item
253 if(eState
< SFX_ITEM_DEFAULT
)
255 SfxItemSet
aSet(*rSet
.GetPool(), rEntry
.nWID
, rEntry
.nWID
);
256 if(FillItem(aSet
, rEntry
.nWID
, sal_False
))
258 const SfxPoolItem
&rItem
= aSet
.Get(rEntry
.nWID
);
259 pNewItem
= rItem
.Clone();
262 if(!pNewItem
&& pItem
)
264 pNewItem
= pItem
->Clone();
268 if( !pNewItem
->PutValue( aVal
, rEntry
.nMemberId
) )
271 throw IllegalArgumentException();
274 rSet
.Put( *pNewItem
, rEntry
.nWID
);
279 void SfxItemPropertySet::setPropertyValue( const OUString
&rName
,
281 SfxItemSet
& rSet
) const
282 throw(RuntimeException
,
283 IllegalArgumentException
,
284 UnknownPropertyException
)
286 const SfxItemPropertySimpleEntry
* pEntry
= m_aMap
.getByName( rName
);
289 throw UnknownPropertyException();
291 setPropertyValue(*pEntry
, aVal
, rSet
);
294 PropertyState
SfxItemPropertySet::getPropertyState(const SfxItemPropertySimpleEntry
& rEntry
, const SfxItemSet
& rSet
) const
297 PropertyState eRet
= PropertyState_DIRECT_VALUE
;
298 sal_uInt16 nWhich
= rEntry
.nWID
;
301 SfxItemState eState
= rSet
.GetItemState( nWhich
, sal_False
);
302 // item-Wert als UnoAny zurueckgeben
303 if(eState
== SFX_ITEM_DEFAULT
)
304 eRet
= PropertyState_DEFAULT_VALUE
;
305 else if(eState
< SFX_ITEM_DEFAULT
)
306 eRet
= PropertyState_AMBIGUOUS_VALUE
;
310 PropertyState
SfxItemPropertySet::getPropertyState(const OUString
& rName
, const SfxItemSet
& rSet
) const
311 throw(UnknownPropertyException
)
313 PropertyState eRet
= PropertyState_DIRECT_VALUE
;
315 // which-id ermitteln
316 const SfxItemPropertySimpleEntry
* pEntry
= m_aMap
.getByName( rName
);
317 if( !pEntry
|| !pEntry
->nWID
)
319 throw UnknownPropertyException();
321 sal_uInt16 nWhich
= pEntry
->nWID
;
324 const SfxPoolItem
* pItem
= 0;
325 SfxItemState eState
= rSet
.GetItemState( nWhich
, sal_False
, &pItem
);
326 if(!pItem
&& nWhich
!= rSet
.GetPool()->GetSlotId(nWhich
))
327 pItem
= &rSet
.GetPool()->GetDefaultItem(nWhich
);
328 // item-Wert als UnoAny zurueckgeben
329 if(eState
== SFX_ITEM_DEFAULT
)
330 eRet
= PropertyState_DEFAULT_VALUE
;
331 else if(eState
< SFX_ITEM_DEFAULT
)
332 eRet
= PropertyState_AMBIGUOUS_VALUE
;
336 Reference
<XPropertySetInfo
> SfxItemPropertySet::getPropertySetInfo() const
339 m_xInfo
= new SfxItemPropertySetInfo( m_aMap
);
343 struct SfxItemPropertySetInfo_Impl
345 SfxItemPropertyMap
* m_pOwnMap
;
348 SfxItemPropertySetInfo::SfxItemPropertySetInfo(const SfxItemPropertyMap
&rMap
)
349 : m_pImpl( new SfxItemPropertySetInfo_Impl
)
351 m_pImpl
->m_pOwnMap
= new SfxItemPropertyMap( rMap
);
354 SfxItemPropertySetInfo::SfxItemPropertySetInfo(const SfxItemPropertyMapEntry
*pEntries
)
355 : m_pImpl( new SfxItemPropertySetInfo_Impl
)
357 m_pImpl
->m_pOwnMap
= new SfxItemPropertyMap( pEntries
);
360 Sequence
< Property
> SAL_CALL
SfxItemPropertySetInfo::getProperties( )
361 throw(RuntimeException
)
363 return m_pImpl
->m_pOwnMap
->getProperties();
366 SfxItemPropertySetInfo::~SfxItemPropertySetInfo()
368 delete m_pImpl
->m_pOwnMap
;
372 Property SAL_CALL
SfxItemPropertySetInfo::getPropertyByName( const OUString
& rName
)
373 throw(UnknownPropertyException
, RuntimeException
)
375 return m_pImpl
->m_pOwnMap
->getPropertyByName( rName
);
378 sal_Bool SAL_CALL
SfxItemPropertySetInfo::hasPropertyByName( const OUString
& rName
)
379 throw(RuntimeException
)
381 return m_pImpl
->m_pOwnMap
->hasPropertyByName( rName
);
384 SfxExtItemPropertySetInfo::SfxExtItemPropertySetInfo( const SfxItemPropertyMapEntry
*pMap
,
385 const Sequence
<Property
>& rPropSeq
)
388 aExtMap
.mergeProperties( rPropSeq
);
391 SfxExtItemPropertySetInfo::~SfxExtItemPropertySetInfo()
395 Sequence
< Property
> SAL_CALL
SfxExtItemPropertySetInfo::getProperties( ) throw(RuntimeException
)
397 return aExtMap
.getProperties();
400 Property SAL_CALL
SfxExtItemPropertySetInfo::getPropertyByName( const OUString
& rPropertyName
)
401 throw(UnknownPropertyException
, RuntimeException
)
403 return aExtMap
.getPropertyByName( rPropertyName
);
406 sal_Bool SAL_CALL
SfxExtItemPropertySetInfo::hasPropertyByName( const OUString
& rPropertyName
)
407 throw(RuntimeException
)
409 return aExtMap
.hasPropertyByName( rPropertyName
);
412 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */