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 .
20 #include <sal/config.h>
22 #include <o3tl/any.hxx>
23 #include <svl/itemprop.hxx>
24 #include <svl/itempool.hxx>
25 #include <svl/itemset.hxx>
26 #include <com/sun/star/beans/PropertyAttribute.hpp>
28 #include <unordered_map>
30 * UNO III Implementation
32 using namespace com::sun::star
;
33 using namespace com::sun::star::beans
;
34 using namespace com::sun::star::lang
;
35 using namespace com::sun::star::uno
;
37 typedef std::unordered_map
< OUString
,
38 SfxItemPropertySimpleEntry
> SfxItemPropertyHashMap_t
;
40 class SfxItemPropertyMap_Impl
: public SfxItemPropertyHashMap_t
43 mutable uno::Sequence
< beans::Property
> m_aPropSeq
;
45 SfxItemPropertyMap_Impl(){}
46 explicit SfxItemPropertyMap_Impl( const SfxItemPropertyMap_Impl
* pSource
);
49 SfxItemPropertyMap_Impl::SfxItemPropertyMap_Impl( const SfxItemPropertyMap_Impl
* pSource
)
51 SfxItemPropertyHashMap_t::operator=( *pSource
);
52 m_aPropSeq
= pSource
->m_aPropSeq
;
55 SfxItemPropertyMap::SfxItemPropertyMap( const SfxItemPropertyMapEntry
* pEntries
) :
56 m_pImpl( new SfxItemPropertyMap_Impl
)
58 while( !pEntries
->aName
.isEmpty() )
60 (*m_pImpl
) [ pEntries
->aName
] = pEntries
;
65 SfxItemPropertyMap::SfxItemPropertyMap( const SfxItemPropertyMap
& rSource
) :
66 m_pImpl( new SfxItemPropertyMap_Impl( rSource
.m_pImpl
.get() ) )
70 SfxItemPropertyMap::~SfxItemPropertyMap()
74 const SfxItemPropertySimpleEntry
* SfxItemPropertyMap::getByName( const OUString
&rName
) const
76 SfxItemPropertyHashMap_t::const_iterator aIter
= m_pImpl
->find(rName
);
77 if( aIter
== m_pImpl
->end() )
79 return &aIter
->second
;
82 uno::Sequence
<beans::Property
> const & SfxItemPropertyMap::getProperties() const
84 if( !m_pImpl
->m_aPropSeq
.getLength() )
86 m_pImpl
->m_aPropSeq
.realloc( m_pImpl
->size() );
87 beans::Property
* pPropArray
= m_pImpl
->m_aPropSeq
.getArray();
89 for( const auto& rEntry
: *m_pImpl
)
90 //for ( const SfxItemPropertyMap *pMap = _pMap; pMap->pName; ++pMap )
92 const SfxItemPropertySimpleEntry
* pEntry
= &rEntry
.second
;
93 pPropArray
[n
].Name
= rEntry
.first
;
94 pPropArray
[n
].Handle
= pEntry
->nWID
;
95 pPropArray
[n
].Type
= pEntry
->aType
;
96 pPropArray
[n
].Attributes
=
97 sal::static_int_cast
< sal_Int16
>(pEntry
->nFlags
);
102 return m_pImpl
->m_aPropSeq
;
105 beans::Property
SfxItemPropertyMap::getPropertyByName( const OUString
& rName
) const
107 SfxItemPropertyHashMap_t::const_iterator aIter
= m_pImpl
->find(rName
);
108 if( aIter
== m_pImpl
->end() )
109 throw UnknownPropertyException();
110 const SfxItemPropertySimpleEntry
* pEntry
= &aIter
->second
;
111 beans::Property aProp
;
113 aProp
.Handle
= pEntry
->nWID
;
114 aProp
.Type
= pEntry
->aType
;
115 aProp
.Attributes
= sal::static_int_cast
< sal_Int16
>(pEntry
->nFlags
);
119 bool SfxItemPropertyMap::hasPropertyByName( const OUString
& rName
) const
121 SfxItemPropertyHashMap_t::const_iterator aIter
= m_pImpl
->find(rName
);
122 return aIter
!= m_pImpl
->end();
125 void SfxItemPropertyMap::mergeProperties( const uno::Sequence
< beans::Property
>& rPropSeq
)
127 const beans::Property
* pPropArray
= rPropSeq
.getConstArray();
128 sal_uInt32 nElements
= rPropSeq
.getLength();
129 for( sal_uInt32 nElement
= 0; nElement
< nElements
; ++nElement
)
131 SfxItemPropertySimpleEntry
aTemp(
132 sal::static_int_cast
< sal_Int16
>( pPropArray
[nElement
].Handle
), //nWID
133 pPropArray
[nElement
].Type
, //aType
134 pPropArray
[nElement
].Attributes
); //nFlags
135 (*m_pImpl
)[pPropArray
[nElement
].Name
] = aTemp
;
139 PropertyEntryVector_t
SfxItemPropertyMap::getPropertyEntries() const
141 PropertyEntryVector_t aRet
;
142 aRet
.reserve(m_pImpl
->size());
144 for( const auto& rEntry
: *m_pImpl
)
146 const SfxItemPropertySimpleEntry
* pEntry
= &rEntry
.second
;
147 aRet
.emplace_back( rEntry
.first
, * pEntry
);
152 sal_uInt32
SfxItemPropertyMap::getSize() const
154 return m_pImpl
->size();
157 SfxItemPropertySet::~SfxItemPropertySet()
161 void SfxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry
& rEntry
,
162 const SfxItemSet
& rSet
, Any
& rAny
) const
164 // get the SfxPoolItem
165 const SfxPoolItem
* pItem
= nullptr;
166 SfxItemState eState
= rSet
.GetItemState( rEntry
.nWID
, true, &pItem
);
167 if (SfxItemState::SET
!= eState
&& SfxItemPool::IsWhich(rEntry
.nWID
) )
168 pItem
= &rSet
.GetPool()->GetDefaultItem(rEntry
.nWID
);
169 // return item values as uno::Any
170 if(eState
>= SfxItemState::DEFAULT
&& pItem
)
172 pItem
->QueryValue( rAny
, rEntry
.nMemberId
);
174 else if(0 == (rEntry
.nFlags
& PropertyAttribute::MAYBEVOID
))
176 throw RuntimeException(
177 "Property not found in ItemSet but not MAYBEVOID?", nullptr);
180 // convert general SfxEnumItem values to specific values
181 if( rEntry
.aType
.getTypeClass() == TypeClass_ENUM
&&
182 rAny
.getValueTypeClass() == TypeClass_LONG
)
184 sal_Int32 nTmp
= *o3tl::forceAccess
<sal_Int32
>(rAny
);
185 rAny
.setValue( &nTmp
, rEntry
.aType
);
189 void SfxItemPropertySet::getPropertyValue( const OUString
&rName
,
190 const SfxItemSet
& rSet
, Any
& rAny
) const
193 const SfxItemPropertySimpleEntry
* pEntry
= m_aMap
.getByName( rName
);
195 throw UnknownPropertyException();
196 getPropertyValue( *pEntry
,rSet
, rAny
);
199 Any
SfxItemPropertySet::getPropertyValue( const OUString
&rName
,
200 const SfxItemSet
& rSet
) const
203 getPropertyValue( rName
,rSet
, aVal
);
207 void SfxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry
& rEntry
,
209 SfxItemSet
& rSet
) const
211 // get the SfxPoolItem
212 const SfxPoolItem
* pItem
= nullptr;
213 std::unique_ptr
<SfxPoolItem
> pNewItem
;
214 SfxItemState eState
= rSet
.GetItemState( rEntry
.nWID
, true, &pItem
);
215 if (SfxItemState::SET
!= eState
&& SfxItemPool::IsWhich(rEntry
.nWID
))
216 pItem
= &rSet
.GetPool()->GetDefaultItem(rEntry
.nWID
);
219 pNewItem
.reset(pItem
->Clone());
223 if( !pNewItem
->PutValue( aVal
, rEntry
.nMemberId
) )
225 throw IllegalArgumentException();
228 rSet
.Put( *pNewItem
);
232 void SfxItemPropertySet::setPropertyValue( const OUString
&rName
,
234 SfxItemSet
& rSet
) const
236 const SfxItemPropertySimpleEntry
* pEntry
= m_aMap
.getByName( rName
);
239 throw UnknownPropertyException();
241 setPropertyValue(*pEntry
, aVal
, rSet
);
244 PropertyState
SfxItemPropertySet::getPropertyState(const SfxItemPropertySimpleEntry
& rEntry
, const SfxItemSet
& rSet
) const
247 PropertyState eRet
= PropertyState_DIRECT_VALUE
;
248 sal_uInt16 nWhich
= rEntry
.nWID
;
251 SfxItemState eState
= rSet
.GetItemState( nWhich
, false );
252 // Return item value as UnoAny
253 if(eState
== SfxItemState::DEFAULT
)
254 eRet
= PropertyState_DEFAULT_VALUE
;
255 else if(eState
< SfxItemState::DEFAULT
)
256 eRet
= PropertyState_AMBIGUOUS_VALUE
;
260 PropertyState
SfxItemPropertySet::getPropertyState(const OUString
& rName
, const SfxItemSet
& rSet
) const
262 PropertyState eRet
= PropertyState_DIRECT_VALUE
;
265 const SfxItemPropertySimpleEntry
* pEntry
= m_aMap
.getByName( rName
);
266 if( !pEntry
|| !pEntry
->nWID
)
268 throw UnknownPropertyException();
270 sal_uInt16 nWhich
= pEntry
->nWID
;
273 SfxItemState eState
= rSet
.GetItemState(nWhich
, false);
274 // Return item value as UnoAny
275 if(eState
== SfxItemState::DEFAULT
)
276 eRet
= PropertyState_DEFAULT_VALUE
;
277 else if(eState
< SfxItemState::DEFAULT
)
278 eRet
= PropertyState_AMBIGUOUS_VALUE
;
282 Reference
<XPropertySetInfo
> const & SfxItemPropertySet::getPropertySetInfo() const
285 m_xInfo
= new SfxItemPropertySetInfo( m_aMap
);
289 SfxItemPropertySetInfo::SfxItemPropertySetInfo(const SfxItemPropertyMap
&rMap
)
294 SfxItemPropertySetInfo::SfxItemPropertySetInfo(const SfxItemPropertyMapEntry
*pEntries
)
295 : m_aOwnMap( pEntries
)
299 Sequence
< Property
> SAL_CALL
SfxItemPropertySetInfo::getProperties( )
301 return m_aOwnMap
.getProperties();
304 SfxItemPropertySetInfo::~SfxItemPropertySetInfo()
308 Property SAL_CALL
SfxItemPropertySetInfo::getPropertyByName( const OUString
& rName
)
310 return m_aOwnMap
.getPropertyByName( rName
);
313 sal_Bool SAL_CALL
SfxItemPropertySetInfo::hasPropertyByName( const OUString
& rName
)
315 return m_aOwnMap
.hasPropertyByName( rName
);
318 SfxExtItemPropertySetInfo::SfxExtItemPropertySetInfo( const SfxItemPropertyMapEntry
*pMap
,
319 const Sequence
<Property
>& rPropSeq
)
322 aExtMap
.mergeProperties( rPropSeq
);
325 SfxExtItemPropertySetInfo::~SfxExtItemPropertySetInfo()
329 Sequence
< Property
> SAL_CALL
SfxExtItemPropertySetInfo::getProperties( )
331 return aExtMap
.getProperties();
334 Property SAL_CALL
SfxExtItemPropertySetInfo::getPropertyByName( const OUString
& rPropertyName
)
336 return aExtMap
.getPropertyByName( rPropertyName
);
339 sal_Bool SAL_CALL
SfxExtItemPropertySetInfo::hasPropertyByName( const OUString
& rPropertyName
)
341 return aExtMap
.hasPropertyByName( rPropertyName
);
344 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */