LCOV - code coverage report
Current view: top level - libreoffice/editeng/source/uno - unoipset.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 92 143 64.3 %
Date: 2012-12-27 Functions: 14 16 87.5 %
Legend: Lines: hit not hit

          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             : using namespace ::rtl;
      34             : 
      35             : using ::std::vector;
      36             : 
      37             : //----------------------------------------------------------------------
      38             : 
      39             : struct SfxItemPropertyMapEntryHash
      40             : {
      41             :     size_t operator()(const SfxItemPropertyMapEntry* pMap) const { return (size_t)pMap; }
      42             : };
      43             : 
      44             : //----------------------------------------------------------------------
      45             : 
      46          76 : struct SvxIDPropertyCombine
      47             : {
      48             :     sal_uInt16  nWID;
      49             :     uno::Any    aAny;
      50             : };
      51             : 
      52             : 
      53          80 : SvxItemPropertySet::SvxItemPropertySet( const SfxItemPropertyMapEntry* pMap, SfxItemPool& rItemPool, sal_Bool bConvertTwips )
      54             : :   m_aPropertyMap( pMap ),
      55          80 :     _pMap(pMap), mbConvertTwips(bConvertTwips), mrItemPool( rItemPool )
      56             : {
      57          80 : }
      58             : 
      59             : //----------------------------------------------------------------------
      60         160 : SvxItemPropertySet::~SvxItemPropertySet()
      61             : {
      62          80 :     ClearAllUsrAny();
      63          80 : }
      64             : 
      65             : //----------------------------------------------------------------------
      66        2176 : uno::Any* SvxItemPropertySet::GetUsrAnyForID(sal_uInt16 nWID) const
      67             : {
      68        8188 :     for ( size_t i = 0, n = aCombineList.size(); i < n; ++i )
      69             :     {
      70        6055 :         SvxIDPropertyCombine* pActual = aCombineList[ i ];
      71        6055 :         if( pActual->nWID == nWID )
      72          43 :             return &pActual->aAny;
      73             :     }
      74        2133 :     return NULL;
      75             : }
      76             : 
      77             : //----------------------------------------------------------------------
      78          38 : void SvxItemPropertySet::AddUsrAnyForID(const uno::Any& rAny, sal_uInt16 nWID)
      79             : {
      80          38 :     SvxIDPropertyCombine* pNew = new SvxIDPropertyCombine;
      81          38 :     pNew->nWID = nWID;
      82          38 :     pNew->aAny = rAny;
      83          38 :     aCombineList.push_back( pNew );
      84          38 : }
      85             : 
      86             : //----------------------------------------------------------------------
      87             : 
      88          93 : void SvxItemPropertySet::ClearAllUsrAny()
      89             : {
      90         131 :     for ( size_t i = 0, n = aCombineList.size(); i < n; ++i )
      91          38 :         delete aCombineList[ i ];
      92          93 :     aCombineList.clear();
      93          93 : }
      94             : 
      95             : //----------------------------------------------------------------------
      96             : 
      97           0 : sal_Bool SvxUnoCheckForPositiveValue( const uno::Any& rVal )
      98             : {
      99           0 :     sal_Bool bConvert = sal_True; // the default is that all metric items must be converted
     100           0 :     sal_Int32 nValue = 0;
     101           0 :     if( rVal >>= nValue )
     102           0 :         bConvert = (nValue > 0);
     103           0 :     return bConvert;
     104             : }
     105             : 
     106             : 
     107             : //----------------------------------------------------------------------
     108        4803 : uno::Any SvxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry* pMap, const SfxItemSet& rSet, bool bSearchInParent, bool bDontConvertNegativeValues ) const
     109             : {
     110        4803 :     uno::Any aVal;
     111        4803 :     if(!pMap || !pMap->nWID)
     112             :         return aVal;
     113             : 
     114        4803 :     const SfxPoolItem* pItem = 0;
     115        4803 :     SfxItemPool* pPool = rSet.GetPool();
     116        4803 :     rSet.GetItemState( pMap->nWID, bSearchInParent, &pItem );
     117        4803 :     if( NULL == pItem && pPool )
     118           0 :         pItem = &(pPool->GetDefaultItem( pMap->nWID ));
     119             : 
     120        4803 :     const SfxMapUnit eMapUnit = pPool ? pPool->GetMetric((sal_uInt16)pMap->nWID) : SFX_MAPUNIT_100TH_MM;
     121        4803 :     sal_uInt8 nMemberId = pMap->nMemberId & (~SFX_METRIC_ITEM);
     122        4803 :     if( eMapUnit == SFX_MAPUNIT_100TH_MM )
     123        4736 :         nMemberId &= (~CONVERT_TWIPS);
     124             : 
     125        4803 :     if(pItem)
     126             :     {
     127        4803 :         pItem->QueryValue( aVal, nMemberId );
     128        4803 :         if( pMap->nMemberId & SFX_METRIC_ITEM )
     129             :         {
     130        1025 :             if( eMapUnit != SFX_MAPUNIT_100TH_MM )
     131             :             {
     132          13 :                 if ( !bDontConvertNegativeValues || SvxUnoCheckForPositiveValue( aVal ) )
     133          13 :                     SvxUnoConvertToMM( eMapUnit, aVal );
     134             :             }
     135             :         }
     136        4530 :         else if ( pMap->pType->getTypeClass() == uno::TypeClass_ENUM &&
     137         752 :               aVal.getValueType() == ::getCppuType((const sal_Int32*)0) )
     138             :         {
     139             :             // convert typeless SfxEnumItem to enum type
     140             :             sal_Int32 nEnum;
     141          72 :             aVal >>= nEnum;
     142          72 :             aVal.setValue( &nEnum, *pMap->pType );
     143             :         }
     144             :     }
     145             :     else
     146             :     {
     147             :         OSL_FAIL( "No SfxPoolItem found for property!" );
     148             :     }
     149             : 
     150           0 :     return aVal;
     151             : }
     152             : 
     153             : //----------------------------------------------------------------------
     154       66115 : void SvxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry* pMap, const uno::Any& rVal, SfxItemSet& rSet, bool bDontConvertNegativeValues ) const
     155             : {
     156       66115 :     if(!pMap || !pMap->nWID)
     157             :         return;
     158             : 
     159             :     // Get item
     160       66115 :     const SfxPoolItem* pItem = 0;
     161       66115 :     SfxItemState eState = rSet.GetItemState( pMap->nWID, sal_True, &pItem );
     162       66115 :     SfxItemPool* pPool = rSet.GetPool();
     163             : 
     164             :     // Put UnoAny in the item value
     165       66115 :     if(eState < SFX_ITEM_DEFAULT || pItem == NULL)
     166             :     {
     167           2 :         if( pPool == NULL )
     168             :         {
     169             :             OSL_FAIL( "No default item and no pool?" );
     170             :             return;
     171             :         }
     172             : 
     173           2 :         pItem = &pPool->GetDefaultItem( pMap->nWID );
     174             :     }
     175             : 
     176             :     DBG_ASSERT( pItem, "Got no default for item!" );
     177       66115 :     if( pItem )
     178             :     {
     179       66115 :         uno::Any aValue( rVal );
     180             : 
     181       66115 :         const SfxMapUnit eMapUnit = pPool ? pPool->GetMetric((sal_uInt16)pMap->nWID) : SFX_MAPUNIT_100TH_MM;
     182             : 
     183             :         // check for needed metric translation
     184       66115 :         if( (pMap->nMemberId & SFX_METRIC_ITEM) && eMapUnit != SFX_MAPUNIT_100TH_MM )
     185             :         {
     186         126 :             if ( !bDontConvertNegativeValues || SvxUnoCheckForPositiveValue( aValue ) )
     187         126 :                 SvxUnoConvertFromMM( eMapUnit, aValue );
     188             :         }
     189             : 
     190       66115 :         SfxPoolItem *pNewItem = pItem->Clone();
     191             : 
     192       66115 :         sal_uInt8 nMemberId = pMap->nMemberId & (~SFX_METRIC_ITEM);
     193       66115 :         if( eMapUnit == SFX_MAPUNIT_100TH_MM )
     194       64925 :             nMemberId &= (~CONVERT_TWIPS);
     195             : 
     196       66115 :         if( pNewItem->PutValue( aValue, nMemberId ) )
     197             :         {
     198             :             // Set new item in item set
     199       66114 :             rSet.Put( *pNewItem, pMap->nWID );
     200             :         }
     201       66115 :         delete pNewItem;
     202             :     }
     203             : }
     204             : 
     205             : //----------------------------------------------------------------------
     206           0 : uno::Any SvxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry* pMap ) const
     207             : {
     208             :     // Already entered a value? Then finish quickly
     209           0 :     uno::Any* pUsrAny = GetUsrAnyForID(pMap->nWID);
     210           0 :     if(pUsrAny)
     211           0 :         return *pUsrAny;
     212             : 
     213             :     // No UsrAny detected yet, generate Default entry and return this
     214           0 :     const SfxMapUnit eMapUnit = mrItemPool.GetMetric((sal_uInt16)pMap->nWID);
     215           0 :     sal_uInt8 nMemberId = pMap->nMemberId & (~SFX_METRIC_ITEM);
     216           0 :     if( eMapUnit == SFX_MAPUNIT_100TH_MM )
     217           0 :         nMemberId &= (~CONVERT_TWIPS);
     218           0 :     uno::Any aVal;
     219           0 :     SfxItemSet aSet( mrItemPool, pMap->nWID, pMap->nWID);
     220             : 
     221           0 :     if( (pMap->nWID < OWN_ATTR_VALUE_START) && (pMap->nWID > OWN_ATTR_VALUE_END ) )
     222             :     {
     223             :         // Get Default from ItemPool
     224           0 :         if(mrItemPool.IsWhich(pMap->nWID))
     225           0 :             aSet.Put(mrItemPool.GetDefaultItem(pMap->nWID));
     226             :     }
     227             : 
     228           0 :     if(aSet.Count())
     229             :     {
     230           0 :         const SfxPoolItem* pItem = NULL;
     231           0 :         SfxItemState eState = aSet.GetItemState( pMap->nWID, sal_True, &pItem );
     232           0 :         if(eState >= SFX_ITEM_DEFAULT && pItem)
     233             :         {
     234           0 :             pItem->QueryValue( aVal, nMemberId );
     235           0 :             ((SvxItemPropertySet*)this)->AddUsrAnyForID(aVal, pMap->nWID);
     236             :         }
     237             :     }
     238             : 
     239           0 :     if( pMap->nMemberId & SFX_METRIC_ITEM )
     240             :     {
     241             :         // check for needed metric translation
     242           0 :         if(pMap->nMemberId & SFX_METRIC_ITEM && eMapUnit != SFX_MAPUNIT_100TH_MM)
     243             :         {
     244           0 :             SvxUnoConvertToMM( eMapUnit, aVal );
     245             :         }
     246             :     }
     247             : 
     248           0 :     if ( pMap->pType->getTypeClass() == uno::TypeClass_ENUM &&
     249           0 :           aVal.getValueType() == ::getCppuType((const sal_Int32*)0) )
     250             :     {
     251             :         sal_Int32 nEnum;
     252           0 :         aVal >>= nEnum;
     253             : 
     254           0 :         aVal.setValue( &nEnum, *pMap->pType );
     255             :     }
     256             : 
     257           0 :     return aVal;
     258             : }
     259             : 
     260             : //----------------------------------------------------------------------
     261             : 
     262          44 : void SvxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry* pMap, const uno::Any& rVal ) const
     263             : {
     264          44 :     uno::Any* pUsrAny = GetUsrAnyForID(pMap->nWID);
     265          44 :     if(!pUsrAny)
     266          38 :         ((SvxItemPropertySet*)this)->AddUsrAnyForID(rVal, pMap->nWID);
     267             :     else
     268           6 :         *pUsrAny = rVal;
     269          44 : }
     270             : 
     271             : //----------------------------------------------------------------------
     272             : 
     273      102304 : const SfxItemPropertySimpleEntry* SvxItemPropertySet::getPropertyMapEntry(const OUString &rName) const
     274             : {
     275      102304 :     return m_aPropertyMap.getByName( rName );
     276             :  }
     277             : 
     278             : //----------------------------------------------------------------------
     279             : 
     280        1181 : uno::Reference< beans::XPropertySetInfo >  SvxItemPropertySet::getPropertySetInfo() const
     281             : {
     282        1181 :     if( !m_xInfo.is() )
     283          50 :         m_xInfo = new SfxItemPropertySetInfo( m_aPropertyMap );
     284        1181 :     return m_xInfo;
     285             : }
     286             : 
     287             : //----------------------------------------------------------------------
     288             : 
     289             : #ifndef TWIPS_TO_MM
     290             : #define TWIPS_TO_MM(val) ((val * 127 + 36) / 72)
     291             : #endif
     292             : #ifndef MM_TO_TWIPS
     293             : #define MM_TO_TWIPS(val) ((val * 72 + 63) / 127)
     294             : #endif
     295             : 
     296             : /** converts the given any with a metric to 100th/mm if needed */
     297          17 : void SvxUnoConvertToMM( const SfxMapUnit eSourceMapUnit, uno::Any & rMetric ) throw()
     298             : {
     299             :     // map the metric of the itempool to 100th mm
     300          17 :     switch(eSourceMapUnit)
     301             :     {
     302             :         case SFX_MAPUNIT_TWIP :
     303             :         {
     304          17 :             switch( rMetric.getValueTypeClass() )
     305             :             {
     306             :             case uno::TypeClass_BYTE:
     307           0 :                 rMetric <<= (sal_Int8)(TWIPS_TO_MM(*(sal_Int8*)rMetric.getValue()));
     308           0 :                 break;
     309             :             case uno::TypeClass_SHORT:
     310           0 :                 rMetric <<= (sal_Int16)(TWIPS_TO_MM(*(sal_Int16*)rMetric.getValue()));
     311           0 :                 break;
     312             :             case uno::TypeClass_UNSIGNED_SHORT:
     313           0 :                 rMetric <<= (sal_uInt16)(TWIPS_TO_MM(*(sal_uInt16*)rMetric.getValue()));
     314           0 :                 break;
     315             :             case uno::TypeClass_LONG:
     316          17 :                 rMetric <<= (sal_Int32)(TWIPS_TO_MM(*(sal_Int32*)rMetric.getValue()));
     317          17 :                 break;
     318             :             case uno::TypeClass_UNSIGNED_LONG:
     319           0 :                 rMetric <<= (sal_uInt32)(TWIPS_TO_MM(*(sal_uInt32*)rMetric.getValue()));
     320           0 :                 break;
     321             :             default:
     322             :                 OSL_FAIL("AW: Missing unit translation to 100th mm!");
     323             :             }
     324          17 :             break;
     325             :         }
     326             :         default:
     327             :         {
     328             :             OSL_FAIL("AW: Missing unit translation to 100th mm!");
     329             :         }
     330             :     }
     331          17 : }
     332             : 
     333             : //----------------------------------------------------------------------
     334             : 
     335             : /** converts the given any with a metric from 100th/mm to the given metric if needed */
     336         160 : void SvxUnoConvertFromMM( const SfxMapUnit eDestinationMapUnit, uno::Any & rMetric ) throw()
     337             : {
     338         160 :     switch(eDestinationMapUnit)
     339             :     {
     340             :         case SFX_MAPUNIT_TWIP :
     341             :         {
     342         160 :             switch( rMetric.getValueTypeClass() )
     343             :             {
     344             :                 case uno::TypeClass_BYTE:
     345           0 :                     rMetric <<= (sal_Int8)(MM_TO_TWIPS(*(sal_Int8*)rMetric.getValue()));
     346           0 :                     break;
     347             :                 case uno::TypeClass_SHORT:
     348           0 :                     rMetric <<= (sal_Int16)(MM_TO_TWIPS(*(sal_Int16*)rMetric.getValue()));
     349           0 :                     break;
     350             :                 case uno::TypeClass_UNSIGNED_SHORT:
     351           0 :                     rMetric <<= (sal_uInt16)(MM_TO_TWIPS(*(sal_uInt16*)rMetric.getValue()));
     352           0 :                     break;
     353             :                 case uno::TypeClass_LONG:
     354         160 :                     rMetric <<= (sal_Int32)(MM_TO_TWIPS(*(sal_Int32*)rMetric.getValue()));
     355         160 :                     break;
     356             :                 case uno::TypeClass_UNSIGNED_LONG:
     357           0 :                     rMetric <<= (sal_uInt32)(MM_TO_TWIPS(*(sal_uInt32*)rMetric.getValue()));
     358           0 :                     break;
     359             :                 default:
     360             :                     OSL_FAIL("AW: Missing unit translation to 100th mm!");
     361             :             }
     362         160 :             break;
     363             :         }
     364             :         default:
     365             :         {
     366             :             OSL_FAIL("AW: Missing unit translation to PoolMetrics!");
     367             :         }
     368             :     }
     369         160 : }
     370             : 
     371             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10