summaryrefslogtreecommitdiff
path: root/editeng/source/uno/unoipset.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'editeng/source/uno/unoipset.cxx')
-rw-r--r--editeng/source/uno/unoipset.cxx391
1 files changed, 391 insertions, 0 deletions
diff --git a/editeng/source/uno/unoipset.cxx b/editeng/source/uno/unoipset.cxx
new file mode 100644
index 000000000000..39ab3507c5d3
--- /dev/null
+++ b/editeng/source/uno/unoipset.cxx
@@ -0,0 +1,391 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_editeng.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <svl/eitem.hxx>
+#include <tools/list.hxx>
+
+#include <hash_map>
+#include <vector>
+#include <svl/itemprop.hxx>
+
+#include <editeng/unoipset.hxx>
+#include <editeng/editids.hrc>
+#include <editeng/editeng.hxx>
+#include <svl/itempool.hxx>
+#include <algorithm>
+
+using namespace ::com::sun::star;
+using namespace ::rtl;
+
+//----------------------------------------------------------------------
+
+struct SfxItemPropertyMapEntryHash
+{
+ size_t operator()(const SfxItemPropertyMapEntry* pMap) const { return (size_t)pMap; }
+};
+
+//----------------------------------------------------------------------
+
+struct SvxIDPropertyCombine
+{
+ sal_uInt16 nWID;
+ uno::Any aAny;
+};
+
+DECLARE_LIST( SvxIDPropertyCombineList, SvxIDPropertyCombine * )
+
+SvxItemPropertySet::SvxItemPropertySet( const SfxItemPropertyMapEntry* pMap, SfxItemPool& rItemPool, sal_Bool bConvertTwips )
+: m_aPropertyMap( pMap ),
+ _pMap(pMap), mbConvertTwips(bConvertTwips), mrItemPool( rItemPool )
+{
+ pCombiList = NULL;
+}
+
+//----------------------------------------------------------------------
+SvxItemPropertySet::~SvxItemPropertySet()
+{
+/*
+ if(pItemPool)
+ delete pItemPool;
+ pItemPool = NULL;
+*/
+
+ if(pCombiList)
+ delete pCombiList;
+ pCombiList = NULL;
+}
+
+//----------------------------------------------------------------------
+uno::Any* SvxItemPropertySet::GetUsrAnyForID(sal_uInt16 nWID) const
+{
+ if(pCombiList && pCombiList->Count())
+ {
+ SvxIDPropertyCombine* pActual = pCombiList->First();
+ while(pActual)
+ {
+ if(pActual->nWID == nWID)
+ return &pActual->aAny;
+ pActual = pCombiList->Next();
+
+ }
+ }
+ return NULL;
+}
+
+//----------------------------------------------------------------------
+void SvxItemPropertySet::AddUsrAnyForID(const uno::Any& rAny, sal_uInt16 nWID)
+{
+ if(!pCombiList)
+ pCombiList = new SvxIDPropertyCombineList();
+
+ SvxIDPropertyCombine* pNew = new SvxIDPropertyCombine;
+ pNew->nWID = nWID;
+ pNew->aAny = rAny;
+ pCombiList->Insert(pNew);
+}
+
+sal_Bool SvxUnoCheckForPositiveValue( const uno::Any& rVal )
+{
+ sal_Bool bConvert = sal_True; // the default is that all metric items must be converted
+ sal_Int32 nValue = 0;
+ if( rVal >>= nValue )
+ bConvert = (nValue > 0);
+ return bConvert;
+}
+
+
+//----------------------------------------------------------------------
+uno::Any SvxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry* pMap, const SfxItemSet& rSet, bool bSearchInParent, bool bDontConvertNegativeValues ) const
+{
+ uno::Any aVal;
+ if(!pMap || !pMap->nWID)
+ return aVal;
+
+ const SfxPoolItem* pItem = 0;
+ SfxItemPool* pPool = rSet.GetPool();
+ rSet.GetItemState( pMap->nWID, bSearchInParent, &pItem );
+ if( NULL == pItem && pPool )
+ pItem = &(pPool->GetDefaultItem( pMap->nWID ));
+
+ const SfxMapUnit eMapUnit = pPool ? pPool->GetMetric((USHORT)pMap->nWID) : SFX_MAPUNIT_100TH_MM;
+ BYTE nMemberId = pMap->nMemberId & (~SFX_METRIC_ITEM);
+ if( eMapUnit == SFX_MAPUNIT_100TH_MM )
+ nMemberId &= (~CONVERT_TWIPS);
+
+ if(pItem)
+ {
+ pItem->QueryValue( aVal, nMemberId );
+ if( pMap->nMemberId & SFX_METRIC_ITEM )
+ {
+ if( eMapUnit != SFX_MAPUNIT_100TH_MM )
+ {
+ if ( !bDontConvertNegativeValues || SvxUnoCheckForPositiveValue( aVal ) )
+ SvxUnoConvertToMM( eMapUnit, aVal );
+ }
+ }
+ else if ( pMap->pType->getTypeClass() == uno::TypeClass_ENUM &&
+ aVal.getValueType() == ::getCppuType((const sal_Int32*)0) )
+ {
+ // convert typeless SfxEnumItem to enum type
+ sal_Int32 nEnum;
+ aVal >>= nEnum;
+ aVal.setValue( &nEnum, *pMap->pType );
+ }
+ }
+ else
+ {
+ DBG_ERROR( "No SfxPoolItem found for property!" );
+ }
+
+ return aVal;
+}
+
+//----------------------------------------------------------------------
+void SvxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry* pMap, const uno::Any& rVal, SfxItemSet& rSet, bool bDontConvertNegativeValues ) const
+{
+ if(!pMap || !pMap->nWID)
+ return;
+
+ // item holen
+ const SfxPoolItem* pItem = 0;
+ SfxPoolItem *pNewItem = 0;
+ SfxItemState eState = rSet.GetItemState( pMap->nWID, sal_True, &pItem );
+ SfxItemPool* pPool = rSet.GetPool();
+
+ // UnoAny in item-Wert stecken
+ if(eState < SFX_ITEM_DEFAULT || pItem == NULL)
+ {
+ if( pPool == NULL )
+ {
+ DBG_ERROR( "No default item and no pool?" );
+ return;
+ }
+
+ pItem = &pPool->GetDefaultItem( pMap->nWID );
+ }
+
+ DBG_ASSERT( pItem, "Got no default for item!" );
+ if( pItem )
+ {
+ uno::Any aValue( rVal );
+
+ const SfxMapUnit eMapUnit = pPool ? pPool->GetMetric((USHORT)pMap->nWID) : SFX_MAPUNIT_100TH_MM;
+
+ // check for needed metric translation
+ if( (pMap->nMemberId & SFX_METRIC_ITEM) && eMapUnit != SFX_MAPUNIT_100TH_MM )
+ {
+ if ( !bDontConvertNegativeValues || SvxUnoCheckForPositiveValue( aValue ) )
+ SvxUnoConvertFromMM( eMapUnit, aValue );
+ }
+
+ pNewItem = pItem->Clone();
+
+ BYTE nMemberId = pMap->nMemberId & (~SFX_METRIC_ITEM);
+ if( eMapUnit == SFX_MAPUNIT_100TH_MM )
+ nMemberId &= (~CONVERT_TWIPS);
+
+ if( pNewItem->PutValue( aValue, nMemberId ) )
+ {
+ // neues item in itemset setzen
+ rSet.Put( *pNewItem, pMap->nWID );
+ }
+ delete pNewItem;
+ }
+}
+
+//----------------------------------------------------------------------
+uno::Any SvxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry* pMap ) const
+{
+ // Schon ein Wert eingetragen? Dann schnell fertig
+ uno::Any* pUsrAny = GetUsrAnyForID(pMap->nWID);
+ if(pUsrAny)
+ return *pUsrAny;
+
+ // Noch kein UsrAny gemerkt, generiere Default-Eintrag und gib
+ // diesen zurueck
+
+ const SfxMapUnit eMapUnit = mrItemPool.GetMetric((USHORT)pMap->nWID);
+ BYTE nMemberId = pMap->nMemberId & (~SFX_METRIC_ITEM);
+ if( eMapUnit == SFX_MAPUNIT_100TH_MM )
+ nMemberId &= (~CONVERT_TWIPS);
+
+ uno::Any aVal;
+ SfxItemSet aSet( mrItemPool, pMap->nWID, pMap->nWID);
+
+ if( (pMap->nWID < OWN_ATTR_VALUE_START) && (pMap->nWID > OWN_ATTR_VALUE_END ) )
+ {
+ // Default aus ItemPool holen
+ if(mrItemPool.IsWhich(pMap->nWID))
+ aSet.Put(mrItemPool.GetDefaultItem(pMap->nWID));
+ }
+
+ if(aSet.Count())
+ {
+ const SfxPoolItem* pItem = NULL;
+ SfxItemState eState = aSet.GetItemState( pMap->nWID, sal_True, &pItem );
+ if(eState >= SFX_ITEM_DEFAULT && pItem)
+ {
+ pItem->QueryValue( aVal, nMemberId );
+ ((SvxItemPropertySet*)this)->AddUsrAnyForID(aVal, pMap->nWID);
+ }
+ }
+
+ if( pMap->nMemberId & SFX_METRIC_ITEM )
+ {
+ // check for needed metric translation
+ if(pMap->nMemberId & SFX_METRIC_ITEM && eMapUnit != SFX_MAPUNIT_100TH_MM)
+ {
+ SvxUnoConvertToMM( eMapUnit, aVal );
+ }
+ }
+
+ if ( pMap->pType->getTypeClass() == uno::TypeClass_ENUM &&
+ aVal.getValueType() == ::getCppuType((const sal_Int32*)0) )
+ {
+ sal_Int32 nEnum;
+ aVal >>= nEnum;
+
+ aVal.setValue( &nEnum, *pMap->pType );
+ }
+
+ return aVal;
+}
+
+//----------------------------------------------------------------------
+
+void SvxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry* pMap, const uno::Any& rVal ) const
+{
+ uno::Any* pUsrAny = GetUsrAnyForID(pMap->nWID);
+ if(!pUsrAny)
+ ((SvxItemPropertySet*)this)->AddUsrAnyForID(rVal, pMap->nWID);
+ else
+ *pUsrAny = rVal;
+}
+
+//----------------------------------------------------------------------
+
+const SfxItemPropertySimpleEntry* SvxItemPropertySet::getPropertyMapEntry(const OUString &rName) const
+{
+ return m_aPropertyMap.getByName( rName );
+ }
+
+//----------------------------------------------------------------------
+
+uno::Reference< beans::XPropertySetInfo > SvxItemPropertySet::getPropertySetInfo() const
+{
+ if( !m_xInfo.is() )
+ m_xInfo = new SfxItemPropertySetInfo( &m_aPropertyMap );
+ return m_xInfo;
+}
+
+//----------------------------------------------------------------------
+
+#ifndef TWIPS_TO_MM
+#define TWIPS_TO_MM(val) ((val * 127 + 36) / 72)
+#endif
+#ifndef MM_TO_TWIPS
+#define MM_TO_TWIPS(val) ((val * 72 + 63) / 127)
+#endif
+
+/** converts the given any with a metric to 100th/mm if needed */
+void SvxUnoConvertToMM( const SfxMapUnit eSourceMapUnit, uno::Any & rMetric ) throw()
+{
+ // map the metric of the itempool to 100th mm
+ switch(eSourceMapUnit)
+ {
+ case SFX_MAPUNIT_TWIP :
+ {
+ switch( rMetric.getValueTypeClass() )
+ {
+ case uno::TypeClass_BYTE:
+ rMetric <<= (sal_Int8)(TWIPS_TO_MM(*(sal_Int8*)rMetric.getValue()));
+ break;
+ case uno::TypeClass_SHORT:
+ rMetric <<= (sal_Int16)(TWIPS_TO_MM(*(sal_Int16*)rMetric.getValue()));
+ break;
+ case uno::TypeClass_UNSIGNED_SHORT:
+ rMetric <<= (sal_uInt16)(TWIPS_TO_MM(*(sal_uInt16*)rMetric.getValue()));
+ break;
+ case uno::TypeClass_LONG:
+ rMetric <<= (sal_Int32)(TWIPS_TO_MM(*(sal_Int32*)rMetric.getValue()));
+ break;
+ case uno::TypeClass_UNSIGNED_LONG:
+ rMetric <<= (sal_uInt32)(TWIPS_TO_MM(*(sal_uInt32*)rMetric.getValue()));
+ break;
+ default:
+ DBG_ERROR("AW: Missing unit translation to 100th mm!");
+ }
+ break;
+ }
+ default:
+ {
+ DBG_ERROR("AW: Missing unit translation to 100th mm!");
+ }
+ }
+}
+
+//----------------------------------------------------------------------
+
+/** converts the given any with a metric from 100th/mm to the given metric if needed */
+void SvxUnoConvertFromMM( const SfxMapUnit eDestinationMapUnit, uno::Any & rMetric ) throw()
+{
+ switch(eDestinationMapUnit)
+ {
+ case SFX_MAPUNIT_TWIP :
+ {
+ switch( rMetric.getValueTypeClass() )
+ {
+ case uno::TypeClass_BYTE:
+ rMetric <<= (sal_Int8)(MM_TO_TWIPS(*(sal_Int8*)rMetric.getValue()));
+ break;
+ case uno::TypeClass_SHORT:
+ rMetric <<= (sal_Int16)(MM_TO_TWIPS(*(sal_Int16*)rMetric.getValue()));
+ break;
+ case uno::TypeClass_UNSIGNED_SHORT:
+ rMetric <<= (sal_uInt16)(MM_TO_TWIPS(*(sal_uInt16*)rMetric.getValue()));
+ break;
+ case uno::TypeClass_LONG:
+ rMetric <<= (sal_Int32)(MM_TO_TWIPS(*(sal_Int32*)rMetric.getValue()));
+ break;
+ case uno::TypeClass_UNSIGNED_LONG:
+ rMetric <<= (sal_uInt32)(MM_TO_TWIPS(*(sal_uInt32*)rMetric.getValue()));
+ break;
+ default:
+ DBG_ERROR("AW: Missing unit translation to 100th mm!");
+ }
+ break;
+ }
+ default:
+ {
+ DBG_ERROR("AW: Missing unit translation to PoolMetrics!");
+ }
+ }
+}
+