Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
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.
15 : : *
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).
21 : : *
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.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <com/sun/star/beans/XPropertySet.hpp>
30 : : #include <svl/eitem.hxx>
31 : :
32 : : #include <boost/unordered_map.hpp>
33 : : #include <svl/itemprop.hxx>
34 : :
35 : : #include <editeng/unoipset.hxx>
36 : : #include <editeng/editids.hrc>
37 : : #include <editeng/editeng.hxx>
38 : : #include <svl/itempool.hxx>
39 : : #include <algorithm>
40 : :
41 : : using namespace ::com::sun::star;
42 : : using namespace ::rtl;
43 : :
44 : : using ::std::vector;
45 : :
46 : : //----------------------------------------------------------------------
47 : :
48 : : struct SfxItemPropertyMapEntryHash
49 : : {
50 : : size_t operator()(const SfxItemPropertyMapEntry* pMap) const { return (size_t)pMap; }
51 : : };
52 : :
53 : : //----------------------------------------------------------------------
54 : :
55 : 316 : struct SvxIDPropertyCombine
56 : : {
57 : : sal_uInt16 nWID;
58 : : uno::Any aAny;
59 : : };
60 : :
61 : :
62 : 670 : SvxItemPropertySet::SvxItemPropertySet( const SfxItemPropertyMapEntry* pMap, SfxItemPool& rItemPool, sal_Bool bConvertTwips )
63 : : : m_aPropertyMap( pMap ),
64 [ + - ]: 670 : _pMap(pMap), mbConvertTwips(bConvertTwips), mrItemPool( rItemPool )
65 : : {
66 : 670 : }
67 : :
68 : : //----------------------------------------------------------------------
69 : 670 : SvxItemPropertySet::~SvxItemPropertySet()
70 : : {
71 [ + - ]: 670 : ClearAllUsrAny();
72 : 670 : }
73 : :
74 : : //----------------------------------------------------------------------
75 : 11157 : uno::Any* SvxItemPropertySet::GetUsrAnyForID(sal_uInt16 nWID) const
76 : : {
77 [ + + ]: 36386 : for ( size_t i = 0, n = aCombineList.size(); i < n; ++i )
78 : : {
79 : 25405 : SvxIDPropertyCombine* pActual = aCombineList[ i ];
80 [ + + ]: 25405 : if( pActual->nWID == nWID )
81 : 176 : return &pActual->aAny;
82 : : }
83 : 11157 : return NULL;
84 : : }
85 : :
86 : : //----------------------------------------------------------------------
87 : 158 : void SvxItemPropertySet::AddUsrAnyForID(const uno::Any& rAny, sal_uInt16 nWID)
88 : : {
89 [ + - ]: 158 : SvxIDPropertyCombine* pNew = new SvxIDPropertyCombine;
90 : 158 : pNew->nWID = nWID;
91 : 158 : pNew->aAny = rAny;
92 [ + - ]: 158 : aCombineList.push_back( pNew );
93 : 158 : }
94 : :
95 : : //----------------------------------------------------------------------
96 : :
97 : 741 : void SvxItemPropertySet::ClearAllUsrAny()
98 : : {
99 [ + + ]: 899 : for ( size_t i = 0, n = aCombineList.size(); i < n; ++i )
100 [ + - ]: 158 : delete aCombineList[ i ];
101 : 741 : aCombineList.clear();
102 : 741 : }
103 : :
104 : : //----------------------------------------------------------------------
105 : :
106 : 0 : sal_Bool SvxUnoCheckForPositiveValue( const uno::Any& rVal )
107 : : {
108 : 0 : sal_Bool bConvert = sal_True; // the default is that all metric items must be converted
109 : 0 : sal_Int32 nValue = 0;
110 [ # # ]: 0 : if( rVal >>= nValue )
111 : 0 : bConvert = (nValue > 0);
112 : 0 : return bConvert;
113 : : }
114 : :
115 : :
116 : : //----------------------------------------------------------------------
117 : 33179 : uno::Any SvxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry* pMap, const SfxItemSet& rSet, bool bSearchInParent, bool bDontConvertNegativeValues ) const
118 : : {
119 : 33179 : uno::Any aVal;
120 [ + - ][ + - ]: 33179 : if(!pMap || !pMap->nWID)
121 : : return aVal;
122 : :
123 : 33179 : const SfxPoolItem* pItem = 0;
124 : 33179 : SfxItemPool* pPool = rSet.GetPool();
125 [ + - ]: 33179 : rSet.GetItemState( pMap->nWID, bSearchInParent, &pItem );
126 [ + + ][ + - ]: 33179 : if( NULL == pItem && pPool )
127 [ + - ]: 9962 : pItem = &(pPool->GetDefaultItem( pMap->nWID ));
128 : :
129 [ + - ][ + - ]: 33179 : const SfxMapUnit eMapUnit = pPool ? pPool->GetMetric((sal_uInt16)pMap->nWID) : SFX_MAPUNIT_100TH_MM;
130 : 33179 : sal_uInt8 nMemberId = pMap->nMemberId & (~SFX_METRIC_ITEM);
131 [ + + ]: 33179 : if( eMapUnit == SFX_MAPUNIT_100TH_MM )
132 : 20684 : nMemberId &= (~CONVERT_TWIPS);
133 : :
134 [ + - ]: 33179 : if(pItem)
135 : : {
136 [ + - ]: 33179 : pItem->QueryValue( aVal, nMemberId );
137 [ + + ]: 33179 : if( pMap->nMemberId & SFX_METRIC_ITEM )
138 : : {
139 [ + + ]: 4880 : if( eMapUnit != SFX_MAPUNIT_100TH_MM )
140 : : {
141 [ - + ][ # # ]: 1004 : if ( !bDontConvertNegativeValues || SvxUnoCheckForPositiveValue( aVal ) )
[ + - ]
142 : 1004 : SvxUnoConvertToMM( eMapUnit, aVal );
143 : : }
144 : : }
145 [ + + + + ]: 31860 : else if ( pMap->pType->getTypeClass() == uno::TypeClass_ENUM &&
[ + + ]
146 [ + - ]: 3561 : aVal.getValueType() == ::getCppuType((const sal_Int32*)0) )
147 : : {
148 : : // convert typeless SfxEnumItem to enum type
149 : : sal_Int32 nEnum;
150 : 216 : aVal >>= nEnum;
151 : 33179 : aVal.setValue( &nEnum, *pMap->pType );
152 : : }
153 : : }
154 : : else
155 : : {
156 : : OSL_FAIL( "No SfxPoolItem found for property!" );
157 : : }
158 : :
159 : 0 : return aVal;
160 : : }
161 : :
162 : : //----------------------------------------------------------------------
163 : 1432681 : void SvxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry* pMap, const uno::Any& rVal, SfxItemSet& rSet, bool bDontConvertNegativeValues ) const
164 : : {
165 [ + - ][ + - ]: 1432681 : if(!pMap || !pMap->nWID)
166 : : return;
167 : :
168 : : // Get item
169 : 1432681 : const SfxPoolItem* pItem = 0;
170 : 1432681 : SfxPoolItem *pNewItem = 0;
171 [ + - ]: 1432681 : SfxItemState eState = rSet.GetItemState( pMap->nWID, sal_True, &pItem );
172 : 1432681 : SfxItemPool* pPool = rSet.GetPool();
173 : :
174 : : // Put UnoAny in the item value
175 [ - + ][ + - ]: 1432681 : if(eState < SFX_ITEM_DEFAULT || pItem == NULL)
176 : : {
177 [ # # ]: 0 : if( pPool == NULL )
178 : : {
179 : : OSL_FAIL( "No default item and no pool?" );
180 : : return;
181 : : }
182 : :
183 [ # # ]: 0 : pItem = &pPool->GetDefaultItem( pMap->nWID );
184 : : }
185 : :
186 : : DBG_ASSERT( pItem, "Got no default for item!" );
187 [ + - ]: 1432681 : if( pItem )
188 : : {
189 : 1432681 : uno::Any aValue( rVal );
190 : :
191 [ + - ][ + - ]: 1432681 : const SfxMapUnit eMapUnit = pPool ? pPool->GetMetric((sal_uInt16)pMap->nWID) : SFX_MAPUNIT_100TH_MM;
192 : :
193 : : // check for needed metric translation
194 [ + + ][ + + ]: 1432681 : if( (pMap->nMemberId & SFX_METRIC_ITEM) && eMapUnit != SFX_MAPUNIT_100TH_MM )
195 : : {
196 [ - + ][ # # ]: 254 : if ( !bDontConvertNegativeValues || SvxUnoCheckForPositiveValue( aValue ) )
[ + - ]
197 : 254 : SvxUnoConvertFromMM( eMapUnit, aValue );
198 : : }
199 : :
200 [ + - ]: 1432681 : pNewItem = pItem->Clone();
201 : :
202 : 1432681 : sal_uInt8 nMemberId = pMap->nMemberId & (~SFX_METRIC_ITEM);
203 [ + + ]: 1432681 : if( eMapUnit == SFX_MAPUNIT_100TH_MM )
204 : 1428496 : nMemberId &= (~CONVERT_TWIPS);
205 : :
206 [ + - ][ + + ]: 1432681 : if( pNewItem->PutValue( aValue, nMemberId ) )
207 : : {
208 : : // Set new item in item set
209 [ + - ]: 1432362 : rSet.Put( *pNewItem, pMap->nWID );
210 : : }
211 [ + - ][ + - ]: 1432681 : delete pNewItem;
212 : : }
213 : : }
214 : :
215 : : //----------------------------------------------------------------------
216 : 0 : uno::Any SvxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry* pMap ) const
217 : : {
218 : : // Already entered a value? Then finish quickly
219 [ # # ]: 0 : uno::Any* pUsrAny = GetUsrAnyForID(pMap->nWID);
220 [ # # ]: 0 : if(pUsrAny)
221 : 0 : return *pUsrAny;
222 : :
223 : : // No UsrAny detected yet, generate Default entry and return this
224 [ # # ]: 0 : const SfxMapUnit eMapUnit = mrItemPool.GetMetric((sal_uInt16)pMap->nWID);
225 : 0 : sal_uInt8 nMemberId = pMap->nMemberId & (~SFX_METRIC_ITEM);
226 [ # # ]: 0 : if( eMapUnit == SFX_MAPUNIT_100TH_MM )
227 : 0 : nMemberId &= (~CONVERT_TWIPS);
228 : 0 : uno::Any aVal;
229 [ # # ]: 0 : SfxItemSet aSet( mrItemPool, pMap->nWID, pMap->nWID);
230 : :
231 [ # # ][ # # ]: 0 : if( (pMap->nWID < OWN_ATTR_VALUE_START) && (pMap->nWID > OWN_ATTR_VALUE_END ) )
232 : : {
233 : : // Get Default from ItemPool
234 [ # # ]: 0 : if(mrItemPool.IsWhich(pMap->nWID))
235 [ # # ][ # # ]: 0 : aSet.Put(mrItemPool.GetDefaultItem(pMap->nWID));
236 : : }
237 : :
238 [ # # ]: 0 : if(aSet.Count())
239 : : {
240 : 0 : const SfxPoolItem* pItem = NULL;
241 [ # # ]: 0 : SfxItemState eState = aSet.GetItemState( pMap->nWID, sal_True, &pItem );
242 [ # # ][ # # ]: 0 : if(eState >= SFX_ITEM_DEFAULT && pItem)
243 : : {
244 [ # # ]: 0 : pItem->QueryValue( aVal, nMemberId );
245 [ # # ]: 0 : ((SvxItemPropertySet*)this)->AddUsrAnyForID(aVal, pMap->nWID);
246 : : }
247 : : }
248 : :
249 [ # # ]: 0 : if( pMap->nMemberId & SFX_METRIC_ITEM )
250 : : {
251 : : // check for needed metric translation
252 [ # # ][ # # ]: 0 : if(pMap->nMemberId & SFX_METRIC_ITEM && eMapUnit != SFX_MAPUNIT_100TH_MM)
253 : : {
254 : 0 : SvxUnoConvertToMM( eMapUnit, aVal );
255 : : }
256 : : }
257 : :
258 [ # # # # ]: 0 : if ( pMap->pType->getTypeClass() == uno::TypeClass_ENUM &&
[ # # ]
259 [ # # ]: 0 : aVal.getValueType() == ::getCppuType((const sal_Int32*)0) )
260 : : {
261 : : sal_Int32 nEnum;
262 : 0 : aVal >>= nEnum;
263 : :
264 : 0 : aVal.setValue( &nEnum, *pMap->pType );
265 : : }
266 : :
267 [ # # ]: 0 : return aVal;
268 : : }
269 : :
270 : : //----------------------------------------------------------------------
271 : :
272 : 176 : void SvxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry* pMap, const uno::Any& rVal ) const
273 : : {
274 : 176 : uno::Any* pUsrAny = GetUsrAnyForID(pMap->nWID);
275 [ + + ]: 176 : if(!pUsrAny)
276 : 158 : ((SvxItemPropertySet*)this)->AddUsrAnyForID(rVal, pMap->nWID);
277 : : else
278 : 18 : *pUsrAny = rVal;
279 : 176 : }
280 : :
281 : : //----------------------------------------------------------------------
282 : :
283 : 1776548 : const SfxItemPropertySimpleEntry* SvxItemPropertySet::getPropertyMapEntry(const OUString &rName) const
284 : : {
285 : 1776548 : return m_aPropertyMap.getByName( rName );
286 : : }
287 : :
288 : : //----------------------------------------------------------------------
289 : :
290 : 4850 : uno::Reference< beans::XPropertySetInfo > SvxItemPropertySet::getPropertySetInfo() const
291 : : {
292 [ + + ]: 4850 : if( !m_xInfo.is() )
293 [ + - ][ + - ]: 233 : m_xInfo = new SfxItemPropertySetInfo( m_aPropertyMap );
294 : 4850 : return m_xInfo;
295 : : }
296 : :
297 : : //----------------------------------------------------------------------
298 : :
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
305 : :
306 : : /** converts the given any with a metric to 100th/mm if needed */
307 : 1046 : void SvxUnoConvertToMM( const SfxMapUnit eSourceMapUnit, uno::Any & rMetric ) throw()
308 : : {
309 : : // map the metric of the itempool to 100th mm
310 [ + - ]: 1046 : switch(eSourceMapUnit)
311 : : {
312 : : case SFX_MAPUNIT_TWIP :
313 : : {
314 [ - - - + : 1046 : switch( rMetric.getValueTypeClass() )
- - ]
315 : : {
316 : : case uno::TypeClass_BYTE:
317 [ # # ]: 0 : rMetric <<= (sal_Int8)(TWIPS_TO_MM(*(sal_Int8*)rMetric.getValue()));
318 : 0 : break;
319 : : case uno::TypeClass_SHORT:
320 [ # # ]: 0 : rMetric <<= (sal_Int16)(TWIPS_TO_MM(*(sal_Int16*)rMetric.getValue()));
321 : 0 : break;
322 : : case uno::TypeClass_UNSIGNED_SHORT:
323 [ # # ]: 0 : rMetric <<= (sal_uInt16)(TWIPS_TO_MM(*(sal_uInt16*)rMetric.getValue()));
324 : 0 : break;
325 : : case uno::TypeClass_LONG:
326 [ + - ]: 1046 : rMetric <<= (sal_Int32)(TWIPS_TO_MM(*(sal_Int32*)rMetric.getValue()));
327 : 1046 : break;
328 : : case uno::TypeClass_UNSIGNED_LONG:
329 [ # # ]: 0 : rMetric <<= (sal_uInt32)(TWIPS_TO_MM(*(sal_uInt32*)rMetric.getValue()));
330 : 0 : break;
331 : : default:
332 : : OSL_FAIL("AW: Missing unit translation to 100th mm!");
333 : : }
334 : 1046 : break;
335 : : }
336 : : default:
337 : : {
338 : : OSL_FAIL("AW: Missing unit translation to 100th mm!");
339 : : }
340 : : }
341 : 1046 : }
342 : :
343 : : //----------------------------------------------------------------------
344 : :
345 : : /** converts the given any with a metric from 100th/mm to the given metric if needed */
346 : 380 : void SvxUnoConvertFromMM( const SfxMapUnit eDestinationMapUnit, uno::Any & rMetric ) throw()
347 : : {
348 [ + - ]: 380 : switch(eDestinationMapUnit)
349 : : {
350 : : case SFX_MAPUNIT_TWIP :
351 : : {
352 [ - - - + : 380 : switch( rMetric.getValueTypeClass() )
- - ]
353 : : {
354 : : case uno::TypeClass_BYTE:
355 [ # # ]: 0 : rMetric <<= (sal_Int8)(MM_TO_TWIPS(*(sal_Int8*)rMetric.getValue()));
356 : 0 : break;
357 : : case uno::TypeClass_SHORT:
358 [ # # ]: 0 : rMetric <<= (sal_Int16)(MM_TO_TWIPS(*(sal_Int16*)rMetric.getValue()));
359 : 0 : break;
360 : : case uno::TypeClass_UNSIGNED_SHORT:
361 [ # # ]: 0 : rMetric <<= (sal_uInt16)(MM_TO_TWIPS(*(sal_uInt16*)rMetric.getValue()));
362 : 0 : break;
363 : : case uno::TypeClass_LONG:
364 [ + - ]: 380 : rMetric <<= (sal_Int32)(MM_TO_TWIPS(*(sal_Int32*)rMetric.getValue()));
365 : 380 : break;
366 : : case uno::TypeClass_UNSIGNED_LONG:
367 [ # # ]: 0 : rMetric <<= (sal_uInt32)(MM_TO_TWIPS(*(sal_uInt32*)rMetric.getValue()));
368 : 0 : break;
369 : : default:
370 : : OSL_FAIL("AW: Missing unit translation to 100th mm!");
371 : : }
372 : 380 : break;
373 : : }
374 : : default:
375 : : {
376 : : OSL_FAIL("AW: Missing unit translation to PoolMetrics!");
377 : : }
378 : : }
379 : 380 : }
380 : :
381 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|