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 <svl/itemprop.hxx>
22 : #include <svl/itempool.hxx>
23 : #include <svl/itemset.hxx>
24 : #include <com/sun/star/beans/PropertyAttribute.hpp>
25 : #include <boost/scoped_ptr.hpp>
26 : #include <boost/unordered_map.hpp>
27 : /*
28 : * UNO III Implementation
29 : */
30 : using namespace com::sun::star;
31 : using namespace com::sun::star::beans;
32 : using namespace com::sun::star::lang;
33 : using namespace com::sun::star::uno;
34 :
35 : struct equalOUString
36 : {
37 9592352 : bool operator()(const OUString& r1, const OUString& r2) const
38 : {
39 9592352 : return r1.equals( r2 );
40 : }
41 : };
42 :
43 : typedef ::boost::unordered_map< OUString,
44 : SfxItemPropertySimpleEntry,
45 : OUStringHash,
46 : equalOUString > SfxItemPropertyHashMap_t;
47 :
48 84685 : class SfxItemPropertyMap_Impl : public SfxItemPropertyHashMap_t
49 : {
50 : public:
51 : mutable uno::Sequence< beans::Property > m_aPropSeq;
52 :
53 82824 : SfxItemPropertyMap_Impl(){}
54 : SfxItemPropertyMap_Impl( const SfxItemPropertyMap_Impl* pSource );
55 : };
56 :
57 2248 : SfxItemPropertyMap_Impl::SfxItemPropertyMap_Impl( const SfxItemPropertyMap_Impl* pSource )
58 : {
59 2248 : this->SfxItemPropertyHashMap_t::operator=( *pSource );
60 2248 : m_aPropSeq = pSource->m_aPropSeq;
61 2248 : }
62 :
63 82824 : SfxItemPropertyMap::SfxItemPropertyMap( const SfxItemPropertyMapEntry* pEntries ) :
64 82824 : m_pImpl( new SfxItemPropertyMap_Impl )
65 : {
66 2986518 : while( !pEntries->aName.isEmpty() )
67 : {
68 2820870 : (*m_pImpl) [ pEntries->aName ] = pEntries;
69 2820870 : ++pEntries;
70 : }
71 82824 : }
72 :
73 2248 : SfxItemPropertyMap::SfxItemPropertyMap( const SfxItemPropertyMap& rSource ) :
74 2248 : m_pImpl( new SfxItemPropertyMap_Impl( rSource.m_pImpl ) )
75 : {
76 2248 : }
77 :
78 84685 : SfxItemPropertyMap::~SfxItemPropertyMap()
79 : {
80 84685 : delete m_pImpl;
81 84685 : }
82 :
83 9187199 : const SfxItemPropertySimpleEntry* SfxItemPropertyMap::getByName( const OUString &rName ) const
84 : {
85 9187199 : SfxItemPropertyHashMap_t::const_iterator aIter = m_pImpl->find(rName);
86 9187199 : if( aIter == m_pImpl->end() )
87 403903 : return 0;
88 8783296 : return &aIter->second;
89 : }
90 :
91 86378 : uno::Sequence<beans::Property> SfxItemPropertyMap::getProperties() const
92 : {
93 86378 : if( !m_pImpl->m_aPropSeq.getLength() )
94 : {
95 836 : m_pImpl->m_aPropSeq.realloc( m_pImpl->size() );
96 836 : beans::Property* pPropArray = m_pImpl->m_aPropSeq.getArray();
97 836 : sal_uInt32 n = 0;
98 836 : SfxItemPropertyHashMap_t::const_iterator aIt = m_pImpl->begin();
99 80706 : while( aIt != m_pImpl->end() )
100 : //for ( const SfxItemPropertyMap *pMap = _pMap; pMap->pName; ++pMap )
101 : {
102 79034 : const SfxItemPropertySimpleEntry* pEntry = &(*aIt).second;
103 79034 : pPropArray[n].Name = (*aIt).first;
104 79034 : pPropArray[n].Handle = pEntry->nWID;
105 79034 : pPropArray[n].Type = pEntry->aType;
106 79034 : pPropArray[n].Attributes =
107 79034 : sal::static_int_cast< sal_Int16 >(pEntry->nFlags);
108 79034 : n++;
109 79034 : ++aIt;
110 : }
111 : }
112 :
113 86378 : return m_pImpl->m_aPropSeq;
114 : }
115 :
116 4480 : beans::Property SfxItemPropertyMap::getPropertyByName( const OUString & rName ) const
117 : throw( beans::UnknownPropertyException )
118 : {
119 4480 : SfxItemPropertyHashMap_t::const_iterator aIter = m_pImpl->find(rName);
120 4480 : if( aIter == m_pImpl->end() )
121 6 : throw UnknownPropertyException();
122 4474 : const SfxItemPropertySimpleEntry* pEntry = &aIter->second;
123 4474 : beans::Property aProp;
124 4474 : aProp.Name = rName;
125 4474 : aProp.Handle = pEntry->nWID;
126 4474 : aProp.Type = pEntry->aType;
127 4474 : aProp.Attributes = sal::static_int_cast< sal_Int16 >(pEntry->nFlags);
128 4474 : return aProp;
129 : }
130 :
131 1177662 : bool SfxItemPropertyMap::hasPropertyByName( const OUString& rName ) const
132 : {
133 1177662 : SfxItemPropertyHashMap_t::const_iterator aIter = m_pImpl->find(rName);
134 1177662 : return aIter != m_pImpl->end();
135 : }
136 :
137 66758 : void SfxItemPropertyMap::mergeProperties( const uno::Sequence< beans::Property >& rPropSeq )
138 : {
139 66758 : const beans::Property* pPropArray = rPropSeq.getConstArray();
140 66758 : sal_uInt32 nElements = rPropSeq.getLength();
141 11248044 : for( sal_uInt32 nElement = 0; nElement < nElements; ++nElement )
142 : {
143 : SfxItemPropertySimpleEntry aTemp(
144 11181286 : sal::static_int_cast< sal_Int16 >( pPropArray[nElement].Handle ), //nWID
145 11181286 : pPropArray[nElement].Type, //aType
146 11181286 : pPropArray[nElement].Attributes, //nFlags
147 33543858 : 0 ); //nMemberId
148 11181286 : (*m_pImpl)[pPropArray[nElement].Name] = aTemp;
149 11181286 : }
150 66758 : }
151 :
152 74642 : PropertyEntryVector_t SfxItemPropertyMap::getPropertyEntries() const
153 : {
154 74642 : PropertyEntryVector_t aRet;
155 74642 : aRet.reserve(m_pImpl->size());
156 :
157 74642 : SfxItemPropertyHashMap_t::const_iterator aIt = m_pImpl->begin();
158 5010518 : while( aIt != m_pImpl->end() )
159 : {
160 4861234 : const SfxItemPropertySimpleEntry* pEntry = &(*aIt).second;
161 4861234 : aRet.push_back( SfxItemPropertyNamedEntry( (*aIt).first, * pEntry ) );
162 4861234 : ++aIt;
163 : }
164 74642 : return aRet;
165 : }
166 :
167 0 : sal_uInt32 SfxItemPropertyMap::getSize() const
168 : {
169 0 : return m_pImpl->size();
170 : }
171 :
172 13864 : SfxItemPropertySet::~SfxItemPropertySet()
173 : {
174 13864 : }
175 :
176 28 : bool SfxItemPropertySet::FillItem(SfxItemSet&, sal_uInt16, bool) const
177 : {
178 28 : return false;
179 : }
180 :
181 99292 : void SfxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry& rEntry,
182 : const SfxItemSet& rSet, Any& rAny ) const
183 : throw(RuntimeException)
184 : {
185 : // get the SfxPoolItem
186 99292 : const SfxPoolItem* pItem = 0;
187 99292 : SfxItemState eState = rSet.GetItemState( rEntry.nWID, true, &pItem );
188 99292 : if(SfxItemState::SET != eState && SFX_WHICH_MAX > rEntry.nWID )
189 10610 : pItem = &rSet.GetPool()->GetDefaultItem(rEntry.nWID);
190 : // return item values as uno::Any
191 99292 : if(eState >= SfxItemState::DEFAULT && pItem)
192 : {
193 99282 : pItem->QueryValue( rAny, rEntry.nMemberId );
194 : }
195 : else
196 : {
197 10 : SfxItemSet aSet(*rSet.GetPool(), rEntry.nWID, rEntry.nWID);
198 10 : if(FillItem(aSet, rEntry.nWID, true))
199 : {
200 0 : const SfxPoolItem& rItem = aSet.Get(rEntry.nWID);
201 0 : rItem.QueryValue( rAny, rEntry.nMemberId );
202 : }
203 10 : else if(0 == (rEntry.nFlags & PropertyAttribute::MAYBEVOID))
204 : throw RuntimeException(
205 4 : "Property not found in ItemSet but not MAYBEVOID?", 0);
206 : }
207 :
208 :
209 : // convert general SfxEnumItem values to specific values
210 119112 : if( rEntry.aType.getTypeClass() == TypeClass_ENUM &&
211 19824 : rAny.getValueTypeClass() == TypeClass_LONG )
212 : {
213 4 : sal_Int32 nTmp = *(sal_Int32*)rAny.getValue();
214 4 : rAny.setValue( &nTmp, rEntry.aType );
215 : }
216 99288 : }
217 :
218 1788 : void SfxItemPropertySet::getPropertyValue( const OUString &rName,
219 : const SfxItemSet& rSet, Any& rAny ) const
220 : throw(RuntimeException, UnknownPropertyException)
221 : {
222 : // detect which-id
223 1788 : const SfxItemPropertySimpleEntry* pEntry = m_aMap.getByName( rName );
224 1788 : if ( !pEntry )
225 0 : throw UnknownPropertyException();
226 1788 : getPropertyValue( *pEntry,rSet, rAny );
227 1788 : }
228 :
229 88 : Any SfxItemPropertySet::getPropertyValue( const OUString &rName,
230 : const SfxItemSet& rSet ) const
231 : throw(RuntimeException, UnknownPropertyException)
232 : {
233 88 : Any aVal;
234 88 : getPropertyValue( rName,rSet, aVal );
235 88 : return aVal;
236 : }
237 :
238 1244072 : void SfxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry& rEntry,
239 : const Any& aVal,
240 : SfxItemSet& rSet ) const
241 : throw(RuntimeException,
242 : IllegalArgumentException)
243 : {
244 : // get the SfxPoolItem
245 1244072 : const SfxPoolItem* pItem = 0;
246 1244072 : boost::scoped_ptr<SfxPoolItem> pNewItem;
247 1244072 : SfxItemState eState = rSet.GetItemState( rEntry.nWID, true, &pItem );
248 1244072 : if(SfxItemState::SET != eState && SFX_WHICH_MAX > rEntry.nWID )
249 493090 : pItem = &rSet.GetPool()->GetDefaultItem(rEntry.nWID);
250 : //maybe there's another way to find an Item
251 1244072 : if(eState < SfxItemState::DEFAULT)
252 : {
253 18 : SfxItemSet aSet(*rSet.GetPool(), rEntry.nWID, rEntry.nWID);
254 18 : if(FillItem(aSet, rEntry.nWID, false))
255 : {
256 0 : const SfxPoolItem &rItem = aSet.Get(rEntry.nWID);
257 0 : pNewItem.reset(rItem.Clone());
258 18 : }
259 : }
260 1244072 : if(!pNewItem && pItem)
261 : {
262 1162086 : pNewItem.reset(pItem->Clone());
263 : }
264 1244072 : if(pNewItem)
265 : {
266 1162086 : if( !pNewItem->PutValue( aVal, rEntry.nMemberId ) )
267 : {
268 162 : throw IllegalArgumentException();
269 : }
270 : // apply new item
271 1161924 : rSet.Put( *pNewItem, rEntry.nWID );
272 1244072 : }
273 1243910 : }
274 :
275 172570 : void SfxItemPropertySet::setPropertyValue( const OUString &rName,
276 : const Any& aVal,
277 : SfxItemSet& rSet ) const
278 : throw(RuntimeException,
279 : IllegalArgumentException,
280 : UnknownPropertyException)
281 : {
282 172570 : const SfxItemPropertySimpleEntry* pEntry = m_aMap.getByName( rName );
283 172570 : if ( !pEntry )
284 : {
285 0 : throw UnknownPropertyException();
286 : }
287 172570 : setPropertyValue(*pEntry, aVal, rSet);
288 172570 : }
289 :
290 3211136 : PropertyState SfxItemPropertySet::getPropertyState(const SfxItemPropertySimpleEntry& rEntry, const SfxItemSet& rSet) const
291 : throw()
292 : {
293 3211136 : PropertyState eRet = PropertyState_DIRECT_VALUE;
294 3211136 : sal_uInt16 nWhich = rEntry.nWID;
295 :
296 : // Get item state
297 3211136 : SfxItemState eState = rSet.GetItemState( nWhich, false );
298 : // Return item value as UnoAny
299 3211136 : if(eState == SfxItemState::DEFAULT)
300 2986608 : eRet = PropertyState_DEFAULT_VALUE;
301 224528 : else if(eState < SfxItemState::DEFAULT)
302 114368 : eRet = PropertyState_AMBIGUOUS_VALUE;
303 3211136 : return eRet;
304 : }
305 :
306 2500 : PropertyState SfxItemPropertySet::getPropertyState(const OUString& rName, const SfxItemSet& rSet) const
307 : throw(UnknownPropertyException)
308 : {
309 2500 : PropertyState eRet = PropertyState_DIRECT_VALUE;
310 :
311 : // Get WhichId
312 2500 : const SfxItemPropertySimpleEntry* pEntry = m_aMap.getByName( rName );
313 2500 : if( !pEntry || !pEntry->nWID )
314 : {
315 0 : throw UnknownPropertyException();
316 : }
317 2500 : sal_uInt16 nWhich = pEntry->nWID;
318 :
319 : // Get item state
320 2500 : SfxItemState eState = rSet.GetItemState(nWhich, false);
321 : // Return item value as UnoAny
322 2500 : if(eState == SfxItemState::DEFAULT)
323 2400 : eRet = PropertyState_DEFAULT_VALUE;
324 100 : else if(eState < SfxItemState::DEFAULT)
325 0 : eRet = PropertyState_AMBIGUOUS_VALUE;
326 2500 : return eRet;
327 : }
328 :
329 12232 : Reference<XPropertySetInfo> SfxItemPropertySet::getPropertySetInfo() const
330 : {
331 12232 : if( !m_xInfo.is() )
332 1286 : m_xInfo = new SfxItemPropertySetInfo( m_aMap );
333 12232 : return m_xInfo;
334 : }
335 :
336 : struct SfxItemPropertySetInfo_Impl
337 : {
338 : SfxItemPropertyMap* m_pOwnMap;
339 : };
340 :
341 2248 : SfxItemPropertySetInfo::SfxItemPropertySetInfo(const SfxItemPropertyMap &rMap )
342 2248 : : m_pImpl( new SfxItemPropertySetInfo_Impl )
343 : {
344 2248 : m_pImpl->m_pOwnMap = new SfxItemPropertyMap( rMap );
345 2248 : }
346 :
347 118 : SfxItemPropertySetInfo::SfxItemPropertySetInfo(const SfxItemPropertyMapEntry *pEntries )
348 118 : : m_pImpl( new SfxItemPropertySetInfo_Impl )
349 : {
350 118 : m_pImpl->m_pOwnMap = new SfxItemPropertyMap( pEntries );
351 118 : }
352 :
353 86332 : Sequence< Property > SAL_CALL SfxItemPropertySetInfo::getProperties( )
354 : throw(RuntimeException, std::exception)
355 : {
356 86332 : return m_pImpl->m_pOwnMap->getProperties();
357 : }
358 :
359 7038 : SfxItemPropertySetInfo::~SfxItemPropertySetInfo()
360 : {
361 2346 : delete m_pImpl->m_pOwnMap;
362 2346 : delete m_pImpl;
363 4692 : }
364 :
365 4056 : Property SAL_CALL SfxItemPropertySetInfo::getPropertyByName( const OUString& rName )
366 : throw(UnknownPropertyException, RuntimeException, std::exception)
367 : {
368 4056 : return m_pImpl->m_pOwnMap->getPropertyByName( rName );
369 : }
370 :
371 1035156 : sal_Bool SAL_CALL SfxItemPropertySetInfo::hasPropertyByName( const OUString& rName )
372 : throw(RuntimeException, std::exception)
373 : {
374 1035156 : return m_pImpl->m_pOwnMap->hasPropertyByName( rName );
375 : }
376 :
377 66758 : SfxExtItemPropertySetInfo::SfxExtItemPropertySetInfo( const SfxItemPropertyMapEntry *pMap,
378 : const Sequence<Property>& rPropSeq )
379 66758 : : aExtMap( pMap )
380 : {
381 66758 : aExtMap.mergeProperties( rPropSeq );
382 66758 : }
383 :
384 133248 : SfxExtItemPropertySetInfo::~SfxExtItemPropertySetInfo()
385 : {
386 133248 : }
387 :
388 46 : Sequence< Property > SAL_CALL SfxExtItemPropertySetInfo::getProperties( ) throw(RuntimeException, std::exception)
389 : {
390 46 : return aExtMap.getProperties();
391 : }
392 :
393 424 : Property SAL_CALL SfxExtItemPropertySetInfo::getPropertyByName( const OUString& rPropertyName )
394 : throw(UnknownPropertyException, RuntimeException, std::exception)
395 : {
396 424 : return aExtMap.getPropertyByName( rPropertyName );
397 : }
398 :
399 142506 : sal_Bool SAL_CALL SfxExtItemPropertySetInfo::hasPropertyByName( const OUString& rPropertyName )
400 : throw(RuntimeException, std::exception)
401 : {
402 142506 : return aExtMap.hasPropertyByName( rPropertyName );
403 : }
404 :
405 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|