bump product version to 5.0.4.1
[LibreOffice.git] / editeng / source / uno / unoipset.cxx
blobfbece038b66aa13c682a62100946714cdee1f232
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <com/sun/star/beans/XPropertySet.hpp>
21 #include <svl/eitem.hxx>
23 #include <svl/itemprop.hxx>
25 #include <editeng/unoipset.hxx>
26 #include <editeng/editids.hrc>
27 #include <editeng/editeng.hxx>
28 #include <svl/itempool.hxx>
29 #include <osl/diagnose.h>
30 #include <algorithm>
32 using namespace ::com::sun::star;
34 using ::std::vector;
36 struct SvxIDPropertyCombine
38 sal_uInt16 nWID;
39 uno::Any aAny;
43 SvxItemPropertySet::SvxItemPropertySet( const SfxItemPropertyMapEntry* pMap, SfxItemPool& rItemPool, bool bConvertTwips )
44 : m_aPropertyMap( pMap ),
45 _pMap(pMap), mbConvertTwips(bConvertTwips), mrItemPool( rItemPool )
50 SvxItemPropertySet::~SvxItemPropertySet()
52 ClearAllUsrAny();
56 uno::Any* SvxItemPropertySet::GetUsrAnyForID(sal_uInt16 nWID) const
58 for ( size_t i = 0, n = aCombineList.size(); i < n; ++i )
60 SvxIDPropertyCombine* pActual = aCombineList[ i ];
61 if( pActual->nWID == nWID )
62 return &pActual->aAny;
64 return NULL;
68 void SvxItemPropertySet::AddUsrAnyForID(const uno::Any& rAny, sal_uInt16 nWID)
70 SvxIDPropertyCombine* pNew = new SvxIDPropertyCombine;
71 pNew->nWID = nWID;
72 pNew->aAny = rAny;
73 aCombineList.push_back( pNew );
78 void SvxItemPropertySet::ClearAllUsrAny()
80 for ( size_t i = 0, n = aCombineList.size(); i < n; ++i )
81 delete aCombineList[ i ];
82 aCombineList.clear();
87 bool SvxUnoCheckForPositiveValue( const uno::Any& rVal )
89 bool bConvert = true; // the default is that all metric items must be converted
90 sal_Int32 nValue = 0;
91 if( rVal >>= nValue )
92 bConvert = (nValue > 0);
93 return bConvert;
98 uno::Any SvxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry* pMap, const SfxItemSet& rSet, bool bSearchInParent, bool bDontConvertNegativeValues )
100 uno::Any aVal;
101 if(!pMap || !pMap->nWID)
102 return aVal;
104 const SfxPoolItem* pItem = 0;
105 SfxItemPool* pPool = rSet.GetPool();
106 rSet.GetItemState( pMap->nWID, bSearchInParent, &pItem );
107 if( NULL == pItem && pPool )
108 pItem = &(pPool->GetDefaultItem( pMap->nWID ));
110 const SfxMapUnit eMapUnit = pPool ? pPool->GetMetric((sal_uInt16)pMap->nWID) : SFX_MAPUNIT_100TH_MM;
111 sal_uInt8 nMemberId = pMap->nMemberId & (~SFX_METRIC_ITEM);
112 if( eMapUnit == SFX_MAPUNIT_100TH_MM )
113 nMemberId &= (~CONVERT_TWIPS);
115 if(pItem)
117 pItem->QueryValue( aVal, nMemberId );
118 if( pMap->nMemberId & SFX_METRIC_ITEM )
120 if( eMapUnit != SFX_MAPUNIT_100TH_MM )
122 if ( !bDontConvertNegativeValues || SvxUnoCheckForPositiveValue( aVal ) )
123 SvxUnoConvertToMM( eMapUnit, aVal );
126 else if ( pMap->aType.getTypeClass() == uno::TypeClass_ENUM &&
127 aVal.getValueType() == ::cppu::UnoType<sal_Int32>::get() )
129 // convert typeless SfxEnumItem to enum type
130 sal_Int32 nEnum;
131 aVal >>= nEnum;
132 aVal.setValue( &nEnum, pMap->aType );
135 else
137 OSL_FAIL( "No SfxPoolItem found for property!" );
140 return aVal;
144 void SvxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry* pMap, const uno::Any& rVal, SfxItemSet& rSet, bool bDontConvertNegativeValues )
146 if(!pMap || !pMap->nWID)
147 return;
149 // Get item
150 const SfxPoolItem* pItem = 0;
151 SfxItemState eState = rSet.GetItemState( pMap->nWID, true, &pItem );
152 SfxItemPool* pPool = rSet.GetPool();
154 // Put UnoAny in the item value
155 if(eState < SfxItemState::DEFAULT || pItem == NULL)
157 if( pPool == NULL )
159 OSL_FAIL( "No default item and no pool?" );
160 return;
163 pItem = &pPool->GetDefaultItem( pMap->nWID );
166 DBG_ASSERT( pItem, "Got no default for item!" );
167 if( pItem )
169 uno::Any aValue( rVal );
171 const SfxMapUnit eMapUnit = pPool ? pPool->GetMetric((sal_uInt16)pMap->nWID) : SFX_MAPUNIT_100TH_MM;
173 // check for needed metric translation
174 if( (pMap->nMemberId & SFX_METRIC_ITEM) && eMapUnit != SFX_MAPUNIT_100TH_MM )
176 if ( !bDontConvertNegativeValues || SvxUnoCheckForPositiveValue( aValue ) )
177 SvxUnoConvertFromMM( eMapUnit, aValue );
180 SfxPoolItem *pNewItem = pItem->Clone();
182 sal_uInt8 nMemberId = pMap->nMemberId & (~SFX_METRIC_ITEM);
183 if( eMapUnit == SFX_MAPUNIT_100TH_MM )
184 nMemberId &= (~CONVERT_TWIPS);
186 if( pNewItem->PutValue( aValue, nMemberId ) )
188 // Set new item in item set
189 rSet.Put( *pNewItem, pMap->nWID );
191 delete pNewItem;
196 uno::Any SvxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry* pMap ) const
198 // Already entered a value? Then finish quickly
199 uno::Any* pUsrAny = GetUsrAnyForID(pMap->nWID);
200 if(pUsrAny)
201 return *pUsrAny;
203 // No UsrAny detected yet, generate Default entry and return this
204 const SfxMapUnit eMapUnit = mrItemPool.GetMetric((sal_uInt16)pMap->nWID);
205 sal_uInt8 nMemberId = pMap->nMemberId & (~SFX_METRIC_ITEM);
206 if( eMapUnit == SFX_MAPUNIT_100TH_MM )
207 nMemberId &= (~CONVERT_TWIPS);
208 uno::Any aVal;
209 SfxItemSet aSet( mrItemPool, pMap->nWID, pMap->nWID);
211 if( (pMap->nWID < OWN_ATTR_VALUE_START) && (pMap->nWID > OWN_ATTR_VALUE_END ) )
213 // Get Default from ItemPool
214 if(SfxItemPool::IsWhich(pMap->nWID))
215 aSet.Put(mrItemPool.GetDefaultItem(pMap->nWID));
218 if(aSet.Count())
220 const SfxPoolItem* pItem = NULL;
221 SfxItemState eState = aSet.GetItemState( pMap->nWID, true, &pItem );
222 if(eState >= SfxItemState::DEFAULT && pItem)
224 pItem->QueryValue( aVal, nMemberId );
225 const_cast<SvxItemPropertySet*>(this)->AddUsrAnyForID(aVal, pMap->nWID);
229 if( pMap->nMemberId & SFX_METRIC_ITEM )
231 // check for needed metric translation
232 if(pMap->nMemberId & SFX_METRIC_ITEM && eMapUnit != SFX_MAPUNIT_100TH_MM)
234 SvxUnoConvertToMM( eMapUnit, aVal );
238 if ( pMap->aType.getTypeClass() == uno::TypeClass_ENUM &&
239 aVal.getValueType() == ::cppu::UnoType<sal_Int32>::get() )
241 sal_Int32 nEnum;
242 aVal >>= nEnum;
244 aVal.setValue( &nEnum, pMap->aType );
247 return aVal;
252 void SvxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry* pMap, const uno::Any& rVal ) const
254 uno::Any* pUsrAny = GetUsrAnyForID(pMap->nWID);
255 if(!pUsrAny)
256 const_cast<SvxItemPropertySet*>(this)->AddUsrAnyForID(rVal, pMap->nWID);
257 else
258 *pUsrAny = rVal;
263 const SfxItemPropertySimpleEntry* SvxItemPropertySet::getPropertyMapEntry(const OUString &rName) const
265 return m_aPropertyMap.getByName( rName );
270 uno::Reference< beans::XPropertySetInfo > SvxItemPropertySet::getPropertySetInfo() const
272 if( !m_xInfo.is() )
273 m_xInfo = new SfxItemPropertySetInfo( m_aPropertyMap );
274 return m_xInfo;
279 #ifndef TWIPS_TO_MM
280 #define TWIPS_TO_MM(val) ((val * 127 + 36) / 72)
281 #endif
282 #ifndef MM_TO_TWIPS
283 #define MM_TO_TWIPS(val) ((val * 72 + 63) / 127)
284 #endif
286 /** converts the given any with a metric to 100th/mm if needed */
287 void SvxUnoConvertToMM( const SfxMapUnit eSourceMapUnit, uno::Any & rMetric ) throw()
289 // map the metric of the itempool to 100th mm
290 switch(eSourceMapUnit)
292 case SFX_MAPUNIT_TWIP :
294 switch( rMetric.getValueTypeClass() )
296 case uno::TypeClass_BYTE:
297 rMetric <<= (sal_Int8)(TWIPS_TO_MM(*static_cast<sal_Int8 const *>(rMetric.getValue())));
298 break;
299 case uno::TypeClass_SHORT:
300 rMetric <<= (sal_Int16)(TWIPS_TO_MM(*static_cast<sal_Int16 const *>(rMetric.getValue())));
301 break;
302 case uno::TypeClass_UNSIGNED_SHORT:
303 rMetric <<= (sal_uInt16)(TWIPS_TO_MM(*static_cast<sal_uInt16 const *>(rMetric.getValue())));
304 break;
305 case uno::TypeClass_LONG:
306 rMetric <<= (sal_Int32)(TWIPS_TO_MM(*static_cast<sal_Int32 const *>(rMetric.getValue())));
307 break;
308 case uno::TypeClass_UNSIGNED_LONG:
309 rMetric <<= (sal_uInt32)(TWIPS_TO_MM(*static_cast<sal_uInt32 const *>(rMetric.getValue())));
310 break;
311 default:
312 OSL_FAIL("AW: Missing unit translation to 100th mm!");
314 break;
316 default:
318 OSL_FAIL("AW: Missing unit translation to 100th mm!");
325 /** converts the given any with a metric from 100th/mm to the given metric if needed */
326 void SvxUnoConvertFromMM( const SfxMapUnit eDestinationMapUnit, uno::Any & rMetric ) throw()
328 switch(eDestinationMapUnit)
330 case SFX_MAPUNIT_TWIP :
332 switch( rMetric.getValueTypeClass() )
334 case uno::TypeClass_BYTE:
335 rMetric <<= (sal_Int8)(MM_TO_TWIPS(*static_cast<sal_Int8 const *>(rMetric.getValue())));
336 break;
337 case uno::TypeClass_SHORT:
338 rMetric <<= (sal_Int16)(MM_TO_TWIPS(*static_cast<sal_Int16 const *>(rMetric.getValue())));
339 break;
340 case uno::TypeClass_UNSIGNED_SHORT:
341 rMetric <<= (sal_uInt16)(MM_TO_TWIPS(*static_cast<sal_uInt16 const *>(rMetric.getValue())));
342 break;
343 case uno::TypeClass_LONG:
344 rMetric <<= (sal_Int32)(MM_TO_TWIPS(*static_cast<sal_Int32 const *>(rMetric.getValue())));
345 break;
346 case uno::TypeClass_UNSIGNED_LONG:
347 rMetric <<= (sal_uInt32)(MM_TO_TWIPS(*static_cast<sal_uInt32 const *>(rMetric.getValue())));
348 break;
349 default:
350 OSL_FAIL("AW: Missing unit translation to 100th mm!");
352 break;
354 default:
356 OSL_FAIL("AW: Missing unit translation to PoolMetrics!");
361 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */