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