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 <boost/unordered_map.hpp>
24 : #include <svl/itemprop.hxx>
25 :
26 : #include <editeng/unoipset.hxx>
27 : #include <editeng/editids.hrc>
28 : #include <editeng/editeng.hxx>
29 : #include <svl/itempool.hxx>
30 : #include <algorithm>
31 :
32 : using namespace ::com::sun::star;
33 :
34 : using ::std::vector;
35 :
36 2156 : struct SvxIDPropertyCombine
37 : {
38 : sal_uInt16 nWID;
39 : uno::Any aAny;
40 : };
41 :
42 :
43 1304 : SvxItemPropertySet::SvxItemPropertySet( const SfxItemPropertyMapEntry* pMap, SfxItemPool& rItemPool, bool bConvertTwips )
44 : : m_aPropertyMap( pMap ),
45 1304 : _pMap(pMap), mbConvertTwips(bConvertTwips), mrItemPool( rItemPool )
46 : {
47 1304 : }
48 :
49 :
50 2608 : SvxItemPropertySet::~SvxItemPropertySet()
51 : {
52 1304 : ClearAllUsrAny();
53 1304 : }
54 :
55 :
56 65112 : uno::Any* SvxItemPropertySet::GetUsrAnyForID(sal_uInt16 nWID) const
57 : {
58 247720 : for ( size_t i = 0, n = aCombineList.size(); i < n; ++i )
59 : {
60 183786 : SvxIDPropertyCombine* pActual = aCombineList[ i ];
61 183786 : if( pActual->nWID == nWID )
62 1178 : return &pActual->aAny;
63 : }
64 63934 : return NULL;
65 : }
66 :
67 :
68 1078 : void SvxItemPropertySet::AddUsrAnyForID(const uno::Any& rAny, sal_uInt16 nWID)
69 : {
70 1078 : SvxIDPropertyCombine* pNew = new SvxIDPropertyCombine;
71 1078 : pNew->nWID = nWID;
72 1078 : pNew->aAny = rAny;
73 1078 : aCombineList.push_back( pNew );
74 1078 : }
75 :
76 :
77 :
78 1684 : void SvxItemPropertySet::ClearAllUsrAny()
79 : {
80 2762 : for ( size_t i = 0, n = aCombineList.size(); i < n; ++i )
81 1078 : delete aCombineList[ i ];
82 1684 : aCombineList.clear();
83 1684 : }
84 :
85 :
86 :
87 56 : bool SvxUnoCheckForPositiveValue( const uno::Any& rVal )
88 : {
89 56 : bool bConvert = true; // the default is that all metric items must be converted
90 56 : sal_Int32 nValue = 0;
91 56 : if( rVal >>= nValue )
92 56 : bConvert = (nValue > 0);
93 56 : return bConvert;
94 : }
95 :
96 :
97 :
98 132005 : uno::Any SvxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry* pMap, const SfxItemSet& rSet, bool bSearchInParent, bool bDontConvertNegativeValues ) const
99 : {
100 132005 : uno::Any aVal;
101 132005 : if(!pMap || !pMap->nWID)
102 0 : return aVal;
103 :
104 132005 : const SfxPoolItem* pItem = 0;
105 132005 : SfxItemPool* pPool = rSet.GetPool();
106 132005 : rSet.GetItemState( pMap->nWID, bSearchInParent, &pItem );
107 132005 : if( NULL == pItem && pPool )
108 12547 : pItem = &(pPool->GetDefaultItem( pMap->nWID ));
109 :
110 132005 : const SfxMapUnit eMapUnit = pPool ? pPool->GetMetric((sal_uInt16)pMap->nWID) : SFX_MAPUNIT_100TH_MM;
111 132005 : sal_uInt8 nMemberId = pMap->nMemberId & (~SFX_METRIC_ITEM);
112 132005 : if( eMapUnit == SFX_MAPUNIT_100TH_MM )
113 66162 : nMemberId &= (~CONVERT_TWIPS);
114 :
115 132005 : if(pItem)
116 : {
117 132005 : pItem->QueryValue( aVal, nMemberId );
118 132005 : if( pMap->nMemberId & SFX_METRIC_ITEM )
119 : {
120 22869 : if( eMapUnit != SFX_MAPUNIT_100TH_MM )
121 : {
122 9367 : if ( !bDontConvertNegativeValues || SvxUnoCheckForPositiveValue( aVal ) )
123 9311 : SvxUnoConvertToMM( eMapUnit, aVal );
124 : }
125 : }
126 133488 : else if ( pMap->aType.getTypeClass() == uno::TypeClass_ENUM &&
127 24352 : aVal.getValueType() == ::cppu::UnoType<sal_Int32>::get() )
128 : {
129 : // convert typeless SfxEnumItem to enum type
130 : sal_Int32 nEnum;
131 1048 : aVal >>= nEnum;
132 1048 : aVal.setValue( &nEnum, pMap->aType );
133 : }
134 : }
135 : else
136 : {
137 : OSL_FAIL( "No SfxPoolItem found for property!" );
138 : }
139 :
140 132005 : return aVal;
141 : }
142 :
143 :
144 1178822 : void SvxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry* pMap, const uno::Any& rVal, SfxItemSet& rSet, bool bDontConvertNegativeValues ) const
145 : {
146 1178822 : if(!pMap || !pMap->nWID)
147 0 : return;
148 :
149 : // Get item
150 1178822 : const SfxPoolItem* pItem = 0;
151 1178822 : SfxItemState eState = rSet.GetItemState( pMap->nWID, true, &pItem );
152 1178822 : SfxItemPool* pPool = rSet.GetPool();
153 :
154 : // Put UnoAny in the item value
155 1178822 : if(eState < SfxItemState::DEFAULT || pItem == NULL)
156 : {
157 12 : if( pPool == NULL )
158 : {
159 : OSL_FAIL( "No default item and no pool?" );
160 0 : return;
161 : }
162 :
163 12 : pItem = &pPool->GetDefaultItem( pMap->nWID );
164 : }
165 :
166 : DBG_ASSERT( pItem, "Got no default for item!" );
167 1178822 : if( pItem )
168 : {
169 1178822 : uno::Any aValue( rVal );
170 :
171 1178822 : const SfxMapUnit eMapUnit = pPool ? pPool->GetMetric((sal_uInt16)pMap->nWID) : SFX_MAPUNIT_100TH_MM;
172 :
173 : // check for needed metric translation
174 1178822 : if( (pMap->nMemberId & SFX_METRIC_ITEM) && eMapUnit != SFX_MAPUNIT_100TH_MM )
175 : {
176 27876 : if ( !bDontConvertNegativeValues || SvxUnoCheckForPositiveValue( aValue ) )
177 27876 : SvxUnoConvertFromMM( eMapUnit, aValue );
178 : }
179 :
180 1178822 : SfxPoolItem *pNewItem = pItem->Clone();
181 :
182 1178822 : sal_uInt8 nMemberId = pMap->nMemberId & (~SFX_METRIC_ITEM);
183 1178822 : if( eMapUnit == SFX_MAPUNIT_100TH_MM )
184 1065760 : nMemberId &= (~CONVERT_TWIPS);
185 :
186 1178822 : if( pNewItem->PutValue( aValue, nMemberId ) )
187 : {
188 : // Set new item in item set
189 1178703 : rSet.Put( *pNewItem, pMap->nWID );
190 : }
191 1178822 : delete pNewItem;
192 : }
193 : }
194 :
195 :
196 600 : uno::Any SvxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry* pMap ) const
197 : {
198 : // Already entered a value? Then finish quickly
199 600 : uno::Any* pUsrAny = GetUsrAnyForID(pMap->nWID);
200 600 : if(pUsrAny)
201 0 : return *pUsrAny;
202 :
203 : // No UsrAny detected yet, generate Default entry and return this
204 600 : const SfxMapUnit eMapUnit = mrItemPool.GetMetric((sal_uInt16)pMap->nWID);
205 600 : sal_uInt8 nMemberId = pMap->nMemberId & (~SFX_METRIC_ITEM);
206 600 : if( eMapUnit == SFX_MAPUNIT_100TH_MM )
207 600 : nMemberId &= (~CONVERT_TWIPS);
208 600 : uno::Any aVal;
209 1200 : SfxItemSet aSet( mrItemPool, pMap->nWID, pMap->nWID);
210 :
211 600 : 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 600 : 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 : ((SvxItemPropertySet*)this)->AddUsrAnyForID(aVal, pMap->nWID);
226 : }
227 : }
228 :
229 600 : 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 600 : 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 1200 : return aVal;
248 : }
249 :
250 :
251 :
252 1134 : void SvxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry* pMap, const uno::Any& rVal ) const
253 : {
254 1134 : uno::Any* pUsrAny = GetUsrAnyForID(pMap->nWID);
255 1134 : if(!pUsrAny)
256 1078 : ((SvxItemPropertySet*)this)->AddUsrAnyForID(rVal, pMap->nWID);
257 : else
258 56 : *pUsrAny = rVal;
259 1134 : }
260 :
261 :
262 :
263 2233198 : const SfxItemPropertySimpleEntry* SvxItemPropertySet::getPropertyMapEntry(const OUString &rName) const
264 : {
265 2233198 : return m_aPropertyMap.getByName( rName );
266 : }
267 :
268 :
269 :
270 101326 : uno::Reference< beans::XPropertySetInfo > SvxItemPropertySet::getPropertySetInfo() const
271 : {
272 101326 : if( !m_xInfo.is() )
273 612 : m_xInfo = new SfxItemPropertySetInfo( m_aPropertyMap );
274 101326 : 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 9443 : void SvxUnoConvertToMM( const SfxMapUnit eSourceMapUnit, uno::Any & rMetric ) throw()
288 : {
289 : // map the metric of the itempool to 100th mm
290 9443 : switch(eSourceMapUnit)
291 : {
292 : case SFX_MAPUNIT_TWIP :
293 : {
294 9443 : switch( rMetric.getValueTypeClass() )
295 : {
296 : case uno::TypeClass_BYTE:
297 0 : rMetric <<= (sal_Int8)(TWIPS_TO_MM(*(sal_Int8*)rMetric.getValue()));
298 0 : break;
299 : case uno::TypeClass_SHORT:
300 0 : rMetric <<= (sal_Int16)(TWIPS_TO_MM(*(sal_Int16*)rMetric.getValue()));
301 0 : break;
302 : case uno::TypeClass_UNSIGNED_SHORT:
303 0 : rMetric <<= (sal_uInt16)(TWIPS_TO_MM(*(sal_uInt16*)rMetric.getValue()));
304 0 : break;
305 : case uno::TypeClass_LONG:
306 9431 : rMetric <<= (sal_Int32)(TWIPS_TO_MM(*(sal_Int32*)rMetric.getValue()));
307 9431 : break;
308 : case uno::TypeClass_UNSIGNED_LONG:
309 0 : rMetric <<= (sal_uInt32)(TWIPS_TO_MM(*(sal_uInt32*)rMetric.getValue()));
310 0 : break;
311 : default:
312 : OSL_FAIL("AW: Missing unit translation to 100th mm!");
313 : }
314 9443 : break;
315 : }
316 : default:
317 : {
318 : OSL_FAIL("AW: Missing unit translation to 100th mm!");
319 : }
320 : }
321 9443 : }
322 :
323 :
324 :
325 : /** converts the given any with a metric from 100th/mm to the given metric if needed */
326 28494 : void SvxUnoConvertFromMM( const SfxMapUnit eDestinationMapUnit, uno::Any & rMetric ) throw()
327 : {
328 28494 : switch(eDestinationMapUnit)
329 : {
330 : case SFX_MAPUNIT_TWIP :
331 : {
332 28494 : switch( rMetric.getValueTypeClass() )
333 : {
334 : case uno::TypeClass_BYTE:
335 0 : rMetric <<= (sal_Int8)(MM_TO_TWIPS(*(sal_Int8*)rMetric.getValue()));
336 0 : break;
337 : case uno::TypeClass_SHORT:
338 0 : rMetric <<= (sal_Int16)(MM_TO_TWIPS(*(sal_Int16*)rMetric.getValue()));
339 0 : break;
340 : case uno::TypeClass_UNSIGNED_SHORT:
341 0 : rMetric <<= (sal_uInt16)(MM_TO_TWIPS(*(sal_uInt16*)rMetric.getValue()));
342 0 : break;
343 : case uno::TypeClass_LONG:
344 28488 : rMetric <<= (sal_Int32)(MM_TO_TWIPS(*(sal_Int32*)rMetric.getValue()));
345 28488 : break;
346 : case uno::TypeClass_UNSIGNED_LONG:
347 0 : rMetric <<= (sal_uInt32)(MM_TO_TWIPS(*(sal_uInt32*)rMetric.getValue()));
348 0 : break;
349 : default:
350 : OSL_FAIL("AW: Missing unit translation to 100th mm!");
351 : }
352 28494 : break;
353 : }
354 : default:
355 : {
356 : OSL_FAIL("AW: Missing unit translation to PoolMetrics!");
357 : }
358 : }
359 28494 : }
360 :
361 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|