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 : #include <com/sun/star/beans/XPropertySet.hpp>
21 : #include <svl/eitem.hxx>
22 :
23 : #include <svl/itemprop.hxx>
24 :
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>
31 :
32 : using namespace ::com::sun::star;
33 :
34 : using ::std::vector;
35 :
36 1236 : struct SvxIDPropertyCombine
37 : {
38 : sal_uInt16 nWID;
39 : uno::Any aAny;
40 : };
41 :
42 :
43 840 : SvxItemPropertySet::SvxItemPropertySet( const SfxItemPropertyMapEntry* pMap, SfxItemPool& rItemPool, bool bConvertTwips )
44 : : m_aPropertyMap( pMap ),
45 840 : _pMap(pMap), mbConvertTwips(bConvertTwips), mrItemPool( rItemPool )
46 : {
47 840 : }
48 :
49 :
50 1678 : SvxItemPropertySet::~SvxItemPropertySet()
51 : {
52 839 : ClearAllUsrAny();
53 839 : }
54 :
55 :
56 35416 : uno::Any* SvxItemPropertySet::GetUsrAnyForID(sal_uInt16 nWID) const
57 : {
58 141971 : for ( size_t i = 0, n = aCombineList.size(); i < n; ++i )
59 : {
60 107225 : SvxIDPropertyCombine* pActual = aCombineList[ i ];
61 107225 : if( pActual->nWID == nWID )
62 670 : return &pActual->aAny;
63 : }
64 34746 : return NULL;
65 : }
66 :
67 :
68 618 : void SvxItemPropertySet::AddUsrAnyForID(const uno::Any& rAny, sal_uInt16 nWID)
69 : {
70 618 : SvxIDPropertyCombine* pNew = new SvxIDPropertyCombine;
71 618 : pNew->nWID = nWID;
72 618 : pNew->aAny = rAny;
73 618 : aCombineList.push_back( pNew );
74 618 : }
75 :
76 :
77 :
78 1043 : void SvxItemPropertySet::ClearAllUsrAny()
79 : {
80 1661 : for ( size_t i = 0, n = aCombineList.size(); i < n; ++i )
81 618 : delete aCombineList[ i ];
82 1043 : aCombineList.clear();
83 1043 : }
84 :
85 :
86 :
87 36 : bool SvxUnoCheckForPositiveValue( const uno::Any& rVal )
88 : {
89 36 : bool bConvert = true; // the default is that all metric items must be converted
90 36 : sal_Int32 nValue = 0;
91 36 : if( rVal >>= nValue )
92 36 : bConvert = (nValue > 0);
93 36 : return bConvert;
94 : }
95 :
96 :
97 :
98 97838 : uno::Any SvxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry* pMap, const SfxItemSet& rSet, bool bSearchInParent, bool bDontConvertNegativeValues )
99 : {
100 97838 : uno::Any aVal;
101 97838 : if(!pMap || !pMap->nWID)
102 0 : return aVal;
103 :
104 97838 : const SfxPoolItem* pItem = 0;
105 97838 : SfxItemPool* pPool = rSet.GetPool();
106 97838 : rSet.GetItemState( pMap->nWID, bSearchInParent, &pItem );
107 97838 : if( NULL == pItem && pPool )
108 10375 : pItem = &(pPool->GetDefaultItem( pMap->nWID ));
109 :
110 97838 : const SfxMapUnit eMapUnit = pPool ? pPool->GetMetric((sal_uInt16)pMap->nWID) : SFX_MAPUNIT_100TH_MM;
111 97838 : sal_uInt8 nMemberId = pMap->nMemberId & (~SFX_METRIC_ITEM);
112 97838 : if( eMapUnit == SFX_MAPUNIT_100TH_MM )
113 61369 : nMemberId &= (~CONVERT_TWIPS);
114 :
115 97838 : if(pItem)
116 : {
117 97838 : pItem->QueryValue( aVal, nMemberId );
118 97838 : if( pMap->nMemberId & SFX_METRIC_ITEM )
119 : {
120 19313 : if( eMapUnit != SFX_MAPUNIT_100TH_MM )
121 : {
122 4991 : if ( !bDontConvertNegativeValues || SvxUnoCheckForPositiveValue( aVal ) )
123 4963 : SvxUnoConvertToMM( eMapUnit, aVal );
124 : }
125 : }
126 94917 : else if ( pMap->aType.getTypeClass() == uno::TypeClass_ENUM &&
127 16392 : aVal.getValueType() == ::cppu::UnoType<sal_Int32>::get() )
128 : {
129 : // convert typeless SfxEnumItem to enum type
130 : sal_Int32 nEnum;
131 610 : aVal >>= nEnum;
132 610 : aVal.setValue( &nEnum, pMap->aType );
133 : }
134 : }
135 : else
136 : {
137 : OSL_FAIL( "No SfxPoolItem found for property!" );
138 : }
139 :
140 97838 : return aVal;
141 : }
142 :
143 :
144 1586754 : void SvxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry* pMap, const uno::Any& rVal, SfxItemSet& rSet, bool bDontConvertNegativeValues )
145 : {
146 1586754 : if(!pMap || !pMap->nWID)
147 0 : return;
148 :
149 : // Get item
150 1586754 : const SfxPoolItem* pItem = 0;
151 1586754 : SfxItemState eState = rSet.GetItemState( pMap->nWID, true, &pItem );
152 1586754 : SfxItemPool* pPool = rSet.GetPool();
153 :
154 : // Put UnoAny in the item value
155 1586754 : if(eState < SfxItemState::DEFAULT || pItem == NULL)
156 : {
157 6 : if( pPool == NULL )
158 : {
159 : OSL_FAIL( "No default item and no pool?" );
160 0 : return;
161 : }
162 :
163 6 : pItem = &pPool->GetDefaultItem( pMap->nWID );
164 : }
165 :
166 : DBG_ASSERT( pItem, "Got no default for item!" );
167 1586754 : if( pItem )
168 : {
169 1586754 : uno::Any aValue( rVal );
170 :
171 1586754 : const SfxMapUnit eMapUnit = pPool ? pPool->GetMetric((sal_uInt16)pMap->nWID) : SFX_MAPUNIT_100TH_MM;
172 :
173 : // check for needed metric translation
174 1586754 : if( (pMap->nMemberId & SFX_METRIC_ITEM) && eMapUnit != SFX_MAPUNIT_100TH_MM )
175 : {
176 15658 : if ( !bDontConvertNegativeValues || SvxUnoCheckForPositiveValue( aValue ) )
177 15658 : SvxUnoConvertFromMM( eMapUnit, aValue );
178 : }
179 :
180 1586754 : SfxPoolItem *pNewItem = pItem->Clone();
181 :
182 1586754 : sal_uInt8 nMemberId = pMap->nMemberId & (~SFX_METRIC_ITEM);
183 1586754 : if( eMapUnit == SFX_MAPUNIT_100TH_MM )
184 1522152 : nMemberId &= (~CONVERT_TWIPS);
185 :
186 1586754 : if( pNewItem->PutValue( aValue, nMemberId ) )
187 : {
188 : // Set new item in item set
189 1586431 : rSet.Put( *pNewItem, pMap->nWID );
190 : }
191 1586754 : delete pNewItem;
192 : }
193 : }
194 :
195 :
196 317 : uno::Any SvxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry* pMap ) const
197 : {
198 : // Already entered a value? Then finish quickly
199 317 : uno::Any* pUsrAny = GetUsrAnyForID(pMap->nWID);
200 317 : if(pUsrAny)
201 0 : return *pUsrAny;
202 :
203 : // No UsrAny detected yet, generate Default entry and return this
204 317 : const SfxMapUnit eMapUnit = mrItemPool.GetMetric((sal_uInt16)pMap->nWID);
205 317 : sal_uInt8 nMemberId = pMap->nMemberId & (~SFX_METRIC_ITEM);
206 317 : if( eMapUnit == SFX_MAPUNIT_100TH_MM )
207 317 : nMemberId &= (~CONVERT_TWIPS);
208 317 : uno::Any aVal;
209 634 : SfxItemSet aSet( mrItemPool, pMap->nWID, pMap->nWID);
210 :
211 317 : if( (pMap->nWID < OWN_ATTR_VALUE_START) && (pMap->nWID > OWN_ATTR_VALUE_END ) )
212 : {
213 : // Get Default from ItemPool
214 0 : if(SfxItemPool::IsWhich(pMap->nWID))
215 0 : aSet.Put(mrItemPool.GetDefaultItem(pMap->nWID));
216 : }
217 :
218 317 : if(aSet.Count())
219 : {
220 0 : const SfxPoolItem* pItem = NULL;
221 0 : SfxItemState eState = aSet.GetItemState( pMap->nWID, true, &pItem );
222 0 : if(eState >= SfxItemState::DEFAULT && pItem)
223 : {
224 0 : pItem->QueryValue( aVal, nMemberId );
225 0 : const_cast<SvxItemPropertySet*>(this)->AddUsrAnyForID(aVal, pMap->nWID);
226 : }
227 : }
228 :
229 317 : if( pMap->nMemberId & SFX_METRIC_ITEM )
230 : {
231 : // check for needed metric translation
232 0 : if(pMap->nMemberId & SFX_METRIC_ITEM && eMapUnit != SFX_MAPUNIT_100TH_MM)
233 : {
234 0 : SvxUnoConvertToMM( eMapUnit, aVal );
235 : }
236 : }
237 :
238 317 : if ( pMap->aType.getTypeClass() == uno::TypeClass_ENUM &&
239 0 : aVal.getValueType() == ::cppu::UnoType<sal_Int32>::get() )
240 : {
241 : sal_Int32 nEnum;
242 0 : aVal >>= nEnum;
243 :
244 0 : aVal.setValue( &nEnum, pMap->aType );
245 : }
246 :
247 634 : return aVal;
248 : }
249 :
250 :
251 :
252 647 : void SvxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry* pMap, const uno::Any& rVal ) const
253 : {
254 647 : uno::Any* pUsrAny = GetUsrAnyForID(pMap->nWID);
255 647 : if(!pUsrAny)
256 618 : const_cast<SvxItemPropertySet*>(this)->AddUsrAnyForID(rVal, pMap->nWID);
257 : else
258 29 : *pUsrAny = rVal;
259 647 : }
260 :
261 :
262 :
263 2626433 : const SfxItemPropertySimpleEntry* SvxItemPropertySet::getPropertyMapEntry(const OUString &rName) const
264 : {
265 2626433 : return m_aPropertyMap.getByName( rName );
266 : }
267 :
268 :
269 :
270 62257 : uno::Reference< beans::XPropertySetInfo > SvxItemPropertySet::getPropertySetInfo() const
271 : {
272 62257 : if( !m_xInfo.is() )
273 407 : m_xInfo = new SfxItemPropertySetInfo( m_aPropertyMap );
274 62257 : return m_xInfo;
275 : }
276 :
277 :
278 :
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
285 :
286 : /** converts the given any with a metric to 100th/mm if needed */
287 5109 : void SvxUnoConvertToMM( const SfxMapUnit eSourceMapUnit, uno::Any & rMetric ) throw()
288 : {
289 : // map the metric of the itempool to 100th mm
290 5109 : switch(eSourceMapUnit)
291 : {
292 : case SFX_MAPUNIT_TWIP :
293 : {
294 5109 : switch( rMetric.getValueTypeClass() )
295 : {
296 : case uno::TypeClass_BYTE:
297 0 : rMetric <<= (sal_Int8)(TWIPS_TO_MM(*static_cast<sal_Int8 const *>(rMetric.getValue())));
298 0 : break;
299 : case uno::TypeClass_SHORT:
300 0 : rMetric <<= (sal_Int16)(TWIPS_TO_MM(*static_cast<sal_Int16 const *>(rMetric.getValue())));
301 0 : break;
302 : case uno::TypeClass_UNSIGNED_SHORT:
303 0 : rMetric <<= (sal_uInt16)(TWIPS_TO_MM(*static_cast<sal_uInt16 const *>(rMetric.getValue())));
304 0 : break;
305 : case uno::TypeClass_LONG:
306 5109 : rMetric <<= (sal_Int32)(TWIPS_TO_MM(*static_cast<sal_Int32 const *>(rMetric.getValue())));
307 5109 : break;
308 : case uno::TypeClass_UNSIGNED_LONG:
309 0 : rMetric <<= (sal_uInt32)(TWIPS_TO_MM(*static_cast<sal_uInt32 const *>(rMetric.getValue())));
310 0 : break;
311 : default:
312 : OSL_FAIL("AW: Missing unit translation to 100th mm!");
313 : }
314 5109 : break;
315 : }
316 : default:
317 : {
318 : OSL_FAIL("AW: Missing unit translation to 100th mm!");
319 : }
320 : }
321 5109 : }
322 :
323 :
324 :
325 : /** converts the given any with a metric from 100th/mm to the given metric if needed */
326 16228 : void SvxUnoConvertFromMM( const SfxMapUnit eDestinationMapUnit, uno::Any & rMetric ) throw()
327 : {
328 16228 : switch(eDestinationMapUnit)
329 : {
330 : case SFX_MAPUNIT_TWIP :
331 : {
332 16228 : switch( rMetric.getValueTypeClass() )
333 : {
334 : case uno::TypeClass_BYTE:
335 0 : rMetric <<= (sal_Int8)(MM_TO_TWIPS(*static_cast<sal_Int8 const *>(rMetric.getValue())));
336 0 : break;
337 : case uno::TypeClass_SHORT:
338 0 : rMetric <<= (sal_Int16)(MM_TO_TWIPS(*static_cast<sal_Int16 const *>(rMetric.getValue())));
339 0 : break;
340 : case uno::TypeClass_UNSIGNED_SHORT:
341 0 : rMetric <<= (sal_uInt16)(MM_TO_TWIPS(*static_cast<sal_uInt16 const *>(rMetric.getValue())));
342 0 : break;
343 : case uno::TypeClass_LONG:
344 16219 : rMetric <<= (sal_Int32)(MM_TO_TWIPS(*static_cast<sal_Int32 const *>(rMetric.getValue())));
345 16219 : break;
346 : case uno::TypeClass_UNSIGNED_LONG:
347 0 : rMetric <<= (sal_uInt32)(MM_TO_TWIPS(*static_cast<sal_uInt32 const *>(rMetric.getValue())));
348 0 : break;
349 : default:
350 : OSL_FAIL("AW: Missing unit translation to 100th mm!");
351 : }
352 16228 : break;
353 : }
354 : default:
355 : {
356 : OSL_FAIL("AW: Missing unit translation to PoolMetrics!");
357 : }
358 : }
359 16228 : }
360 :
361 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|