1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: unoipset.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 #include <svtools/eitem.hxx>
35 #include <tools/list.hxx>
39 #include <svtools/itemprop.hxx>
41 #include <svx/unoipset.hxx>
42 #include <svx/svdpool.hxx>
43 #include <svx/svxids.hrc>
44 #include <svx/deflt3d.hxx>
45 #include <svx/unoshprp.hxx>
46 #include <svx/editeng.hxx>
48 #include <svx/svdobj.hxx>
52 using namespace ::com::sun::star
;
53 using namespace ::rtl
;
55 //----------------------------------------------------------------------
57 struct SfxItemPropertyMapEntryHash
59 size_t operator()(const SfxItemPropertyMapEntry
* pMap
) const { return (size_t)pMap
; }
62 //----------------------------------------------------------------------
64 struct SvxIDPropertyCombine
70 DECLARE_LIST( SvxIDPropertyCombineList
, SvxIDPropertyCombine
* )
72 SvxItemPropertySet::SvxItemPropertySet( const SfxItemPropertyMapEntry
* pMap
, sal_Bool bConvertTwips
)
73 : m_aPropertyMap( pMap
),
74 _pMap(pMap
), mbConvertTwips(bConvertTwips
)
79 //----------------------------------------------------------------------
80 SvxItemPropertySet::~SvxItemPropertySet()
93 //----------------------------------------------------------------------
94 uno::Any
* SvxItemPropertySet::GetUsrAnyForID(sal_uInt16 nWID
) const
96 if(pCombiList
&& pCombiList
->Count())
98 SvxIDPropertyCombine
* pActual
= pCombiList
->First();
101 if(pActual
->nWID
== nWID
)
102 return &pActual
->aAny
;
103 pActual
= pCombiList
->Next();
110 //----------------------------------------------------------------------
111 void SvxItemPropertySet::AddUsrAnyForID(const uno::Any
& rAny
, sal_uInt16 nWID
)
114 pCombiList
= new SvxIDPropertyCombineList();
116 SvxIDPropertyCombine
* pNew
= new SvxIDPropertyCombine
;
119 pCombiList
->Insert(pNew
);
122 //----------------------------------------------------------------------
123 void SvxItemPropertySet::ObtainSettingsFromPropertySet(const SvxItemPropertySet
& rPropSet
,
124 SfxItemSet
& rSet
, uno::Reference
< beans::XPropertySet
> xSet
) const
126 if(rPropSet
.AreThereOwnUsrAnys())
128 const SfxItemPropertyMap
* pSrc
= rPropSet
.getPropertyMap();
129 PropertyEntryVector_t aSrcPropVector
= pSrc
->getPropertyEntries();
130 PropertyEntryVector_t::const_iterator aSrcIt
= aSrcPropVector
.begin();
131 while(aSrcIt
!= aSrcPropVector
.end())
135 uno::Any
* pUsrAny
= rPropSet
.GetUsrAnyForID(aSrcIt
->nWID
);
138 // Aequivalenten Eintrag in pDst suchen
139 const SfxItemPropertySimpleEntry
* pEntry
= m_aPropertyMap
.getByName( aSrcIt
->sName
);
143 if(pEntry
->nWID
>= OWN_ATTR_VALUE_START
&& pEntry
->nWID
<= OWN_ATTR_VALUE_END
)
145 // Special ID im PropertySet, kann nur direkt am
146 // Objekt gesetzt werden+
147 xSet
->setPropertyValue( aSrcIt
->sName
, *pUsrAny
);
151 if(rSet
.GetPool()->IsWhich(pEntry
->nWID
))
152 rSet
.Put(rSet
.GetPool()->GetDefaultItem(pEntry
->nWID
));
155 setPropertyValue(pEntry
, *pUsrAny
, rSet
);
167 /** this function checks if a SFX_METRIC_ITEM realy needs to be converted.
168 This check is for items that store either metric values if theire positiv
169 or percentage if theire negativ.
171 sal_Bool
SvxUnoCheckForConversion( const SfxItemSet
&, sal_Int32 nWID
, const uno::Any
& rVal
)
173 sal_Bool bConvert
= sal_True
; // the default is that all metric items must be converted
177 case XATTR_FILLBMP_SIZEX
:
178 case XATTR_FILLBMP_SIZEY
:
180 sal_Int32 nValue
= 0;
181 if( rVal
>>= nValue
)
182 bConvert
= nValue
> 0;
187 // the default is to always
191 //----------------------------------------------------------------------
192 uno::Any
SvxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry
* pMap
, const SfxItemSet
& rSet
) const
195 if(!pMap
|| !pMap
->nWID
)
199 const SfxPoolItem
* pItem
= 0;
200 SfxItemPool
* pPool
= rSet
.GetPool();
202 rSet
.GetItemState( pMap
->nWID
, pMap
->nWID
!= SDRATTR_XMLATTRIBUTES
, &pItem
);
204 if( NULL
== pItem
&& pPool
)
206 pItem
= &(pPool
->GetDefaultItem( pMap
->nWID
));
209 const SfxMapUnit eMapUnit
= pPool
? pPool
->GetMetric((USHORT
)pMap
->nWID
) : SFX_MAPUNIT_100TH_MM
;
211 BYTE nMemberId
= pMap
->nMemberId
& (~SFX_METRIC_ITEM
);
212 if( eMapUnit
== SFX_MAPUNIT_100TH_MM
)
213 nMemberId
&= (~CONVERT_TWIPS
);
215 // item-Wert als UnoAny zurueckgeben
218 pItem
->QueryValue( aVal
, nMemberId
);
220 if( pMap
->nMemberId
& SFX_METRIC_ITEM
)
222 // check for needed metric translation
223 if(pMap
->nMemberId
& SFX_METRIC_ITEM
&& eMapUnit
!= SFX_MAPUNIT_100TH_MM
)
225 if( SvxUnoCheckForConversion( rSet
, pMap
->nWID
, aVal
) )
226 SvxUnoConvertToMM( eMapUnit
, aVal
);
229 // convert typeless SfxEnumItem to enum type
230 else if ( pMap
->pType
->getTypeClass() == uno::TypeClass_ENUM
&&
231 aVal
.getValueType() == ::getCppuType((const sal_Int32
*)0) )
236 aVal
.setValue( &nEnum
, *pMap
->pType
);
241 DBG_ERROR( "No SfxPoolItem found for property!" );
247 //----------------------------------------------------------------------
248 void SvxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry
* pMap
, const uno::Any
& rVal
, SfxItemSet
& rSet
) const
250 if(!pMap
|| !pMap
->nWID
)
254 const SfxPoolItem
* pItem
= 0;
255 SfxPoolItem
*pNewItem
= 0;
256 SfxItemState eState
= rSet
.GetItemState( pMap
->nWID
, sal_True
, &pItem
);
257 SfxItemPool
* pPool
= rSet
.GetPool();
259 // UnoAny in item-Wert stecken
260 if(eState
< SFX_ITEM_DEFAULT
|| pItem
== NULL
)
264 DBG_ERROR( "No default item and no pool?" );
268 pItem
= &pPool
->GetDefaultItem( pMap
->nWID
);
271 DBG_ASSERT( pItem
, "Got no default for item!" );
274 uno::Any
aValue( rVal
);
276 const SfxMapUnit eMapUnit
= pPool
? pPool
->GetMetric((USHORT
)pMap
->nWID
) : SFX_MAPUNIT_100TH_MM
;
278 if( pMap
->nMemberId
& SFX_METRIC_ITEM
)
280 // check for needed metric translation
281 if(pMap
->nMemberId
& SFX_METRIC_ITEM
&& eMapUnit
!= SFX_MAPUNIT_100TH_MM
)
283 if( SvxUnoCheckForConversion( rSet
, pMap
->nWID
, aValue
) )
284 SvxUnoConvertFromMM( eMapUnit
, aValue
);
288 pNewItem
= pItem
->Clone();
290 BYTE nMemberId
= pMap
->nMemberId
& (~SFX_METRIC_ITEM
);
291 if( eMapUnit
== SFX_MAPUNIT_100TH_MM
)
292 nMemberId
&= (~CONVERT_TWIPS
);
294 if( pNewItem
->PutValue( aValue
, nMemberId
) )
296 // neues item in itemset setzen
297 rSet
.Put( *pNewItem
, pMap
->nWID
);
303 //----------------------------------------------------------------------
304 uno::Any
SvxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry
* pMap
) const
306 // Schon ein Wert eingetragen? Dann schnell fertig
307 uno::Any
* pUsrAny
= GetUsrAnyForID(pMap
->nWID
);
311 // Noch kein UsrAny gemerkt, generiere Default-Eintrag und gib
314 SdrItemPool
& rItemPool
= SdrObject::GetGlobalDrawObjectItemPool();
315 const SfxMapUnit eMapUnit
= rItemPool
.GetMetric((USHORT
)pMap
->nWID
);
316 BYTE nMemberId
= pMap
->nMemberId
& (~SFX_METRIC_ITEM
);
317 if( eMapUnit
== SFX_MAPUNIT_100TH_MM
)
318 nMemberId
&= (~CONVERT_TWIPS
);
321 SfxItemSet
aSet( rItemPool
, pMap
->nWID
, pMap
->nWID
);
323 if( (pMap
->nWID
< OWN_ATTR_VALUE_START
) && (pMap
->nWID
> OWN_ATTR_VALUE_END
) )
325 // Default aus ItemPool holen
326 if(rItemPool
.IsWhich(pMap
->nWID
))
327 aSet
.Put(rItemPool
.GetDefaultItem(pMap
->nWID
));
332 const SfxPoolItem
* pItem
= NULL
;
333 SfxItemState eState
= aSet
.GetItemState( pMap
->nWID
, sal_True
, &pItem
);
334 if(eState
>= SFX_ITEM_DEFAULT
&& pItem
)
336 pItem
->QueryValue( aVal
, nMemberId
);
337 ((SvxItemPropertySet
*)this)->AddUsrAnyForID(aVal
, pMap
->nWID
);
341 if( pMap
->nMemberId
& SFX_METRIC_ITEM
)
343 // check for needed metric translation
344 if(pMap
->nMemberId
& SFX_METRIC_ITEM
&& eMapUnit
!= SFX_MAPUNIT_100TH_MM
)
346 SvxUnoConvertToMM( eMapUnit
, aVal
);
350 if ( pMap
->pType
->getTypeClass() == uno::TypeClass_ENUM
&&
351 aVal
.getValueType() == ::getCppuType((const sal_Int32
*)0) )
356 aVal
.setValue( &nEnum
, *pMap
->pType
);
362 //----------------------------------------------------------------------
364 void SvxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry
* pMap
, const uno::Any
& rVal
) const
366 uno::Any
* pUsrAny
= GetUsrAnyForID(pMap
->nWID
);
368 ((SvxItemPropertySet
*)this)->AddUsrAnyForID(rVal
, pMap
->nWID
);
373 //----------------------------------------------------------------------
375 const SfxItemPropertySimpleEntry
* SvxItemPropertySet::getPropertyMapEntry(const OUString
&rName
) const
377 return m_aPropertyMap
.getByName( rName
);
380 //----------------------------------------------------------------------
382 uno::Reference
< beans::XPropertySetInfo
> SvxItemPropertySet::getPropertySetInfo() const
385 m_xInfo
= new SfxItemPropertySetInfo( &m_aPropertyMap
);
389 //----------------------------------------------------------------------
392 #define TWIPS_TO_MM(val) ((val * 127 + 36) / 72)
395 #define MM_TO_TWIPS(val) ((val * 72 + 63) / 127)
398 /** converts the given any with a metric to 100th/mm if needed */
399 void SvxUnoConvertToMM( const SfxMapUnit eSourceMapUnit
, uno::Any
& rMetric
) throw()
401 // map the metric of the itempool to 100th mm
402 switch(eSourceMapUnit
)
404 case SFX_MAPUNIT_TWIP
:
406 switch( rMetric
.getValueTypeClass() )
408 case uno::TypeClass_BYTE
:
409 rMetric
<<= (sal_Int8
)(TWIPS_TO_MM(*(sal_Int8
*)rMetric
.getValue()));
411 case uno::TypeClass_SHORT
:
412 rMetric
<<= (sal_Int16
)(TWIPS_TO_MM(*(sal_Int16
*)rMetric
.getValue()));
414 case uno::TypeClass_UNSIGNED_SHORT
:
415 rMetric
<<= (sal_uInt16
)(TWIPS_TO_MM(*(sal_uInt16
*)rMetric
.getValue()));
417 case uno::TypeClass_LONG
:
418 rMetric
<<= (sal_Int32
)(TWIPS_TO_MM(*(sal_Int32
*)rMetric
.getValue()));
420 case uno::TypeClass_UNSIGNED_LONG
:
421 rMetric
<<= (sal_uInt32
)(TWIPS_TO_MM(*(sal_uInt32
*)rMetric
.getValue()));
424 DBG_ERROR("AW: Missing unit translation to 100th mm!");
430 DBG_ERROR("AW: Missing unit translation to 100th mm!");
435 //----------------------------------------------------------------------
437 /** converts the given any with a metric from 100th/mm to the given metric if needed */
438 void SvxUnoConvertFromMM( const SfxMapUnit eDestinationMapUnit
, uno::Any
& rMetric
) throw()
440 switch(eDestinationMapUnit
)
442 case SFX_MAPUNIT_TWIP
:
444 switch( rMetric
.getValueTypeClass() )
446 case uno::TypeClass_BYTE
:
447 rMetric
<<= (sal_Int8
)(MM_TO_TWIPS(*(sal_Int8
*)rMetric
.getValue()));
449 case uno::TypeClass_SHORT
:
450 rMetric
<<= (sal_Int16
)(MM_TO_TWIPS(*(sal_Int16
*)rMetric
.getValue()));
452 case uno::TypeClass_UNSIGNED_SHORT
:
453 rMetric
<<= (sal_uInt16
)(MM_TO_TWIPS(*(sal_uInt16
*)rMetric
.getValue()));
455 case uno::TypeClass_LONG
:
456 rMetric
<<= (sal_Int32
)(MM_TO_TWIPS(*(sal_Int32
*)rMetric
.getValue()));
458 case uno::TypeClass_UNSIGNED_LONG
:
459 rMetric
<<= (sal_uInt32
)(MM_TO_TWIPS(*(sal_uInt32
*)rMetric
.getValue()));
462 DBG_ERROR("AW: Missing unit translation to 100th mm!");
468 DBG_ERROR("AW: Missing unit translation to PoolMetrics!");