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