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