1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
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.
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).
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.
27 ************************************************************************/
29 #include <com/sun/star/beans/XPropertySet.hpp>
30 #include <svl/eitem.hxx>
32 #include <boost/unordered_map.hpp>
33 #include <svl/itemprop.hxx>
35 #include <editeng/unoipset.hxx>
36 #include <editeng/editids.hrc>
37 #include <editeng/editeng.hxx>
38 #include <svl/itempool.hxx>
41 using namespace ::com::sun::star
;
42 using namespace ::rtl
;
46 //----------------------------------------------------------------------
48 struct SfxItemPropertyMapEntryHash
50 size_t operator()(const SfxItemPropertyMapEntry
* pMap
) const { return (size_t)pMap
; }
53 //----------------------------------------------------------------------
55 struct SvxIDPropertyCombine
62 SvxItemPropertySet::SvxItemPropertySet( const SfxItemPropertyMapEntry
* pMap
, SfxItemPool
& rItemPool
, sal_Bool bConvertTwips
)
63 : m_aPropertyMap( pMap
),
64 _pMap(pMap
), mbConvertTwips(bConvertTwips
), mrItemPool( rItemPool
)
68 //----------------------------------------------------------------------
69 SvxItemPropertySet::~SvxItemPropertySet()
74 //----------------------------------------------------------------------
75 uno::Any
* SvxItemPropertySet::GetUsrAnyForID(sal_uInt16 nWID
) const
77 for ( size_t i
= 0, n
= aCombineList
.size(); i
< n
; ++i
)
79 SvxIDPropertyCombine
* pActual
= aCombineList
[ i
];
80 if( pActual
->nWID
== nWID
)
81 return &pActual
->aAny
;
86 //----------------------------------------------------------------------
87 void SvxItemPropertySet::AddUsrAnyForID(const uno::Any
& rAny
, sal_uInt16 nWID
)
89 SvxIDPropertyCombine
* pNew
= new SvxIDPropertyCombine
;
92 aCombineList
.push_back( pNew
);
95 //----------------------------------------------------------------------
97 void SvxItemPropertySet::ClearAllUsrAny()
99 for ( size_t i
= 0, n
= aCombineList
.size(); i
< n
; ++i
)
100 delete aCombineList
[ i
];
101 aCombineList
.clear();
104 //----------------------------------------------------------------------
106 sal_Bool
SvxUnoCheckForPositiveValue( const uno::Any
& rVal
)
108 sal_Bool bConvert
= sal_True
; // the default is that all metric items must be converted
109 sal_Int32 nValue
= 0;
110 if( rVal
>>= nValue
)
111 bConvert
= (nValue
> 0);
116 //----------------------------------------------------------------------
117 uno::Any
SvxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry
* pMap
, const SfxItemSet
& rSet
, bool bSearchInParent
, bool bDontConvertNegativeValues
) const
120 if(!pMap
|| !pMap
->nWID
)
123 const SfxPoolItem
* pItem
= 0;
124 SfxItemPool
* pPool
= rSet
.GetPool();
125 rSet
.GetItemState( pMap
->nWID
, bSearchInParent
, &pItem
);
126 if( NULL
== pItem
&& pPool
)
127 pItem
= &(pPool
->GetDefaultItem( pMap
->nWID
));
129 const SfxMapUnit eMapUnit
= pPool
? pPool
->GetMetric((sal_uInt16
)pMap
->nWID
) : SFX_MAPUNIT_100TH_MM
;
130 sal_uInt8 nMemberId
= pMap
->nMemberId
& (~SFX_METRIC_ITEM
);
131 if( eMapUnit
== SFX_MAPUNIT_100TH_MM
)
132 nMemberId
&= (~CONVERT_TWIPS
);
136 pItem
->QueryValue( aVal
, nMemberId
);
137 if( pMap
->nMemberId
& SFX_METRIC_ITEM
)
139 if( eMapUnit
!= SFX_MAPUNIT_100TH_MM
)
141 if ( !bDontConvertNegativeValues
|| SvxUnoCheckForPositiveValue( aVal
) )
142 SvxUnoConvertToMM( eMapUnit
, aVal
);
145 else if ( pMap
->pType
->getTypeClass() == uno::TypeClass_ENUM
&&
146 aVal
.getValueType() == ::getCppuType((const sal_Int32
*)0) )
148 // convert typeless SfxEnumItem to enum type
151 aVal
.setValue( &nEnum
, *pMap
->pType
);
156 OSL_FAIL( "No SfxPoolItem found for property!" );
162 //----------------------------------------------------------------------
163 void SvxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry
* pMap
, const uno::Any
& rVal
, SfxItemSet
& rSet
, bool bDontConvertNegativeValues
) const
165 if(!pMap
|| !pMap
->nWID
)
169 const SfxPoolItem
* pItem
= 0;
170 SfxPoolItem
*pNewItem
= 0;
171 SfxItemState eState
= rSet
.GetItemState( pMap
->nWID
, sal_True
, &pItem
);
172 SfxItemPool
* pPool
= rSet
.GetPool();
174 // Put UnoAny in the item value
175 if(eState
< SFX_ITEM_DEFAULT
|| pItem
== NULL
)
179 OSL_FAIL( "No default item and no pool?" );
183 pItem
= &pPool
->GetDefaultItem( pMap
->nWID
);
186 DBG_ASSERT( pItem
, "Got no default for item!" );
189 uno::Any
aValue( rVal
);
191 const SfxMapUnit eMapUnit
= pPool
? pPool
->GetMetric((sal_uInt16
)pMap
->nWID
) : SFX_MAPUNIT_100TH_MM
;
193 // check for needed metric translation
194 if( (pMap
->nMemberId
& SFX_METRIC_ITEM
) && eMapUnit
!= SFX_MAPUNIT_100TH_MM
)
196 if ( !bDontConvertNegativeValues
|| SvxUnoCheckForPositiveValue( aValue
) )
197 SvxUnoConvertFromMM( eMapUnit
, aValue
);
200 pNewItem
= pItem
->Clone();
202 sal_uInt8 nMemberId
= pMap
->nMemberId
& (~SFX_METRIC_ITEM
);
203 if( eMapUnit
== SFX_MAPUNIT_100TH_MM
)
204 nMemberId
&= (~CONVERT_TWIPS
);
206 if( pNewItem
->PutValue( aValue
, nMemberId
) )
208 // Set new item in item set
209 rSet
.Put( *pNewItem
, pMap
->nWID
);
215 //----------------------------------------------------------------------
216 uno::Any
SvxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry
* pMap
) const
218 // Already entered a value? Then finish quickly
219 uno::Any
* pUsrAny
= GetUsrAnyForID(pMap
->nWID
);
223 // No UsrAny detected yet, generate Default entry and return this
224 const SfxMapUnit eMapUnit
= mrItemPool
.GetMetric((sal_uInt16
)pMap
->nWID
);
225 sal_uInt8 nMemberId
= pMap
->nMemberId
& (~SFX_METRIC_ITEM
);
226 if( eMapUnit
== SFX_MAPUNIT_100TH_MM
)
227 nMemberId
&= (~CONVERT_TWIPS
);
229 SfxItemSet
aSet( mrItemPool
, pMap
->nWID
, pMap
->nWID
);
231 if( (pMap
->nWID
< OWN_ATTR_VALUE_START
) && (pMap
->nWID
> OWN_ATTR_VALUE_END
) )
233 // Get Default from ItemPool
234 if(mrItemPool
.IsWhich(pMap
->nWID
))
235 aSet
.Put(mrItemPool
.GetDefaultItem(pMap
->nWID
));
240 const SfxPoolItem
* pItem
= NULL
;
241 SfxItemState eState
= aSet
.GetItemState( pMap
->nWID
, sal_True
, &pItem
);
242 if(eState
>= SFX_ITEM_DEFAULT
&& pItem
)
244 pItem
->QueryValue( aVal
, nMemberId
);
245 ((SvxItemPropertySet
*)this)->AddUsrAnyForID(aVal
, pMap
->nWID
);
249 if( pMap
->nMemberId
& SFX_METRIC_ITEM
)
251 // check for needed metric translation
252 if(pMap
->nMemberId
& SFX_METRIC_ITEM
&& eMapUnit
!= SFX_MAPUNIT_100TH_MM
)
254 SvxUnoConvertToMM( eMapUnit
, aVal
);
258 if ( pMap
->pType
->getTypeClass() == uno::TypeClass_ENUM
&&
259 aVal
.getValueType() == ::getCppuType((const sal_Int32
*)0) )
264 aVal
.setValue( &nEnum
, *pMap
->pType
);
270 //----------------------------------------------------------------------
272 void SvxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry
* pMap
, const uno::Any
& rVal
) const
274 uno::Any
* pUsrAny
= GetUsrAnyForID(pMap
->nWID
);
276 ((SvxItemPropertySet
*)this)->AddUsrAnyForID(rVal
, pMap
->nWID
);
281 //----------------------------------------------------------------------
283 const SfxItemPropertySimpleEntry
* SvxItemPropertySet::getPropertyMapEntry(const OUString
&rName
) const
285 return m_aPropertyMap
.getByName( rName
);
288 //----------------------------------------------------------------------
290 uno::Reference
< beans::XPropertySetInfo
> SvxItemPropertySet::getPropertySetInfo() const
293 m_xInfo
= new SfxItemPropertySetInfo( m_aPropertyMap
);
297 //----------------------------------------------------------------------
300 #define TWIPS_TO_MM(val) ((val * 127 + 36) / 72)
303 #define MM_TO_TWIPS(val) ((val * 72 + 63) / 127)
306 /** converts the given any with a metric to 100th/mm if needed */
307 void SvxUnoConvertToMM( const SfxMapUnit eSourceMapUnit
, uno::Any
& rMetric
) throw()
309 // map the metric of the itempool to 100th mm
310 switch(eSourceMapUnit
)
312 case SFX_MAPUNIT_TWIP
:
314 switch( rMetric
.getValueTypeClass() )
316 case uno::TypeClass_BYTE
:
317 rMetric
<<= (sal_Int8
)(TWIPS_TO_MM(*(sal_Int8
*)rMetric
.getValue()));
319 case uno::TypeClass_SHORT
:
320 rMetric
<<= (sal_Int16
)(TWIPS_TO_MM(*(sal_Int16
*)rMetric
.getValue()));
322 case uno::TypeClass_UNSIGNED_SHORT
:
323 rMetric
<<= (sal_uInt16
)(TWIPS_TO_MM(*(sal_uInt16
*)rMetric
.getValue()));
325 case uno::TypeClass_LONG
:
326 rMetric
<<= (sal_Int32
)(TWIPS_TO_MM(*(sal_Int32
*)rMetric
.getValue()));
328 case uno::TypeClass_UNSIGNED_LONG
:
329 rMetric
<<= (sal_uInt32
)(TWIPS_TO_MM(*(sal_uInt32
*)rMetric
.getValue()));
332 OSL_FAIL("AW: Missing unit translation to 100th mm!");
338 OSL_FAIL("AW: Missing unit translation to 100th mm!");
343 //----------------------------------------------------------------------
345 /** converts the given any with a metric from 100th/mm to the given metric if needed */
346 void SvxUnoConvertFromMM( const SfxMapUnit eDestinationMapUnit
, uno::Any
& rMetric
) throw()
348 switch(eDestinationMapUnit
)
350 case SFX_MAPUNIT_TWIP
:
352 switch( rMetric
.getValueTypeClass() )
354 case uno::TypeClass_BYTE
:
355 rMetric
<<= (sal_Int8
)(MM_TO_TWIPS(*(sal_Int8
*)rMetric
.getValue()));
357 case uno::TypeClass_SHORT
:
358 rMetric
<<= (sal_Int16
)(MM_TO_TWIPS(*(sal_Int16
*)rMetric
.getValue()));
360 case uno::TypeClass_UNSIGNED_SHORT
:
361 rMetric
<<= (sal_uInt16
)(MM_TO_TWIPS(*(sal_uInt16
*)rMetric
.getValue()));
363 case uno::TypeClass_LONG
:
364 rMetric
<<= (sal_Int32
)(MM_TO_TWIPS(*(sal_Int32
*)rMetric
.getValue()));
366 case uno::TypeClass_UNSIGNED_LONG
:
367 rMetric
<<= (sal_uInt32
)(MM_TO_TWIPS(*(sal_uInt32
*)rMetric
.getValue()));
370 OSL_FAIL("AW: Missing unit translation to 100th mm!");
376 OSL_FAIL("AW: Missing unit translation to PoolMetrics!");
381 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */