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/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;
33 :
34 : struct equalOUString
35 : {
36 2915122 : bool operator()(const OUString& r1, const OUString& r2) const
37 : {
38 2915122 : return r1.equals( r2 );
39 : }
40 : };
41 :
42 : typedef ::boost::unordered_map< OUString,
43 : SfxItemPropertySimpleEntry,
44 : OUStringHash,
45 : equalOUString > SfxItemPropertyHashMap_t;
46 :
47 22260 : class SfxItemPropertyMap_Impl : public SfxItemPropertyHashMap_t
48 : {
49 : public:
50 : mutable uno::Sequence< beans::Property > m_aPropSeq;
51 :
52 22052 : SfxItemPropertyMap_Impl(){}
53 : SfxItemPropertyMap_Impl( const SfxItemPropertyMap_Impl* pSource );
54 : };
55 :
56 842 : SfxItemPropertyMap_Impl::SfxItemPropertyMap_Impl( const SfxItemPropertyMap_Impl* pSource )
57 : {
58 842 : this->SfxItemPropertyHashMap_t::operator=( *pSource );
59 842 : m_aPropSeq = pSource->m_aPropSeq;
60 842 : }
61 :
62 22052 : SfxItemPropertyMap::SfxItemPropertyMap( const SfxItemPropertyMapEntry* pEntries ) :
63 22052 : m_pImpl( new SfxItemPropertyMap_Impl )
64 : {
65 696593 : while( !pEntries->aName.isEmpty() )
66 : {
67 652489 : (*m_pImpl) [ pEntries->aName ] = pEntries;
68 652489 : ++pEntries;
69 : }
70 22052 : }
71 :
72 842 : SfxItemPropertyMap::SfxItemPropertyMap( const SfxItemPropertyMap& rSource ) :
73 842 : m_pImpl( new SfxItemPropertyMap_Impl( rSource.m_pImpl ) )
74 : {
75 842 : }
76 :
77 22260 : SfxItemPropertyMap::~SfxItemPropertyMap()
78 : {
79 22260 : delete m_pImpl;
80 22260 : }
81 :
82 2768324 : const SfxItemPropertySimpleEntry* SfxItemPropertyMap::getByName( const OUString &rName ) const
83 : {
84 2768324 : SfxItemPropertyHashMap_t::const_iterator aIter = m_pImpl->find(rName);
85 2768324 : if( aIter == m_pImpl->end() )
86 115389 : return 0;
87 2652935 : return &aIter->second;
88 : }
89 :
90 15526 : uno::Sequence<beans::Property> SfxItemPropertyMap::getProperties() const
91 : {
92 15526 : if( !m_pImpl->m_aPropSeq.getLength() )
93 : {
94 290 : m_pImpl->m_aPropSeq.realloc( m_pImpl->size() );
95 290 : beans::Property* pPropArray = m_pImpl->m_aPropSeq.getArray();
96 290 : sal_uInt32 n = 0;
97 290 : SfxItemPropertyHashMap_t::const_iterator aIt = m_pImpl->begin();
98 24591 : while( aIt != m_pImpl->end() )
99 : //for ( const SfxItemPropertyMap *pMap = _pMap; pMap->pName; ++pMap )
100 : {
101 24011 : const SfxItemPropertySimpleEntry* pEntry = &(*aIt).second;
102 24011 : pPropArray[n].Name = (*aIt).first;
103 24011 : pPropArray[n].Handle = pEntry->nWID;
104 24011 : pPropArray[n].Type = pEntry->aType;
105 24011 : pPropArray[n].Attributes =
106 24011 : sal::static_int_cast< sal_Int16 >(pEntry->nFlags);
107 24011 : n++;
108 24011 : ++aIt;
109 : }
110 : }
111 :
112 15526 : return m_pImpl->m_aPropSeq;
113 : }
114 :
115 2227 : beans::Property SfxItemPropertyMap::getPropertyByName( const OUString & rName ) const
116 : throw( beans::UnknownPropertyException )
117 : {
118 2227 : SfxItemPropertyHashMap_t::const_iterator aIter = m_pImpl->find(rName);
119 2227 : if( aIter == m_pImpl->end() )
120 3 : throw UnknownPropertyException();
121 2224 : const SfxItemPropertySimpleEntry* pEntry = &aIter->second;
122 2224 : beans::Property aProp;
123 2224 : aProp.Name = rName;
124 2224 : aProp.Handle = pEntry->nWID;
125 2224 : aProp.Type = pEntry->aType;
126 2224 : aProp.Attributes = sal::static_int_cast< sal_Int16 >(pEntry->nFlags);
127 2224 : return aProp;
128 : }
129 :
130 396363 : bool SfxItemPropertyMap::hasPropertyByName( const OUString& rName ) const
131 : {
132 396363 : SfxItemPropertyHashMap_t::const_iterator aIter = m_pImpl->find(rName);
133 396363 : return aIter != m_pImpl->end();
134 : }
135 :
136 15220 : void SfxItemPropertyMap::mergeProperties( const uno::Sequence< beans::Property >& rPropSeq )
137 : {
138 15220 : const beans::Property* pPropArray = rPropSeq.getConstArray();
139 15220 : sal_uInt32 nElements = rPropSeq.getLength();
140 2572991 : for( sal_uInt32 nElement = 0; nElement < nElements; ++nElement )
141 : {
142 : SfxItemPropertySimpleEntry aTemp(
143 2557771 : sal::static_int_cast< sal_Int16 >( pPropArray[nElement].Handle ), //nWID
144 2557771 : pPropArray[nElement].Type, //aType
145 2557771 : pPropArray[nElement].Attributes, //nFlags
146 7673313 : 0 ); //nMemberId
147 2557771 : (*m_pImpl)[pPropArray[nElement].Name] = aTemp;
148 2557771 : }
149 15220 : }
150 :
151 23496 : PropertyEntryVector_t SfxItemPropertyMap::getPropertyEntries() const
152 : {
153 23496 : PropertyEntryVector_t aRet;
154 23496 : aRet.reserve(m_pImpl->size());
155 :
156 23496 : SfxItemPropertyHashMap_t::const_iterator aIt = m_pImpl->begin();
157 1055546 : while( aIt != m_pImpl->end() )
158 : {
159 1008554 : const SfxItemPropertySimpleEntry* pEntry = &(*aIt).second;
160 1008554 : aRet.push_back( SfxItemPropertyNamedEntry( (*aIt).first, * pEntry ) );
161 1008554 : ++aIt;
162 : }
163 23496 : return aRet;
164 : }
165 :
166 0 : sal_uInt32 SfxItemPropertyMap::getSize() const
167 : {
168 0 : return m_pImpl->size();
169 : }
170 :
171 5524 : SfxItemPropertySet::~SfxItemPropertySet()
172 : {
173 5524 : }
174 :
175 14 : bool SfxItemPropertySet::FillItem(SfxItemSet&, sal_uInt16, bool) const
176 : {
177 14 : return false;
178 : }
179 :
180 32707 : void SfxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry& rEntry,
181 : const SfxItemSet& rSet, Any& rAny ) const
182 : throw(RuntimeException)
183 : {
184 : // get the SfxPoolItem
185 32707 : const SfxPoolItem* pItem = 0;
186 32707 : SfxItemState eState = rSet.GetItemState( rEntry.nWID, true, &pItem );
187 32707 : if(SFX_ITEM_SET != eState && SFX_WHICH_MAX > rEntry.nWID )
188 4349 : pItem = &rSet.GetPool()->GetDefaultItem(rEntry.nWID);
189 : // return item values as uno::Any
190 32707 : if(eState >= SFX_ITEM_DEFAULT && pItem)
191 : {
192 32702 : pItem->QueryValue( rAny, rEntry.nMemberId );
193 : }
194 : else
195 : {
196 5 : SfxItemSet aSet(*rSet.GetPool(), rEntry.nWID, rEntry.nWID);
197 5 : if(FillItem(aSet, rEntry.nWID, true))
198 : {
199 0 : const SfxPoolItem& rItem = aSet.Get(rEntry.nWID);
200 0 : rItem.QueryValue( rAny, rEntry.nMemberId );
201 : }
202 5 : else if(0 == (rEntry.nFlags & PropertyAttribute::MAYBEVOID))
203 : throw RuntimeException(
204 2 : "Property not found in ItemSet but not MAYBEVOID?", 0);
205 : }
206 :
207 :
208 : // convert general SfxEnumItem values to specific values
209 38817 : if( rEntry.aType.getTypeClass() == TypeClass_ENUM &&
210 6112 : rAny.getValueTypeClass() == TypeClass_LONG )
211 : {
212 0 : sal_Int32 nTmp = *(sal_Int32*)rAny.getValue();
213 0 : rAny.setValue( &nTmp, rEntry.aType );
214 : }
215 32705 : }
216 :
217 800 : void SfxItemPropertySet::getPropertyValue( const OUString &rName,
218 : const SfxItemSet& rSet, Any& rAny ) const
219 : throw(RuntimeException, UnknownPropertyException)
220 : {
221 : // detect which-id
222 800 : const SfxItemPropertySimpleEntry* pEntry = m_aMap.getByName( rName );
223 800 : if ( !pEntry )
224 0 : throw UnknownPropertyException();
225 800 : getPropertyValue( *pEntry,rSet, rAny );
226 800 : }
227 :
228 44 : Any SfxItemPropertySet::getPropertyValue( const OUString &rName,
229 : const SfxItemSet& rSet ) const
230 : throw(RuntimeException, UnknownPropertyException)
231 : {
232 44 : Any aVal;
233 44 : getPropertyValue( rName,rSet, aVal );
234 44 : return aVal;
235 : }
236 :
237 444570 : void SfxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry& rEntry,
238 : const Any& aVal,
239 : SfxItemSet& rSet ) const
240 : throw(RuntimeException,
241 : IllegalArgumentException)
242 : {
243 : // get the SfxPoolItem
244 444570 : const SfxPoolItem* pItem = 0;
245 444570 : SfxPoolItem *pNewItem = 0;
246 444570 : SfxItemState eState = rSet.GetItemState( rEntry.nWID, true, &pItem );
247 444570 : if(SFX_ITEM_SET != eState && SFX_WHICH_MAX > rEntry.nWID )
248 170072 : pItem = &rSet.GetPool()->GetDefaultItem(rEntry.nWID);
249 : //maybe there's another way to find an Item
250 444570 : if(eState < SFX_ITEM_DEFAULT)
251 : {
252 9 : SfxItemSet aSet(*rSet.GetPool(), rEntry.nWID, rEntry.nWID);
253 9 : if(FillItem(aSet, rEntry.nWID, false))
254 : {
255 0 : const SfxPoolItem &rItem = aSet.Get(rEntry.nWID);
256 0 : pNewItem = rItem.Clone();
257 9 : }
258 : }
259 444570 : if(!pNewItem && pItem)
260 : {
261 419474 : pNewItem = pItem->Clone();
262 : }
263 444570 : if(pNewItem)
264 : {
265 419474 : if( !pNewItem->PutValue( aVal, rEntry.nMemberId ) )
266 : {
267 9 : DELETEZ(pNewItem);
268 9 : throw IllegalArgumentException();
269 : }
270 : // apply new item
271 419465 : rSet.Put( *pNewItem, rEntry.nWID );
272 419465 : delete pNewItem;
273 : }
274 444561 : }
275 :
276 73957 : void SfxItemPropertySet::setPropertyValue( const OUString &rName,
277 : const Any& aVal,
278 : SfxItemSet& rSet ) const
279 : throw(RuntimeException,
280 : IllegalArgumentException,
281 : UnknownPropertyException)
282 : {
283 73957 : const SfxItemPropertySimpleEntry* pEntry = m_aMap.getByName( rName );
284 73957 : if ( !pEntry )
285 : {
286 0 : throw UnknownPropertyException();
287 : }
288 73957 : setPropertyValue(*pEntry, aVal, rSet);
289 73957 : }
290 :
291 41825 : PropertyState SfxItemPropertySet::getPropertyState(const SfxItemPropertySimpleEntry& rEntry, const SfxItemSet& rSet) const
292 : throw()
293 : {
294 41825 : PropertyState eRet = PropertyState_DIRECT_VALUE;
295 41825 : sal_uInt16 nWhich = rEntry.nWID;
296 :
297 : // item state holen
298 41825 : SfxItemState eState = rSet.GetItemState( nWhich, false );
299 : // item-Wert als UnoAny zurueckgeben
300 41825 : if(eState == SFX_ITEM_DEFAULT)
301 32367 : eRet = PropertyState_DEFAULT_VALUE;
302 9458 : else if(eState < SFX_ITEM_DEFAULT)
303 334 : eRet = PropertyState_AMBIGUOUS_VALUE;
304 41825 : return eRet;
305 : }
306 :
307 852 : PropertyState SfxItemPropertySet::getPropertyState(const OUString& rName, const SfxItemSet& rSet) const
308 : throw(UnknownPropertyException)
309 : {
310 852 : PropertyState eRet = PropertyState_DIRECT_VALUE;
311 :
312 : // which-id ermitteln
313 852 : const SfxItemPropertySimpleEntry* pEntry = m_aMap.getByName( rName );
314 852 : if( !pEntry || !pEntry->nWID )
315 : {
316 0 : throw UnknownPropertyException();
317 : }
318 852 : sal_uInt16 nWhich = pEntry->nWID;
319 :
320 : // get item state
321 852 : SfxItemState eState = rSet.GetItemState(nWhich, false);
322 : // item-Wert als UnoAny zurueckgeben
323 852 : if(eState == SFX_ITEM_DEFAULT)
324 788 : eRet = PropertyState_DEFAULT_VALUE;
325 64 : else if(eState < SFX_ITEM_DEFAULT)
326 0 : eRet = PropertyState_AMBIGUOUS_VALUE;
327 852 : return eRet;
328 : }
329 :
330 4652 : Reference<XPropertySetInfo> SfxItemPropertySet::getPropertySetInfo() const
331 : {
332 4652 : if( !m_xInfo.is() )
333 469 : m_xInfo = new SfxItemPropertySetInfo( m_aMap );
334 4652 : return m_xInfo;
335 : }
336 :
337 : struct SfxItemPropertySetInfo_Impl
338 : {
339 : SfxItemPropertyMap* m_pOwnMap;
340 : };
341 :
342 842 : SfxItemPropertySetInfo::SfxItemPropertySetInfo(const SfxItemPropertyMap &rMap )
343 842 : : m_pImpl( new SfxItemPropertySetInfo_Impl )
344 : {
345 842 : m_pImpl->m_pOwnMap = new SfxItemPropertyMap( rMap );
346 842 : }
347 :
348 51 : SfxItemPropertySetInfo::SfxItemPropertySetInfo(const SfxItemPropertyMapEntry *pEntries )
349 51 : : m_pImpl( new SfxItemPropertySetInfo_Impl )
350 : {
351 51 : m_pImpl->m_pOwnMap = new SfxItemPropertyMap( pEntries );
352 51 : }
353 :
354 15503 : Sequence< Property > SAL_CALL SfxItemPropertySetInfo::getProperties( )
355 : throw(RuntimeException, std::exception)
356 : {
357 15503 : return m_pImpl->m_pOwnMap->getProperties();
358 : }
359 :
360 2649 : SfxItemPropertySetInfo::~SfxItemPropertySetInfo()
361 : {
362 883 : delete m_pImpl->m_pOwnMap;
363 883 : delete m_pImpl;
364 1766 : }
365 :
366 2015 : Property SAL_CALL SfxItemPropertySetInfo::getPropertyByName( const OUString& rName )
367 : throw(UnknownPropertyException, RuntimeException, std::exception)
368 : {
369 2015 : return m_pImpl->m_pOwnMap->getPropertyByName( rName );
370 : }
371 :
372 357195 : sal_Bool SAL_CALL SfxItemPropertySetInfo::hasPropertyByName( const OUString& rName )
373 : throw(RuntimeException, std::exception)
374 : {
375 357195 : return m_pImpl->m_pOwnMap->hasPropertyByName( rName );
376 : }
377 :
378 15220 : SfxExtItemPropertySetInfo::SfxExtItemPropertySetInfo( const SfxItemPropertyMapEntry *pMap,
379 : const Sequence<Property>& rPropSeq )
380 15220 : : aExtMap( pMap )
381 : {
382 15220 : aExtMap.mergeProperties( rPropSeq );
383 15220 : }
384 :
385 30342 : SfxExtItemPropertySetInfo::~SfxExtItemPropertySetInfo()
386 : {
387 30342 : }
388 :
389 23 : Sequence< Property > SAL_CALL SfxExtItemPropertySetInfo::getProperties( ) throw(RuntimeException, std::exception)
390 : {
391 23 : return aExtMap.getProperties();
392 : }
393 :
394 212 : Property SAL_CALL SfxExtItemPropertySetInfo::getPropertyByName( const OUString& rPropertyName )
395 : throw(UnknownPropertyException, RuntimeException, std::exception)
396 : {
397 212 : return aExtMap.getPropertyByName( rPropertyName );
398 : }
399 :
400 39168 : sal_Bool SAL_CALL SfxExtItemPropertySetInfo::hasPropertyByName( const OUString& rPropertyName )
401 : throw(RuntimeException, std::exception)
402 : {
403 39168 : return aExtMap.hasPropertyByName( rPropertyName );
404 : }
405 :
406 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|