Bump for 3.6-28
[LibreOffice.git] / editeng / source / uno / unoipset.cxx
bloba99ee1afd2f5a829712a560dcc2ee564c6922305
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include <com/sun/star/beans/XPropertySet.hpp>
30 #include <svl/eitem.hxx>
32 #include <boost/unordered_map.hpp>
33 #include <svl/itemprop.hxx>
35 #include <editeng/unoipset.hxx>
36 #include <editeng/editids.hrc>
37 #include <editeng/editeng.hxx>
38 #include <svl/itempool.hxx>
39 #include <algorithm>
41 using namespace ::com::sun::star;
42 using namespace ::rtl;
44 using ::std::vector;
46 //----------------------------------------------------------------------
48 struct SfxItemPropertyMapEntryHash
50 size_t operator()(const SfxItemPropertyMapEntry* pMap) const { return (size_t)pMap; }
53 //----------------------------------------------------------------------
55 struct SvxIDPropertyCombine
57 sal_uInt16 nWID;
58 uno::Any aAny;
62 SvxItemPropertySet::SvxItemPropertySet( const SfxItemPropertyMapEntry* pMap, SfxItemPool& rItemPool, sal_Bool bConvertTwips )
63 : m_aPropertyMap( pMap ),
64 _pMap(pMap), mbConvertTwips(bConvertTwips), mrItemPool( rItemPool )
68 //----------------------------------------------------------------------
69 SvxItemPropertySet::~SvxItemPropertySet()
71 ClearAllUsrAny();
74 //----------------------------------------------------------------------
75 uno::Any* SvxItemPropertySet::GetUsrAnyForID(sal_uInt16 nWID) const
77 for ( size_t i = 0, n = aCombineList.size(); i < n; ++i )
79 SvxIDPropertyCombine* pActual = aCombineList[ i ];
80 if( pActual->nWID == nWID )
81 return &pActual->aAny;
83 return NULL;
86 //----------------------------------------------------------------------
87 void SvxItemPropertySet::AddUsrAnyForID(const uno::Any& rAny, sal_uInt16 nWID)
89 SvxIDPropertyCombine* pNew = new SvxIDPropertyCombine;
90 pNew->nWID = nWID;
91 pNew->aAny = rAny;
92 aCombineList.push_back( pNew );
95 //----------------------------------------------------------------------
97 void SvxItemPropertySet::ClearAllUsrAny()
99 for ( size_t i = 0, n = aCombineList.size(); i < n; ++i )
100 delete aCombineList[ i ];
101 aCombineList.clear();
104 //----------------------------------------------------------------------
106 sal_Bool SvxUnoCheckForPositiveValue( const uno::Any& rVal )
108 sal_Bool bConvert = sal_True; // the default is that all metric items must be converted
109 sal_Int32 nValue = 0;
110 if( rVal >>= nValue )
111 bConvert = (nValue > 0);
112 return bConvert;
116 //----------------------------------------------------------------------
117 uno::Any SvxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry* pMap, const SfxItemSet& rSet, bool bSearchInParent, bool bDontConvertNegativeValues ) const
119 uno::Any aVal;
120 if(!pMap || !pMap->nWID)
121 return aVal;
123 const SfxPoolItem* pItem = 0;
124 SfxItemPool* pPool = rSet.GetPool();
125 rSet.GetItemState( pMap->nWID, bSearchInParent, &pItem );
126 if( NULL == pItem && pPool )
127 pItem = &(pPool->GetDefaultItem( pMap->nWID ));
129 const SfxMapUnit eMapUnit = pPool ? pPool->GetMetric((sal_uInt16)pMap->nWID) : SFX_MAPUNIT_100TH_MM;
130 sal_uInt8 nMemberId = pMap->nMemberId & (~SFX_METRIC_ITEM);
131 if( eMapUnit == SFX_MAPUNIT_100TH_MM )
132 nMemberId &= (~CONVERT_TWIPS);
134 if(pItem)
136 pItem->QueryValue( aVal, nMemberId );
137 if( pMap->nMemberId & SFX_METRIC_ITEM )
139 if( eMapUnit != SFX_MAPUNIT_100TH_MM )
141 if ( !bDontConvertNegativeValues || SvxUnoCheckForPositiveValue( aVal ) )
142 SvxUnoConvertToMM( eMapUnit, aVal );
145 else if ( pMap->pType->getTypeClass() == uno::TypeClass_ENUM &&
146 aVal.getValueType() == ::getCppuType((const sal_Int32*)0) )
148 // convert typeless SfxEnumItem to enum type
149 sal_Int32 nEnum;
150 aVal >>= nEnum;
151 aVal.setValue( &nEnum, *pMap->pType );
154 else
156 OSL_FAIL( "No SfxPoolItem found for property!" );
159 return aVal;
162 //----------------------------------------------------------------------
163 void SvxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry* pMap, const uno::Any& rVal, SfxItemSet& rSet, bool bDontConvertNegativeValues ) const
165 if(!pMap || !pMap->nWID)
166 return;
168 // Get item
169 const SfxPoolItem* pItem = 0;
170 SfxPoolItem *pNewItem = 0;
171 SfxItemState eState = rSet.GetItemState( pMap->nWID, sal_True, &pItem );
172 SfxItemPool* pPool = rSet.GetPool();
174 // Put UnoAny in the item value
175 if(eState < SFX_ITEM_DEFAULT || pItem == NULL)
177 if( pPool == NULL )
179 OSL_FAIL( "No default item and no pool?" );
180 return;
183 pItem = &pPool->GetDefaultItem( pMap->nWID );
186 DBG_ASSERT( pItem, "Got no default for item!" );
187 if( pItem )
189 uno::Any aValue( rVal );
191 const SfxMapUnit eMapUnit = pPool ? pPool->GetMetric((sal_uInt16)pMap->nWID) : SFX_MAPUNIT_100TH_MM;
193 // check for needed metric translation
194 if( (pMap->nMemberId & SFX_METRIC_ITEM) && eMapUnit != SFX_MAPUNIT_100TH_MM )
196 if ( !bDontConvertNegativeValues || SvxUnoCheckForPositiveValue( aValue ) )
197 SvxUnoConvertFromMM( eMapUnit, aValue );
200 pNewItem = pItem->Clone();
202 sal_uInt8 nMemberId = pMap->nMemberId & (~SFX_METRIC_ITEM);
203 if( eMapUnit == SFX_MAPUNIT_100TH_MM )
204 nMemberId &= (~CONVERT_TWIPS);
206 if( pNewItem->PutValue( aValue, nMemberId ) )
208 // Set new item in item set
209 rSet.Put( *pNewItem, pMap->nWID );
211 delete pNewItem;
215 //----------------------------------------------------------------------
216 uno::Any SvxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry* pMap ) const
218 // Already entered a value? Then finish quickly
219 uno::Any* pUsrAny = GetUsrAnyForID(pMap->nWID);
220 if(pUsrAny)
221 return *pUsrAny;
223 // No UsrAny detected yet, generate Default entry and return this
224 const SfxMapUnit eMapUnit = mrItemPool.GetMetric((sal_uInt16)pMap->nWID);
225 sal_uInt8 nMemberId = pMap->nMemberId & (~SFX_METRIC_ITEM);
226 if( eMapUnit == SFX_MAPUNIT_100TH_MM )
227 nMemberId &= (~CONVERT_TWIPS);
228 uno::Any aVal;
229 SfxItemSet aSet( mrItemPool, pMap->nWID, pMap->nWID);
231 if( (pMap->nWID < OWN_ATTR_VALUE_START) && (pMap->nWID > OWN_ATTR_VALUE_END ) )
233 // Get Default from ItemPool
234 if(mrItemPool.IsWhich(pMap->nWID))
235 aSet.Put(mrItemPool.GetDefaultItem(pMap->nWID));
238 if(aSet.Count())
240 const SfxPoolItem* pItem = NULL;
241 SfxItemState eState = aSet.GetItemState( pMap->nWID, sal_True, &pItem );
242 if(eState >= SFX_ITEM_DEFAULT && pItem)
244 pItem->QueryValue( aVal, nMemberId );
245 ((SvxItemPropertySet*)this)->AddUsrAnyForID(aVal, pMap->nWID);
249 if( pMap->nMemberId & SFX_METRIC_ITEM )
251 // check for needed metric translation
252 if(pMap->nMemberId & SFX_METRIC_ITEM && eMapUnit != SFX_MAPUNIT_100TH_MM)
254 SvxUnoConvertToMM( eMapUnit, aVal );
258 if ( pMap->pType->getTypeClass() == uno::TypeClass_ENUM &&
259 aVal.getValueType() == ::getCppuType((const sal_Int32*)0) )
261 sal_Int32 nEnum;
262 aVal >>= nEnum;
264 aVal.setValue( &nEnum, *pMap->pType );
267 return aVal;
270 //----------------------------------------------------------------------
272 void SvxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry* pMap, const uno::Any& rVal ) const
274 uno::Any* pUsrAny = GetUsrAnyForID(pMap->nWID);
275 if(!pUsrAny)
276 ((SvxItemPropertySet*)this)->AddUsrAnyForID(rVal, pMap->nWID);
277 else
278 *pUsrAny = rVal;
281 //----------------------------------------------------------------------
283 const SfxItemPropertySimpleEntry* SvxItemPropertySet::getPropertyMapEntry(const OUString &rName) const
285 return m_aPropertyMap.getByName( rName );
288 //----------------------------------------------------------------------
290 uno::Reference< beans::XPropertySetInfo > SvxItemPropertySet::getPropertySetInfo() const
292 if( !m_xInfo.is() )
293 m_xInfo = new SfxItemPropertySetInfo( m_aPropertyMap );
294 return m_xInfo;
297 //----------------------------------------------------------------------
299 #ifndef TWIPS_TO_MM
300 #define TWIPS_TO_MM(val) ((val * 127 + 36) / 72)
301 #endif
302 #ifndef MM_TO_TWIPS
303 #define MM_TO_TWIPS(val) ((val * 72 + 63) / 127)
304 #endif
306 /** converts the given any with a metric to 100th/mm if needed */
307 void SvxUnoConvertToMM( const SfxMapUnit eSourceMapUnit, uno::Any & rMetric ) throw()
309 // map the metric of the itempool to 100th mm
310 switch(eSourceMapUnit)
312 case SFX_MAPUNIT_TWIP :
314 switch( rMetric.getValueTypeClass() )
316 case uno::TypeClass_BYTE:
317 rMetric <<= (sal_Int8)(TWIPS_TO_MM(*(sal_Int8*)rMetric.getValue()));
318 break;
319 case uno::TypeClass_SHORT:
320 rMetric <<= (sal_Int16)(TWIPS_TO_MM(*(sal_Int16*)rMetric.getValue()));
321 break;
322 case uno::TypeClass_UNSIGNED_SHORT:
323 rMetric <<= (sal_uInt16)(TWIPS_TO_MM(*(sal_uInt16*)rMetric.getValue()));
324 break;
325 case uno::TypeClass_LONG:
326 rMetric <<= (sal_Int32)(TWIPS_TO_MM(*(sal_Int32*)rMetric.getValue()));
327 break;
328 case uno::TypeClass_UNSIGNED_LONG:
329 rMetric <<= (sal_uInt32)(TWIPS_TO_MM(*(sal_uInt32*)rMetric.getValue()));
330 break;
331 default:
332 OSL_FAIL("AW: Missing unit translation to 100th mm!");
334 break;
336 default:
338 OSL_FAIL("AW: Missing unit translation to 100th mm!");
343 //----------------------------------------------------------------------
345 /** converts the given any with a metric from 100th/mm to the given metric if needed */
346 void SvxUnoConvertFromMM( const SfxMapUnit eDestinationMapUnit, uno::Any & rMetric ) throw()
348 switch(eDestinationMapUnit)
350 case SFX_MAPUNIT_TWIP :
352 switch( rMetric.getValueTypeClass() )
354 case uno::TypeClass_BYTE:
355 rMetric <<= (sal_Int8)(MM_TO_TWIPS(*(sal_Int8*)rMetric.getValue()));
356 break;
357 case uno::TypeClass_SHORT:
358 rMetric <<= (sal_Int16)(MM_TO_TWIPS(*(sal_Int16*)rMetric.getValue()));
359 break;
360 case uno::TypeClass_UNSIGNED_SHORT:
361 rMetric <<= (sal_uInt16)(MM_TO_TWIPS(*(sal_uInt16*)rMetric.getValue()));
362 break;
363 case uno::TypeClass_LONG:
364 rMetric <<= (sal_Int32)(MM_TO_TWIPS(*(sal_Int32*)rMetric.getValue()));
365 break;
366 case uno::TypeClass_UNSIGNED_LONG:
367 rMetric <<= (sal_uInt32)(MM_TO_TWIPS(*(sal_uInt32*)rMetric.getValue()));
368 break;
369 default:
370 OSL_FAIL("AW: Missing unit translation to 100th mm!");
372 break;
374 default:
376 OSL_FAIL("AW: Missing unit translation to PoolMetrics!");
381 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */