nss: upgrade to release 3.73
[LibreOffice.git] / editeng / source / uno / unoipset.cxx
blobc9d54c83e97244a03e6bf0e1e3268cec31b52605
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/itemprop.hxx>
22 #include <tools/helpers.hxx>
23 #include <editeng/unoipset.hxx>
24 #include <svl/itempool.hxx>
25 #include <svl/solar.hrc>
26 #include <o3tl/any.hxx>
27 #include <osl/diagnose.h>
28 #include <sal/log.hxx>
29 #include <algorithm>
31 using namespace ::com::sun::star;
34 struct SvxIDPropertyCombine
36 sal_uInt16 nWID;
37 sal_uInt8 memberId;
38 uno::Any aAny;
42 SvxItemPropertySet::SvxItemPropertySet( const SfxItemPropertyMapEntry* pMap, SfxItemPool& rItemPool )
43 : m_aPropertyMap( pMap ),
44 mrItemPool( rItemPool )
49 SvxItemPropertySet::~SvxItemPropertySet()
51 ClearAllUsrAny();
55 uno::Any* SvxItemPropertySet::GetUsrAnyForID(SfxItemPropertySimpleEntry const & entry) const
57 for (auto const & pActual : aCombineList)
59 if( pActual->nWID == entry.nWID && pActual->memberId == entry.nMemberId )
60 return &pActual->aAny;
62 return nullptr;
66 void SvxItemPropertySet::AddUsrAnyForID(
67 const uno::Any& rAny, SfxItemPropertySimpleEntry const & entry)
69 std::unique_ptr<SvxIDPropertyCombine> pNew(new SvxIDPropertyCombine);
70 pNew->nWID = entry.nWID;
71 pNew->memberId = entry.nMemberId;
72 pNew->aAny = rAny;
73 aCombineList.push_back( std::move(pNew) );
77 void SvxItemPropertySet::ClearAllUsrAny()
79 aCombineList.clear();
83 static bool SvxUnoCheckForPositiveValue( const uno::Any& rVal )
85 bool bConvert = true; // the default is that all metric items must be converted
86 sal_Int32 nValue = 0;
87 if( rVal >>= nValue )
88 bConvert = (nValue > 0);
89 return bConvert;
93 uno::Any SvxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry* pMap, const SfxItemSet& rSet, bool bSearchInParent, bool bDontConvertNegativeValues )
95 uno::Any aVal;
96 if(!pMap || !pMap->nWID)
97 return aVal;
99 const SfxPoolItem* pItem = nullptr;
100 SfxItemPool* pPool = rSet.GetPool();
101 (void)rSet.GetItemState( pMap->nWID, bSearchInParent, &pItem );
102 if( nullptr == pItem && pPool )
103 pItem = &(pPool->GetDefaultItem( pMap->nWID ));
105 const MapUnit eMapUnit = pPool ? pPool->GetMetric(pMap->nWID) : MapUnit::Map100thMM;
106 sal_uInt8 nMemberId = pMap->nMemberId;
107 if( eMapUnit == MapUnit::Map100thMM )
108 nMemberId &= (~CONVERT_TWIPS);
110 if(pItem)
112 pItem->QueryValue( aVal, nMemberId );
113 if( pMap->nMoreFlags & PropertyMoreFlags::METRIC_ITEM )
115 if( eMapUnit != MapUnit::Map100thMM )
117 if ( !bDontConvertNegativeValues || SvxUnoCheckForPositiveValue( aVal ) )
118 SvxUnoConvertToMM( eMapUnit, aVal );
121 else if ( pMap->aType.getTypeClass() == uno::TypeClass_ENUM &&
122 aVal.getValueType() == ::cppu::UnoType<sal_Int32>::get() )
124 // convert typeless SfxEnumItem to enum type
125 sal_Int32 nEnum;
126 aVal >>= nEnum;
127 aVal.setValue( &nEnum, pMap->aType );
130 else
132 OSL_FAIL( "No SfxPoolItem found for property!" );
135 return aVal;
139 void SvxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry* pMap, const uno::Any& rVal, SfxItemSet& rSet, bool bDontConvertNegativeValues )
141 if(!pMap || !pMap->nWID)
142 return;
144 // Get item
145 const SfxPoolItem* pItem = nullptr;
146 SfxItemState eState = rSet.GetItemState( pMap->nWID, true, &pItem );
147 SfxItemPool* pPool = rSet.GetPool();
149 // Put UnoAny in the item value
150 if(eState < SfxItemState::DEFAULT || pItem == nullptr)
152 if( pPool == nullptr )
154 OSL_FAIL( "No default item and no pool?" );
155 return;
158 pItem = &pPool->GetDefaultItem( pMap->nWID );
161 uno::Any aValue(rVal);
163 const MapUnit eMapUnit = pPool ? pPool->GetMetric(pMap->nWID) : MapUnit::Map100thMM;
165 // check for needed metric translation
166 if ((pMap->nMoreFlags & PropertyMoreFlags::METRIC_ITEM) && eMapUnit != MapUnit::Map100thMM)
168 if (!bDontConvertNegativeValues || SvxUnoCheckForPositiveValue(aValue))
169 SvxUnoConvertFromMM(eMapUnit, aValue);
172 std::unique_ptr<SfxPoolItem> pNewItem(pItem->Clone());
174 sal_uInt8 nMemberId = pMap->nMemberId;
175 if (eMapUnit == MapUnit::Map100thMM)
176 nMemberId &= (~CONVERT_TWIPS);
178 if (pNewItem->PutValue(aValue, nMemberId))
180 // Set new item in item set
181 pNewItem->SetWhich(pMap->nWID);
182 rSet.Put(*pNewItem);
187 uno::Any SvxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry* pMap ) const
189 // Already entered a value? Then finish quickly
190 uno::Any* pUsrAny = GetUsrAnyForID(*pMap);
191 if(pUsrAny)
192 return *pUsrAny;
194 // No UsrAny detected yet, generate Default entry and return this
195 const MapUnit eMapUnit = mrItemPool.GetMetric(pMap->nWID);
196 sal_uInt8 nMemberId = pMap->nMemberId;
197 if( eMapUnit == MapUnit::Map100thMM )
198 nMemberId &= (~CONVERT_TWIPS);
199 uno::Any aVal;
200 SfxItemSet aSet( mrItemPool, {{pMap->nWID, pMap->nWID}});
202 if( (pMap->nWID < OWN_ATTR_VALUE_START) || (pMap->nWID > OWN_ATTR_VALUE_END ) )
204 // Get Default from ItemPool
205 if(SfxItemPool::IsWhich(pMap->nWID))
206 aSet.Put(mrItemPool.GetDefaultItem(pMap->nWID));
209 if(aSet.Count())
211 const SfxPoolItem* pItem = nullptr;
212 SfxItemState eState = aSet.GetItemState( pMap->nWID, true, &pItem );
213 if(eState >= SfxItemState::DEFAULT && pItem)
215 pItem->QueryValue( aVal, nMemberId );
216 const_cast<SvxItemPropertySet*>(this)->AddUsrAnyForID(aVal, *pMap);
220 // check for needed metric translation
221 if(pMap->nMoreFlags & PropertyMoreFlags::METRIC_ITEM && eMapUnit != MapUnit::Map100thMM)
223 SvxUnoConvertToMM( eMapUnit, aVal );
226 if ( pMap->aType.getTypeClass() == uno::TypeClass_ENUM &&
227 aVal.getValueType() == ::cppu::UnoType<sal_Int32>::get() )
229 sal_Int32 nEnum;
230 aVal >>= nEnum;
232 aVal.setValue( &nEnum, pMap->aType );
235 return aVal;
239 void SvxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry* pMap, const uno::Any& rVal ) const
241 uno::Any* pUsrAny = GetUsrAnyForID(*pMap);
242 if(!pUsrAny)
243 const_cast<SvxItemPropertySet*>(this)->AddUsrAnyForID(rVal, *pMap);
244 else
245 *pUsrAny = rVal;
249 const SfxItemPropertySimpleEntry* SvxItemPropertySet::getPropertyMapEntry(const OUString &rName) const
251 return m_aPropertyMap.getByName( rName );
255 uno::Reference< beans::XPropertySetInfo > const & SvxItemPropertySet::getPropertySetInfo() const
257 if( !m_xInfo.is() )
258 m_xInfo = new SfxItemPropertySetInfo( m_aPropertyMap );
259 return m_xInfo;
263 #ifndef TWIPS_TO_MM
264 #define TWIPS_TO_MM(val) ((val * 127 + 36) / 72)
265 #endif
267 /** converts the given any with a metric to 100th/mm if needed */
268 void SvxUnoConvertToMM( const MapUnit eSourceMapUnit, uno::Any & rMetric ) throw()
270 // map the metric of the itempool to 100th mm
271 switch(eSourceMapUnit)
273 case MapUnit::MapTwip :
275 switch( rMetric.getValueTypeClass() )
277 case uno::TypeClass_BYTE:
278 rMetric <<= static_cast<sal_Int8>(TWIPS_TO_MM(*o3tl::forceAccess<sal_Int8>(rMetric)));
279 break;
280 case uno::TypeClass_SHORT:
281 rMetric <<= static_cast<sal_Int16>(TWIPS_TO_MM(*o3tl::forceAccess<sal_Int16>(rMetric)));
282 break;
283 case uno::TypeClass_UNSIGNED_SHORT:
284 rMetric <<= static_cast<sal_uInt16>(TWIPS_TO_MM(*o3tl::forceAccess<sal_uInt16>(rMetric)));
285 break;
286 case uno::TypeClass_LONG:
287 rMetric <<= static_cast<sal_Int32>(TWIPS_TO_MM(*o3tl::forceAccess<sal_Int32>(rMetric)));
288 break;
289 case uno::TypeClass_UNSIGNED_LONG:
290 rMetric <<= static_cast<sal_uInt32>(TWIPS_TO_MM(*o3tl::forceAccess<sal_uInt32>(rMetric)));
291 break;
292 default:
293 SAL_WARN("editeng", "AW: Missing unit translation to 100th mm, " << OString::number(static_cast<sal_Int32>(rMetric.getValueTypeClass())));
294 assert(false);
296 break;
298 default:
300 OSL_FAIL("AW: Missing unit translation to 100th mm!");
306 /** converts the given any with a metric from 100th/mm to the given metric if needed */
307 void SvxUnoConvertFromMM( const MapUnit eDestinationMapUnit, uno::Any & rMetric ) throw()
309 switch(eDestinationMapUnit)
311 case MapUnit::MapTwip :
313 switch( rMetric.getValueTypeClass() )
315 case uno::TypeClass_BYTE:
316 rMetric <<= static_cast<sal_Int8>(sanitiseMm100ToTwip(*o3tl::forceAccess<sal_Int8>(rMetric)));
317 break;
318 case uno::TypeClass_SHORT:
319 rMetric <<= static_cast<sal_Int16>(sanitiseMm100ToTwip(*o3tl::forceAccess<sal_Int16>(rMetric)));
320 break;
321 case uno::TypeClass_UNSIGNED_SHORT:
322 rMetric <<= static_cast<sal_uInt16>(sanitiseMm100ToTwip(*o3tl::forceAccess<sal_uInt16>(rMetric)));
323 break;
324 case uno::TypeClass_LONG:
325 rMetric <<= static_cast<sal_Int32>(sanitiseMm100ToTwip(*o3tl::forceAccess<sal_Int32>(rMetric)));
326 break;
327 case uno::TypeClass_UNSIGNED_LONG:
328 rMetric <<= static_cast<sal_uInt32>(sanitiseMm100ToTwip(*o3tl::forceAccess<sal_uInt32>(rMetric)));
329 break;
330 default:
331 OSL_FAIL("AW: Missing unit translation to 100th mm!");
333 break;
335 default:
337 OSL_FAIL("AW: Missing unit translation to PoolMetrics!");
342 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */