merge the formfield patch from ooo-build
[ooovba.git] / svx / source / unodraw / unoipset.cxx
blob25a72b0f8b3347011b3be9548c8d28532acd590d
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: unoipset.cxx,v $
10 * $Revision: 1.28 $
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>
37 #include <hash_map>
38 #include <vector>
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>
47 #include "unoapi.hxx"
48 #include <svx/svdobj.hxx>
50 #include <algorithm>
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
66 sal_uInt16 nWID;
67 uno::Any aAny;
70 DECLARE_LIST( SvxIDPropertyCombineList, SvxIDPropertyCombine * )
72 SvxItemPropertySet::SvxItemPropertySet( const SfxItemPropertyMapEntry* pMap, sal_Bool bConvertTwips )
73 : m_aPropertyMap( pMap ),
74 _pMap(pMap), mbConvertTwips(bConvertTwips)
76 pCombiList = NULL;
79 //----------------------------------------------------------------------
80 SvxItemPropertySet::~SvxItemPropertySet()
83 if(pItemPool)
84 delete pItemPool;
85 pItemPool = NULL;
88 if(pCombiList)
89 delete pCombiList;
90 pCombiList = NULL;
93 //----------------------------------------------------------------------
94 uno::Any* SvxItemPropertySet::GetUsrAnyForID(sal_uInt16 nWID) const
96 if(pCombiList && pCombiList->Count())
98 SvxIDPropertyCombine* pActual = pCombiList->First();
99 while(pActual)
101 if(pActual->nWID == nWID)
102 return &pActual->aAny;
103 pActual = pCombiList->Next();
107 return NULL;
110 //----------------------------------------------------------------------
111 void SvxItemPropertySet::AddUsrAnyForID(const uno::Any& rAny, sal_uInt16 nWID)
113 if(!pCombiList)
114 pCombiList = new SvxIDPropertyCombineList();
116 SvxIDPropertyCombine* pNew = new SvxIDPropertyCombine;
117 pNew->nWID = nWID;
118 pNew->aAny = rAny;
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())
133 if(aSrcIt->nWID)
135 uno::Any* pUsrAny = rPropSet.GetUsrAnyForID(aSrcIt->nWID);
136 if(pUsrAny)
138 // Aequivalenten Eintrag in pDst suchen
139 const SfxItemPropertySimpleEntry* pEntry = m_aPropertyMap.getByName( aSrcIt->sName );
140 if(pEntry)
142 // entry found
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);
149 else
151 if(rSet.GetPool()->IsWhich(pEntry->nWID))
152 rSet.Put(rSet.GetPool()->GetDefaultItem(pEntry->nWID));
154 // setzen
155 setPropertyValue(pEntry, *pUsrAny, rSet);
161 // next entry
162 ++aSrcIt;
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
175 switch( nWID )
177 case XATTR_FILLBMP_SIZEX:
178 case XATTR_FILLBMP_SIZEY:
180 sal_Int32 nValue = 0;
181 if( rVal >>= nValue )
182 bConvert = nValue > 0;
183 break;
187 // the default is to always
188 return bConvert;
191 //----------------------------------------------------------------------
192 uno::Any SvxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry* pMap, const SfxItemSet& rSet ) const
194 uno::Any aVal;
195 if(!pMap || !pMap->nWID)
196 return aVal;
198 // item holen
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
216 if(pItem)
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) )
233 sal_Int32 nEnum;
234 aVal >>= nEnum;
236 aVal.setValue( &nEnum, *pMap->pType );
239 else
241 DBG_ERROR( "No SfxPoolItem found for property!" );
244 return aVal;
247 //----------------------------------------------------------------------
248 void SvxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry* pMap, const uno::Any& rVal, SfxItemSet& rSet ) const
250 if(!pMap || !pMap->nWID)
251 return;
253 // item holen
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)
262 if( pPool == NULL )
264 DBG_ERROR( "No default item and no pool?" );
265 return;
268 pItem = &pPool->GetDefaultItem( pMap->nWID );
271 DBG_ASSERT( pItem, "Got no default for item!" );
272 if( pItem )
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 );
299 delete pNewItem;
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);
308 if(pUsrAny)
309 return *pUsrAny;
311 // Noch kein UsrAny gemerkt, generiere Default-Eintrag und gib
312 // diesen zurueck
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);
320 uno::Any aVal;
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));
330 if(aSet.Count())
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) )
353 sal_Int32 nEnum;
354 aVal >>= nEnum;
356 aVal.setValue( &nEnum, *pMap->pType );
359 return aVal;
362 //----------------------------------------------------------------------
364 void SvxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry* pMap, const uno::Any& rVal ) const
366 uno::Any* pUsrAny = GetUsrAnyForID(pMap->nWID);
367 if(!pUsrAny)
368 ((SvxItemPropertySet*)this)->AddUsrAnyForID(rVal, pMap->nWID);
369 else
370 *pUsrAny = rVal;
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
384 if( !m_xInfo.is() )
385 m_xInfo = new SfxItemPropertySetInfo( &m_aPropertyMap );
386 return m_xInfo;
389 //----------------------------------------------------------------------
391 #ifndef TWIPS_TO_MM
392 #define TWIPS_TO_MM(val) ((val * 127 + 36) / 72)
393 #endif
394 #ifndef MM_TO_TWIPS
395 #define MM_TO_TWIPS(val) ((val * 72 + 63) / 127)
396 #endif
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()));
410 break;
411 case uno::TypeClass_SHORT:
412 rMetric <<= (sal_Int16)(TWIPS_TO_MM(*(sal_Int16*)rMetric.getValue()));
413 break;
414 case uno::TypeClass_UNSIGNED_SHORT:
415 rMetric <<= (sal_uInt16)(TWIPS_TO_MM(*(sal_uInt16*)rMetric.getValue()));
416 break;
417 case uno::TypeClass_LONG:
418 rMetric <<= (sal_Int32)(TWIPS_TO_MM(*(sal_Int32*)rMetric.getValue()));
419 break;
420 case uno::TypeClass_UNSIGNED_LONG:
421 rMetric <<= (sal_uInt32)(TWIPS_TO_MM(*(sal_uInt32*)rMetric.getValue()));
422 break;
423 default:
424 DBG_ERROR("AW: Missing unit translation to 100th mm!");
426 break;
428 default:
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()));
448 break;
449 case uno::TypeClass_SHORT:
450 rMetric <<= (sal_Int16)(MM_TO_TWIPS(*(sal_Int16*)rMetric.getValue()));
451 break;
452 case uno::TypeClass_UNSIGNED_SHORT:
453 rMetric <<= (sal_uInt16)(MM_TO_TWIPS(*(sal_uInt16*)rMetric.getValue()));
454 break;
455 case uno::TypeClass_LONG:
456 rMetric <<= (sal_Int32)(MM_TO_TWIPS(*(sal_Int32*)rMetric.getValue()));
457 break;
458 case uno::TypeClass_UNSIGNED_LONG:
459 rMetric <<= (sal_uInt32)(MM_TO_TWIPS(*(sal_uInt32*)rMetric.getValue()));
460 break;
461 default:
462 DBG_ERROR("AW: Missing unit translation to 100th mm!");
464 break;
466 default:
468 DBG_ERROR("AW: Missing unit translation to PoolMetrics!");