LibreOffice Module editeng (master) 1
unoipset.cxx
Go to the documentation of this file.
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#include <com/sun/star/beans/XPropertySet.hpp>
21#include <svl/itemprop.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>
30
31using namespace ::com::sun::star;
32
33
35: m_aPropertyMap( pMap ),
36 mrItemPool( rItemPool )
37{
38}
39
40
42{
43}
44
45
46static bool SvxUnoCheckForPositiveValue( const uno::Any& rVal )
47{
48 bool bConvert = true; // the default is that all metric items must be converted
49 sal_Int32 nValue = 0;
50 if( rVal >>= nValue )
51 bConvert = (nValue > 0);
52 return bConvert;
53}
54
55
56uno::Any SvxItemPropertySet::getPropertyValue( const SfxItemPropertyMapEntry* pMap, const SfxItemSet& rSet, bool bSearchInParent, bool bDontConvertNegativeValues )
57{
58 uno::Any aVal;
59 if(!pMap || !pMap->nWID)
60 return aVal;
61
62 const SfxPoolItem* pItem = nullptr;
63 SfxItemPool* pPool = rSet.GetPool();
64 (void)rSet.GetItemState( pMap->nWID, bSearchInParent, &pItem );
65 if( nullptr == pItem && pPool )
66 pItem = &(pPool->GetDefaultItem( pMap->nWID ));
67
68 const MapUnit eMapUnit = pPool ? pPool->GetMetric(pMap->nWID) : MapUnit::Map100thMM;
69 sal_uInt8 nMemberId = pMap->nMemberId;
70 if( eMapUnit == MapUnit::Map100thMM )
71 nMemberId &= (~CONVERT_TWIPS);
72
73 if(pItem)
74 {
75 pItem->QueryValue( aVal, nMemberId );
76 if( pMap->nMoreFlags & PropertyMoreFlags::METRIC_ITEM )
77 {
78 if( eMapUnit != MapUnit::Map100thMM )
79 {
80 if ( !bDontConvertNegativeValues || SvxUnoCheckForPositiveValue( aVal ) )
81 SvxUnoConvertToMM( eMapUnit, aVal );
82 }
83 }
84 else if ( pMap->aType.getTypeClass() == uno::TypeClass_ENUM &&
85 aVal.getValueType() == ::cppu::UnoType<sal_Int32>::get() )
86 {
87 // convert typeless SfxEnumItem to enum type
88 sal_Int32 nEnum;
89 aVal >>= nEnum;
90 aVal.setValue( &nEnum, pMap->aType );
91 }
92 }
93 else
94 {
95 OSL_FAIL( "No SfxPoolItem found for property!" );
96 }
97
98 return aVal;
99}
100
101
102void SvxItemPropertySet::setPropertyValue( const SfxItemPropertyMapEntry* pMap, const uno::Any& rVal, SfxItemSet& rSet, bool bDontConvertNegativeValues )
103{
104 if(!pMap || !pMap->nWID)
105 return;
106
107 // Get item
108 const SfxPoolItem* pItem = nullptr;
109 SfxItemState eState = rSet.GetItemState( pMap->nWID, true, &pItem );
110 SfxItemPool* pPool = rSet.GetPool();
111
112 // Put UnoAny in the item value
113 if(eState < SfxItemState::DEFAULT || pItem == nullptr)
114 {
115 if( pPool == nullptr )
116 {
117 OSL_FAIL( "No default item and no pool?" );
118 return;
119 }
120
121 pItem = &pPool->GetDefaultItem( pMap->nWID );
122 }
123
124 uno::Any aValue(rVal);
125
126 const MapUnit eMapUnit = pPool ? pPool->GetMetric(pMap->nWID) : MapUnit::Map100thMM;
127
128 // check for needed metric translation
129 if ((pMap->nMoreFlags & PropertyMoreFlags::METRIC_ITEM) && eMapUnit != MapUnit::Map100thMM)
130 {
131 if (!bDontConvertNegativeValues || SvxUnoCheckForPositiveValue(aValue))
132 SvxUnoConvertFromMM(eMapUnit, aValue);
133 }
134
135 std::unique_ptr<SfxPoolItem> pNewItem(pItem->Clone());
136
137 sal_uInt8 nMemberId = pMap->nMemberId;
138 if (eMapUnit == MapUnit::Map100thMM)
139 nMemberId &= (~CONVERT_TWIPS);
140
141 if (pNewItem->PutValue(aValue, nMemberId))
142 {
143 // Set new item in item set
144 pNewItem->SetWhich(pMap->nWID);
145 rSet.Put(std::move(pNewItem));
146 }
147}
148
149
151{
152 // Already entered a value? Then finish quickly
153 uno::Any* pUsrAny = rAnys.GetUsrAnyForID(*pMap);
154 if(pUsrAny)
155 return *pUsrAny;
156
157 // No UsrAny detected yet, generate Default entry and return this
158 const MapUnit eMapUnit = mrItemPool.GetMetric(pMap->nWID);
159 sal_uInt8 nMemberId = pMap->nMemberId;
160 if( eMapUnit == MapUnit::Map100thMM )
161 nMemberId &= (~CONVERT_TWIPS);
162 uno::Any aVal;
163 SfxItemSet aSet( mrItemPool, pMap->nWID, pMap->nWID);
164
165 if( (pMap->nWID < OWN_ATTR_VALUE_START) || (pMap->nWID > OWN_ATTR_VALUE_END ) )
166 {
167 // Get Default from ItemPool
168 if(SfxItemPool::IsWhich(pMap->nWID))
169 aSet.Put(mrItemPool.GetDefaultItem(pMap->nWID));
170 }
171
172 if(aSet.Count())
173 {
174 const SfxPoolItem* pItem = nullptr;
175 SfxItemState eState = aSet.GetItemState( pMap->nWID, true, &pItem );
176 if(eState >= SfxItemState::DEFAULT && pItem)
177 {
178 pItem->QueryValue( aVal, nMemberId );
179 rAnys.AddUsrAnyForID(aVal, *pMap);
180 }
181 }
182
183 // check for needed metric translation
184 if(pMap->nMoreFlags & PropertyMoreFlags::METRIC_ITEM && eMapUnit != MapUnit::Map100thMM)
185 {
186 SvxUnoConvertToMM( eMapUnit, aVal );
187 }
188
189 if ( pMap->aType.getTypeClass() == uno::TypeClass_ENUM &&
190 aVal.getValueType() == ::cppu::UnoType<sal_Int32>::get() )
191 {
192 sal_Int32 nEnum;
193 aVal >>= nEnum;
194
195 aVal.setValue( &nEnum, pMap->aType );
196 }
197
198 return aVal;
199}
200
201
203{
204 uno::Any* pUsrAny = rAnys.GetUsrAnyForID(*pMap);
205 if(!pUsrAny)
206 rAnys.AddUsrAnyForID(rVal, *pMap);
207 else
208 *pUsrAny = rVal;
209}
210
211
213{
214 return m_aPropertyMap.getByName( rName );
215 }
216
217
218uno::Reference< beans::XPropertySetInfo > const & SvxItemPropertySet::getPropertySetInfo() const
219{
220 if( !m_xInfo.is() )
222 return m_xInfo;
223}
224
225
227void SvxUnoConvertToMM( const MapUnit eSourceMapUnit, uno::Any & rMetric ) noexcept
228{
229 // map the metric of the itempool to 100th mm
230 switch(eSourceMapUnit)
231 {
232 case MapUnit::MapTwip :
233 {
234 switch( rMetric.getValueTypeClass() )
235 {
236 case uno::TypeClass_BYTE:
237 rMetric <<= static_cast<sal_Int8>(convertTwipToMm100(*o3tl::forceAccess<sal_Int8>(rMetric)));
238 break;
239 case uno::TypeClass_SHORT:
240 rMetric <<= static_cast<sal_Int16>(convertTwipToMm100(*o3tl::forceAccess<sal_Int16>(rMetric)));
241 break;
242 case uno::TypeClass_UNSIGNED_SHORT:
243 rMetric <<= static_cast<sal_uInt16>(convertTwipToMm100(*o3tl::forceAccess<sal_uInt16>(rMetric)));
244 break;
245 case uno::TypeClass_LONG:
246 rMetric <<= static_cast<sal_Int32>(convertTwipToMm100(*o3tl::forceAccess<sal_Int32>(rMetric)));
247 break;
248 case uno::TypeClass_UNSIGNED_LONG:
249 rMetric <<= static_cast<sal_uInt32>(convertTwipToMm100(*o3tl::forceAccess<sal_uInt32>(rMetric)));
250 break;
251 default:
252 SAL_WARN("editeng", "AW: Missing unit translation to 100th mm, " << OString::number(static_cast<sal_Int32>(rMetric.getValueTypeClass())));
253 assert(false);
254 }
255 break;
256 }
257 default:
258 {
259 OSL_FAIL("AW: Missing unit translation to 100th mm!");
260 }
261 }
262}
263
264
266void SvxUnoConvertFromMM( const MapUnit eDestinationMapUnit, uno::Any & rMetric ) noexcept
267{
268 switch(eDestinationMapUnit)
269 {
270 case MapUnit::MapTwip :
271 {
272 switch( rMetric.getValueTypeClass() )
273 {
274 case uno::TypeClass_BYTE:
275 rMetric <<= static_cast<sal_Int8>(sanitiseMm100ToTwip(*o3tl::forceAccess<sal_Int8>(rMetric)));
276 break;
277 case uno::TypeClass_SHORT:
278 rMetric <<= static_cast<sal_Int16>(sanitiseMm100ToTwip(*o3tl::forceAccess<sal_Int16>(rMetric)));
279 break;
280 case uno::TypeClass_UNSIGNED_SHORT:
281 rMetric <<= static_cast<sal_uInt16>(sanitiseMm100ToTwip(*o3tl::forceAccess<sal_uInt16>(rMetric)));
282 break;
283 case uno::TypeClass_LONG:
284 rMetric <<= static_cast<sal_Int32>(sanitiseMm100ToTwip(*o3tl::forceAccess<sal_Int32>(rMetric)));
285 break;
286 case uno::TypeClass_UNSIGNED_LONG:
287 rMetric <<= static_cast<sal_uInt32>(sanitiseMm100ToTwip(*o3tl::forceAccess<sal_uInt32>(rMetric)));
288 break;
289 default:
290 OSL_FAIL("AW: Missing unit translation to 100th mm!");
291 }
292 break;
293 }
294 default:
295 {
296 OSL_FAIL("AW: Missing unit translation to PoolMetrics!");
297 }
298 }
299}
300
302
304{
306}
307
309{
310 for (auto const & rActual : aCombineList)
311 {
312 if( rActual.nWID == entry.nWID && rActual.memberId == entry.nMemberId )
313 return const_cast<uno::Any*>(&rActual.aAny);
314 }
315 return nullptr;
316}
317
319 const uno::Any& rAny, SfxItemPropertyMapEntry const & entry)
320{
322 aNew.nWID = entry.nWID;
323 aNew.memberId = entry.nMemberId;
324 aNew.aAny = rAny;
325 aCombineList.push_back( std::move(aNew) );
326}
327
329{
330 aCombineList.clear();
331}
332
333/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr sal_Int64 sanitiseMm100ToTwip(sal_Int64 n)
constexpr auto convertTwipToMm100(N n)
const SfxPoolItem & GetDefaultItem(sal_uInt16 nWhich) const
static bool IsWhich(sal_uInt16 nId)
virtual MapUnit GetMetric(sal_uInt16 nWhich) const
const SfxItemPropertyMapEntry * getByName(std::u16string_view rName) const
SfxItemPool * GetPool() const
sal_uInt16 Count() const
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
virtual bool QueryValue(css::uno::Any &rVal, sal_uInt8 nMemberId=0) const
virtual SfxPoolItem * Clone(SfxItemPool *pPool=nullptr) const=0
::std::vector< SvxIDPropertyCombine > aCombineList
Definition: unoipset.hxx:68
css::uno::Any * GetUsrAnyForID(SfxItemPropertyMapEntry const &entry) const
Definition: unoipset.cxx:308
void AddUsrAnyForID(const css::uno::Any &rAny, SfxItemPropertyMapEntry const &entry)
Definition: unoipset.cxx:318
SvxItemPropertySet(o3tl::span< const SfxItemPropertyMapEntry > pMap, SfxItemPool &rPool)
Definition: unoipset.cxx:34
css::uno::Reference< css::beans::XPropertySetInfo > const & getPropertySetInfo() const
Definition: unoipset.cxx:218
const SfxItemPropertyMapEntry * getPropertyMapEntry(std::u16string_view rName) const
Definition: unoipset.cxx:212
static void setPropertyValue(const SfxItemPropertyMapEntry *pMap, const css::uno::Any &rVal, SfxItemSet &rSet, bool bDontConvertNegativeValues)
SfxItemPropertyMap m_aPropertyMap
Definition: unoipset.hxx:34
css::uno::Reference< css::beans::XPropertySetInfo > m_xInfo
Definition: unoipset.hxx:35
SfxItemPool & mrItemPool
Definition: unoipset.hxx:36
static css::uno::Any getPropertyValue(const SfxItemPropertyMapEntry *pMap, const SfxItemSet &rSet, bool bSearchInParent, bool bDontConvertNegativeValues)
Definition: unoipset.cxx:56
css::uno::Type const & get()
sal_Int16 nValue
#define SAL_WARN(area, stream)
MapUnit
SfxItemState
static SfxItemSet & rSet
PropertyMoreFlags nMoreFlags
css::uno::Type aType
sal_uInt8 memberId
Definition: unoipset.hxx:61
css::uno::Any aAny
Definition: unoipset.hxx:62
void setValue(Type type, object value)
unsigned char sal_uInt8
void SvxUnoConvertToMM(const MapUnit eSourceMapUnit, uno::Any &rMetric) noexcept
converts the given any with a metric to 100th/mm if needed
Definition: unoipset.cxx:227
void SvxUnoConvertFromMM(const MapUnit eDestinationMapUnit, uno::Any &rMetric) noexcept
converts the given any with a metric from 100th/mm to the given metric if needed
Definition: unoipset.cxx:266
static bool SvxUnoCheckForPositiveValue(const uno::Any &rVal)
Definition: unoipset.cxx:46