LCOV - code coverage report
Current view: top level - libreoffice/scaddins/source/datefunc - datefunc.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 148 320 46.2 %
Date: 2012-12-27 Functions: 26 56 46.4 %
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             : //------------------------------------------------------------------
      21             : //
      22             : // date functions add in
      23             : //
      24             : //------------------------------------------------------------------
      25             : 
      26             : #include "datefunc.hxx"
      27             : #include "datefunc.hrc"
      28             : #include <cppuhelper/factory.hxx>
      29             : #include <osl/diagnose.h>
      30             : #include <rtl/ustrbuf.hxx>
      31             : #include <tools/resmgr.hxx>
      32             : #include <tools/rcid.h>
      33             : #include <com/sun/star/util/Date.hpp>
      34             : 
      35             : using namespace ::com::sun::star;
      36             : using namespace ::rtl;
      37             : 
      38             : //------------------------------------------------------------------
      39             : 
      40             : #define ADDIN_SERVICE           "com.sun.star.sheet.AddIn"
      41             : #define MY_SERVICE              "com.sun.star.sheet.addin.DateFunctions"
      42             : #define MY_IMPLNAME             "com.sun.star.sheet.addin.DateFunctionsImpl"
      43             : 
      44             : //------------------------------------------------------------------
      45             : 
      46             : #define STR_FROM_ANSI( s )      OUString( s, strlen( s ), RTL_TEXTENCODING_MS_1252 )
      47             : 
      48             : //------------------------------------------------------------------
      49             : 
      50             : const sal_uInt32 ScaList::nStartSize = 16;
      51             : const sal_uInt32 ScaList::nIncrSize = 16;
      52             : 
      53          27 : ScaList::ScaList() :
      54          27 :     pData( new void*[ nStartSize ] ),
      55             :     nSize( nStartSize ),
      56             :     nCount( 0 ),
      57          54 :     nCurr( 0 )
      58             : {
      59          27 : }
      60             : 
      61           0 : ScaList::~ScaList()
      62             : {
      63           0 :     delete[] pData;
      64           0 : }
      65             : 
      66           0 : void ScaList::_Grow()
      67             : {
      68           0 :     nSize += nIncrSize;
      69             : 
      70           0 :     void** pNewData = new void*[ nSize ];
      71           0 :     memcpy( pNewData, pData, nCount * sizeof( void* ) );
      72             : 
      73           0 :     delete[] pData;
      74           0 :     pData = pNewData;
      75           0 : }
      76             : 
      77             : //------------------------------------------------------------------
      78             : 
      79           0 : ScaStringList::~ScaStringList()
      80             : {
      81           0 :     for( OUString* pStr = First(); pStr; pStr = Next() )
      82           0 :         delete pStr;
      83           0 : }
      84             : 
      85             : //------------------------------------------------------------------
      86             : 
      87         420 : ScaResId::ScaResId( sal_uInt16 nId, ResMgr& rResMgr ) :
      88         420 :     ResId( nId, rResMgr )
      89             : {
      90         420 : }
      91             : 
      92             : 
      93             : //------------------------------------------------------------------
      94             : 
      95             : #define UNIQUE              sal_False   // function name does not exist in Calc
      96             : #define DOUBLE              sal_True    // function name exists in Calc
      97             : 
      98             : #define STDPAR              sal_False   // all parameters are described
      99             : #define INTPAR              sal_True    // first parameter is internal
     100             : 
     101             : #define FUNCDATA( FuncName, ParamCount, Category, Double, IntPar )  \
     102             :     { "get" #FuncName, DATE_FUNCNAME_##FuncName, DATE_FUNCDESC_##FuncName, DATE_DEFFUNCNAME_##FuncName, ParamCount, Category, Double, IntPar }
     103             : 
     104             : const ScaFuncDataBase pFuncDataArr[] =
     105             : {
     106             :     FUNCDATA( DiffWeeks,    3, ScaCat_DateTime, UNIQUE, INTPAR ),
     107             :     FUNCDATA( DiffMonths,   3, ScaCat_DateTime, UNIQUE, INTPAR ),
     108             :     FUNCDATA( DiffYears,    3, ScaCat_DateTime, UNIQUE, INTPAR ),
     109             :     FUNCDATA( IsLeapYear,   1, ScaCat_DateTime, UNIQUE, INTPAR ),
     110             :     FUNCDATA( DaysInMonth,  1, ScaCat_DateTime, UNIQUE, INTPAR ),
     111             :     FUNCDATA( DaysInYear,   1, ScaCat_DateTime, UNIQUE, INTPAR ),
     112             :     FUNCDATA( WeeksInYear,  1, ScaCat_DateTime, UNIQUE, INTPAR ),
     113             :     FUNCDATA( Rot13,        1, ScaCat_Text,     UNIQUE, STDPAR )
     114             : };
     115             : 
     116             : #undef FUNCDATA
     117             : 
     118             : 
     119             : //------------------------------------------------------------------
     120             : 
     121          24 : ScaFuncData::ScaFuncData( const ScaFuncDataBase& rBaseData, ResMgr& rResMgr ) :
     122             :     aIntName( OUString::createFromAscii( rBaseData.pIntName ) ),
     123             :     nUINameID( rBaseData.nUINameID ),
     124             :     nDescrID( rBaseData.nDescrID ),
     125             :     nCompListID( rBaseData.nCompListID ),
     126             :     nParamCount( rBaseData.nParamCount ),
     127             :     eCat( rBaseData.eCat ),
     128             :     bDouble( rBaseData.bDouble ),
     129          24 :     bWithOpt( rBaseData.bWithOpt )
     130             : {
     131          24 :     ScaResStringArrLoader aArrLoader( RID_DATE_DEFFUNCTION_NAMES, nCompListID, rResMgr );
     132          24 :     const ResStringArray& rArr = aArrLoader.GetStringArray();
     133             : 
     134          72 :     for( sal_uInt16 nIndex = 0; nIndex < rArr.Count(); nIndex++ )
     135          72 :         aCompList.Append( rArr.GetString( nIndex ) );
     136          24 : }
     137             : 
     138           0 : ScaFuncData::~ScaFuncData()
     139             : {
     140           0 : }
     141             : 
     142          84 : sal_uInt16 ScaFuncData::GetStrIndex( sal_uInt16 nParam ) const
     143             : {
     144          84 :     if( !bWithOpt )
     145           6 :         nParam++;
     146          84 :     return (nParam > nParamCount) ? (nParamCount * 2) : (nParam * 2);
     147             : }
     148             : 
     149             : 
     150             : //------------------------------------------------------------------
     151             : 
     152           3 : ScaFuncDataList::ScaFuncDataList( ResMgr& rResMgr ) :
     153           3 :     nLast( 0xFFFFFFFF )
     154             : {
     155          27 :     for( sal_uInt16 nIndex = 0; nIndex < SAL_N_ELEMENTS(pFuncDataArr); nIndex++ )
     156          24 :         Append( new ScaFuncData( pFuncDataArr[ nIndex ], rResMgr ) );
     157           3 : }
     158             : 
     159           0 : ScaFuncDataList::~ScaFuncDataList()
     160             : {
     161           0 :     for( ScaFuncData* pFData = First(); pFData; pFData = Next() )
     162           0 :         delete pFData;
     163           0 : }
     164             : 
     165         164 : const ScaFuncData* ScaFuncDataList::Get( const OUString& rProgrammaticName ) const
     166             : {
     167         164 :     if( aLastName == rProgrammaticName )
     168         132 :         return Get( nLast );
     169             : 
     170         144 :     for( sal_uInt32 nIndex = 0; nIndex < Count(); nIndex++ )
     171             :     {
     172         144 :         const ScaFuncData* pCurr = Get( nIndex );
     173         144 :         if( pCurr->Is( rProgrammaticName ) )
     174             :         {
     175          32 :             const_cast< ScaFuncDataList* >( this )->aLastName = rProgrammaticName;
     176          32 :             const_cast< ScaFuncDataList* >( this )->nLast = nIndex;
     177          32 :             return pCurr;
     178             :         }
     179             :     }
     180           0 :     return NULL;
     181             : }
     182             : 
     183             : 
     184             : //------------------------------------------------------------------
     185             : 
     186         108 : ScaFuncRes::ScaFuncRes( ResId& rResId, ResMgr& rResMgr, sal_uInt16 nIndex, OUString& rRet ) :
     187         108 :     Resource( rResId )
     188             : {
     189         108 :     rRet = String( ScaResId( nIndex, rResMgr ) );
     190         108 :     FreeResource();
     191         108 : }
     192             : 
     193             : 
     194             : //------------------------------------------------------------------
     195             : //
     196             : //  entry points for service registration / instantiation
     197             : //
     198             : //------------------------------------------------------------------
     199             : 
     200           3 : uno::Reference< uno::XInterface > SAL_CALL ScaDateAddIn_CreateInstance(
     201             :         const uno::Reference< lang::XMultiServiceFactory >& )
     202             : {
     203           3 :     static uno::Reference< uno::XInterface > xInst = (cppu::OWeakObject*) new ScaDateAddIn();
     204           3 :     return xInst;
     205             : }
     206             : 
     207             : 
     208             : //------------------------------------------------------------------------
     209             : 
     210             : extern "C" {
     211             : 
     212           3 : SAL_DLLPUBLIC_EXPORT void * SAL_CALL date_component_getFactory(
     213             :     const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ )
     214             : {
     215           3 :     void* pRet = 0;
     216             : 
     217          15 :     if ( pServiceManager &&
     218          12 :             OUString::createFromAscii( pImplName ) == ScaDateAddIn::getImplementationName_Static() )
     219             :     {
     220             :         uno::Reference< lang::XSingleServiceFactory > xFactory( cppu::createOneInstanceFactory(
     221             :                 reinterpret_cast< lang::XMultiServiceFactory* >( pServiceManager ),
     222             :                 ScaDateAddIn::getImplementationName_Static(),
     223             :                 ScaDateAddIn_CreateInstance,
     224           3 :                 ScaDateAddIn::getSupportedServiceNames_Static() ) );
     225             : 
     226           3 :         if (xFactory.is())
     227             :         {
     228           3 :             xFactory->acquire();
     229           3 :             pRet = xFactory.get();
     230           3 :         }
     231             :     }
     232             : 
     233           3 :     return pRet;
     234             : }
     235             : 
     236             : }   // extern C
     237             : 
     238             : //------------------------------------------------------------------------
     239             : //
     240             : //  "normal" service implementation
     241             : //
     242             : //------------------------------------------------------------------------
     243             : 
     244           3 : ScaDateAddIn::ScaDateAddIn() :
     245             :     pDefLocales( NULL ),
     246             :     pResMgr( NULL ),
     247           3 :     pFuncDataList( NULL )
     248             : {
     249           3 : }
     250             : 
     251           0 : ScaDateAddIn::~ScaDateAddIn()
     252             : {
     253           0 :     if( pFuncDataList )
     254           0 :         delete pFuncDataList;
     255           0 :     if( pDefLocales )
     256           0 :         delete[] pDefLocales;
     257             : 
     258             :     // pResMgr already deleted (_all_ resource managers are deleted _before_ this dtor is called)
     259           0 : }
     260             : 
     261             : static const sal_Char*  pLang[] = { "de", "en" };
     262             : static const sal_Char*  pCoun[] = { "DE", "US" };
     263             : static const sal_uInt32 nNumOfLoc = SAL_N_ELEMENTS( pLang );
     264             : 
     265           1 : void ScaDateAddIn::InitDefLocales()
     266             : {
     267           1 :     pDefLocales = new lang::Locale[ nNumOfLoc ];
     268             : 
     269           3 :     for( sal_uInt32 nIndex = 0; nIndex < nNumOfLoc; nIndex++ )
     270             :     {
     271           2 :         pDefLocales[ nIndex ].Language = OUString::createFromAscii( pLang[ nIndex ] );
     272           2 :         pDefLocales[ nIndex ].Country = OUString::createFromAscii( pCoun[ nIndex ] );
     273             :     }
     274           1 : }
     275             : 
     276          16 : const lang::Locale& ScaDateAddIn::GetLocale( sal_uInt32 nIndex )
     277             : {
     278          16 :     if( !pDefLocales )
     279           1 :         InitDefLocales();
     280             : 
     281          16 :     return (nIndex < sizeof( pLang )) ? pDefLocales[ nIndex ] : aFuncLoc;
     282             : }
     283             : 
     284         348 : ResMgr& ScaDateAddIn::GetResMgr() throw( uno::RuntimeException )
     285             : {
     286         348 :     if( !pResMgr )
     287             :     {
     288           0 :         InitData();     // try to get resource manager
     289           0 :         if( !pResMgr )
     290           0 :             throw uno::RuntimeException();
     291             :     }
     292         348 :     return *pResMgr;
     293             : }
     294             : 
     295           3 : void ScaDateAddIn::InitData()
     296             : {
     297           3 :     if( pResMgr )
     298           0 :         delete pResMgr;
     299             : 
     300           3 :     OString aModName( "date" );
     301           3 :     pResMgr = ResMgr::CreateResMgr( aModName.getStr(), aFuncLoc );
     302             : 
     303           3 :     if( pFuncDataList )
     304           0 :         delete pFuncDataList;
     305             : 
     306           3 :     pFuncDataList = pResMgr ? new ScaFuncDataList( *pResMgr ) : NULL;
     307             : 
     308           3 :     if( pDefLocales )
     309             :     {
     310           0 :         delete pDefLocales;
     311           0 :         pDefLocales = NULL;
     312           3 :     }
     313           3 : }
     314             : 
     315          24 : OUString ScaDateAddIn::GetDisplFuncStr( sal_uInt16 nResId ) throw( uno::RuntimeException )
     316             : {
     317          24 :     return ScaResStringLoader( RID_DATE_FUNCTION_NAMES, nResId, GetResMgr() ).GetString();
     318             : }
     319             : 
     320         108 : OUString ScaDateAddIn::GetFuncDescrStr( sal_uInt16 nResId, sal_uInt16 nStrIndex ) throw( uno::RuntimeException )
     321             : {
     322         108 :     OUString aRet;
     323             : 
     324         108 :     ScaResPublisher aResPubl( ScaResId( RID_DATE_FUNCTION_DESCRIPTIONS, GetResMgr() ) );
     325         108 :     ScaResId aResId( nResId, GetResMgr() );
     326         108 :     aResId.SetRT( RSC_RESOURCE );
     327             : 
     328         108 :     if( aResPubl.IsAvailableRes( aResId ) )
     329         108 :         ScaFuncRes aSubRes( aResId, GetResMgr(), nStrIndex, aRet );
     330             : 
     331         108 :     aResPubl.FreeResource();
     332         108 :     return aRet;
     333             : }
     334             : 
     335             : 
     336             : //------------------------------------------------------------------------
     337             : 
     338           6 : OUString ScaDateAddIn::getImplementationName_Static()
     339             : {
     340           6 :     return OUString(RTL_CONSTASCII_USTRINGPARAM( MY_IMPLNAME ));
     341             : }
     342             : 
     343           3 : uno::Sequence< OUString > ScaDateAddIn::getSupportedServiceNames_Static()
     344             : {
     345           3 :     uno::Sequence< OUString > aRet( 2 );
     346           3 :     OUString* pArray = aRet.getArray();
     347           3 :     pArray[0] = OUString(RTL_CONSTASCII_USTRINGPARAM( ADDIN_SERVICE ));
     348           3 :     pArray[1] = OUString(RTL_CONSTASCII_USTRINGPARAM( MY_SERVICE ));
     349           3 :     return aRet;
     350             : }
     351             : 
     352             : // XServiceName
     353             : 
     354           6 : OUString SAL_CALL ScaDateAddIn::getServiceName() throw( uno::RuntimeException )
     355             : {
     356             :     // name of specific AddIn service
     357           6 :     return OUString(RTL_CONSTASCII_USTRINGPARAM( MY_SERVICE ));
     358             : }
     359             : 
     360             : // XServiceInfo
     361             : 
     362           0 : OUString SAL_CALL ScaDateAddIn::getImplementationName() throw( uno::RuntimeException )
     363             : {
     364           0 :     return getImplementationName_Static();
     365             : }
     366             : 
     367           0 : sal_Bool SAL_CALL ScaDateAddIn::supportsService( const OUString& aServiceName ) throw( uno::RuntimeException )
     368             : {
     369           0 :     return aServiceName == ADDIN_SERVICE || aServiceName == MY_SERVICE;
     370             : }
     371             : 
     372           0 : uno::Sequence< OUString > SAL_CALL ScaDateAddIn::getSupportedServiceNames() throw( uno::RuntimeException )
     373             : {
     374           0 :     return getSupportedServiceNames_Static();
     375             : }
     376             : 
     377             : // XLocalizable
     378             : 
     379           3 : void SAL_CALL ScaDateAddIn::setLocale( const lang::Locale& eLocale ) throw( uno::RuntimeException )
     380             : {
     381           3 :     aFuncLoc = eLocale;
     382           3 :     InitData();     // change of locale invalidates resources!
     383           3 : }
     384             : 
     385           0 : lang::Locale SAL_CALL ScaDateAddIn::getLocale() throw( uno::RuntimeException )
     386             : {
     387           0 :     return aFuncLoc;
     388             : }
     389             : 
     390             : //------------------------------------------------------------------
     391             : //
     392             : //  function descriptions start here
     393             : //
     394             : //------------------------------------------------------------------
     395             : 
     396             : // XAddIn
     397             : 
     398           0 : OUString SAL_CALL ScaDateAddIn::getProgrammaticFuntionName( const OUString& ) throw( uno::RuntimeException )
     399             : {
     400             :     //  not used by calc
     401             :     //  (but should be implemented for other uses of the AddIn service)
     402           0 :     return OUString();
     403             : }
     404             : 
     405          24 : OUString SAL_CALL ScaDateAddIn::getDisplayFunctionName( const OUString& aProgrammaticName ) throw( uno::RuntimeException )
     406             : {
     407          24 :     OUString aRet;
     408             : 
     409          24 :     const ScaFuncData* pFData = pFuncDataList->Get( aProgrammaticName );
     410          24 :     if( pFData )
     411             :     {
     412          24 :         aRet = GetDisplFuncStr( pFData->GetUINameID() );
     413          24 :         if( pFData->IsDouble() )
     414           0 :             aRet += STR_FROM_ANSI( "_ADD" );
     415             :     }
     416             :     else
     417             :     {
     418           0 :         aRet = STR_FROM_ANSI( "UNKNOWNFUNC_" );
     419           0 :         aRet += aProgrammaticName;
     420             :     }
     421             : 
     422          24 :     return aRet;
     423             : }
     424             : 
     425          24 : OUString SAL_CALL ScaDateAddIn::getFunctionDescription( const OUString& aProgrammaticName ) throw( uno::RuntimeException )
     426             : {
     427          24 :     OUString aRet;
     428             : 
     429          24 :     const ScaFuncData* pFData = pFuncDataList->Get( aProgrammaticName );
     430          24 :     if( pFData )
     431          24 :         aRet = GetFuncDescrStr( pFData->GetDescrID(), 1 );
     432             : 
     433          24 :     return aRet;
     434             : }
     435             : 
     436          42 : OUString SAL_CALL ScaDateAddIn::getDisplayArgumentName(
     437             :         const OUString& aProgrammaticName, sal_Int32 nArgument ) throw( uno::RuntimeException )
     438             : {
     439          42 :     OUString aRet;
     440             : 
     441          42 :     const ScaFuncData* pFData = pFuncDataList->Get( aProgrammaticName );
     442          42 :     if( pFData && (nArgument <= 0xFFFF) )
     443             :     {
     444          42 :         sal_uInt16 nStr = pFData->GetStrIndex( static_cast< sal_uInt16 >( nArgument ) );
     445          42 :         if( nStr )
     446          42 :             aRet = GetFuncDescrStr( pFData->GetDescrID(), nStr );
     447             :         else
     448           0 :             aRet = STR_FROM_ANSI( "internal" );
     449             :     }
     450             : 
     451          42 :     return aRet;
     452             : }
     453             : 
     454          42 : OUString SAL_CALL ScaDateAddIn::getArgumentDescription(
     455             :         const OUString& aProgrammaticName, sal_Int32 nArgument ) throw( uno::RuntimeException )
     456             : {
     457          42 :     OUString aRet;
     458             : 
     459          42 :     const ScaFuncData* pFData = pFuncDataList->Get( aProgrammaticName );
     460          42 :     if( pFData && (nArgument <= 0xFFFF) )
     461             :     {
     462          42 :         sal_uInt16 nStr = pFData->GetStrIndex( static_cast< sal_uInt16 >( nArgument ) );
     463          42 :         if( nStr )
     464          42 :             aRet = GetFuncDescrStr( pFData->GetDescrID(), nStr + 1 );
     465             :         else
     466           0 :             aRet = STR_FROM_ANSI( "for internal use only" );
     467             :     }
     468             : 
     469          42 :     return aRet;
     470             : }
     471             : 
     472          24 : OUString SAL_CALL ScaDateAddIn::getProgrammaticCategoryName(
     473             :         const OUString& aProgrammaticName ) throw( uno::RuntimeException )
     474             : {
     475          24 :     OUString aRet;
     476             : 
     477          24 :     const ScaFuncData* pFData = pFuncDataList->Get( aProgrammaticName );
     478          24 :     if( pFData )
     479             :     {
     480          24 :         switch( pFData->GetCategory() )
     481             :         {
     482          21 :             case ScaCat_DateTime:   aRet = STR_FROM_ANSI( "Date&Time" );    break;
     483           3 :             case ScaCat_Text:       aRet = STR_FROM_ANSI( "Text" );         break;
     484           0 :             case ScaCat_Finance:    aRet = STR_FROM_ANSI( "Financial" );    break;
     485           0 :             case ScaCat_Inf:        aRet = STR_FROM_ANSI( "Information" );  break;
     486           0 :             case ScaCat_Math:       aRet = STR_FROM_ANSI( "Mathematical" ); break;
     487           0 :             case ScaCat_Tech:       aRet = STR_FROM_ANSI( "Technical" );    break;
     488             :             default:    // to prevent compiler warnings
     489           0 :                 break;
     490             :         }
     491             :     }
     492             : 
     493          24 :     if( aRet.isEmpty() )
     494           0 :         aRet = STR_FROM_ANSI( "Add-In" );
     495          24 :     return aRet;
     496             : }
     497             : 
     498           0 : OUString SAL_CALL ScaDateAddIn::getDisplayCategoryName(
     499             :         const OUString& aProgrammaticName ) throw( uno::RuntimeException )
     500             : {
     501           0 :     return getProgrammaticCategoryName( aProgrammaticName );
     502             : }
     503             : 
     504             : 
     505             : // XCompatibilityNames
     506             : 
     507           8 : uno::Sequence< sheet::LocalizedName > SAL_CALL ScaDateAddIn::getCompatibilityNames(
     508             :         const OUString& aProgrammaticName ) throw( uno::RuntimeException )
     509             : {
     510           8 :     const ScaFuncData* pFData = pFuncDataList->Get( aProgrammaticName );
     511           8 :     if( !pFData )
     512           0 :         return uno::Sequence< sheet::LocalizedName >( 0 );
     513             : 
     514           8 :     const ScaStringList& rStrList = pFData->GetCompNameList();
     515           8 :     sal_uInt32 nCount = rStrList.Count();
     516             : 
     517           8 :     uno::Sequence< sheet::LocalizedName > aRet( nCount );
     518           8 :     sheet::LocalizedName* pArray = aRet.getArray();
     519             : 
     520          24 :     for( sal_uInt32 nIndex = 0; nIndex < nCount; nIndex++ )
     521          16 :         pArray[ nIndex ] = sheet::LocalizedName( GetLocale( nIndex ), *rStrList.Get( nIndex ) );
     522             : 
     523           8 :     return aRet;
     524             : }
     525             : 
     526             : namespace {
     527             : // auxiliary functions
     528             : 
     529           0 : sal_Bool IsLeapYear( sal_uInt16 nYear )
     530             : {
     531           0 :     return ((((nYear % 4) == 0) && ((nYear % 100) != 0)) || ((nYear % 400) == 0));
     532             : }
     533             : 
     534           0 : sal_uInt16 DaysInMonth( sal_uInt16 nMonth, sal_uInt16 nYear )
     535             : {
     536             :     static sal_uInt16 aDaysInMonth[12] = { 31, 28, 31, 30, 31, 30,
     537             :                                         31, 31, 30, 31, 30, 31 };
     538             : 
     539           0 :     if ( nMonth != 2 )
     540           0 :         return aDaysInMonth[nMonth-1];
     541             :     else
     542             :     {
     543           0 :         if ( IsLeapYear(nYear) )
     544           0 :             return aDaysInMonth[nMonth-1] + 1;
     545             :         else
     546           0 :             return aDaysInMonth[nMonth-1];
     547             :     }
     548             : }
     549             : 
     550             : /**
     551             :  * Convert a date to a count of days starting from 01/01/0001
     552             :  *
     553             :  * The internal representation of a Date used in this Addin
     554             :  * is the number of days between 01/01/0001 and the date
     555             :  * this function converts a Day , Month, Year representation
     556             :  * to this internal Date value.
     557             :  */
     558             : 
     559           0 : sal_Int32 DateToDays( sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear )
     560             : {
     561           0 :     sal_Int32 nDays = ((sal_Int32)nYear-1) * 365;
     562           0 :     nDays += ((nYear-1) / 4) - ((nYear-1) / 100) + ((nYear-1) / 400);
     563             : 
     564           0 :     for( sal_uInt16 i = 1; i < nMonth; i++ )
     565           0 :         nDays += DaysInMonth(i,nYear);
     566           0 :     nDays += nDay;
     567             : 
     568           0 :     return nDays;
     569             : }
     570             : 
     571             : /**
     572             :  * Convert a count of days starting from 01/01/0001 to a date
     573             :  *
     574             :  * The internal representation of a Date used in this Addin
     575             :  * is the number of days between 01/01/0001 and the date
     576             :  * this function converts this internal Date value
     577             :  * to a Day , Month, Year representation of a Date.
     578             :  */
     579             : 
     580           0 : void DaysToDate( sal_Int32 nDays,
     581             :                 sal_uInt16& rDay, sal_uInt16& rMonth, sal_uInt16& rYear )
     582             :         throw( lang::IllegalArgumentException )
     583             : {
     584           0 :     if( nDays < 0 )
     585           0 :         throw lang::IllegalArgumentException();
     586             : 
     587             :     sal_Int32   nTempDays;
     588           0 :     sal_Int32   i = 0;
     589             :     sal_Bool    bCalc;
     590             : 
     591           0 :     do
     592             :     {
     593           0 :         nTempDays = nDays;
     594           0 :         rYear = (sal_uInt16)((nTempDays / 365) - i);
     595           0 :         nTempDays -= ((sal_Int32) rYear -1) * 365;
     596           0 :         nTempDays -= (( rYear -1) / 4) - (( rYear -1) / 100) + ((rYear -1) / 400);
     597           0 :         bCalc = sal_False;
     598           0 :         if ( nTempDays < 1 )
     599             :         {
     600           0 :             i++;
     601           0 :             bCalc = sal_True;
     602             :         }
     603             :         else
     604             :         {
     605           0 :             if ( nTempDays > 365 )
     606             :             {
     607           0 :                 if ( (nTempDays != 366) || !IsLeapYear( rYear ) )
     608             :                 {
     609           0 :                     i--;
     610           0 :                     bCalc = sal_True;
     611             :                 }
     612             :             }
     613             :         }
     614             :     }
     615             :     while ( bCalc );
     616             : 
     617           0 :     rMonth = 1;
     618           0 :     while ( (sal_Int32)nTempDays > DaysInMonth( rMonth, rYear ) )
     619             :     {
     620           0 :         nTempDays -= DaysInMonth( rMonth, rYear );
     621           0 :         rMonth++;
     622             :     }
     623           0 :     rDay = (sal_uInt16)nTempDays;
     624           0 : }
     625             : 
     626             : /**
     627             :  * Get the null date used by the spreadsheet document
     628             :  *
     629             :  * The internal representation of a Date used in this Addin
     630             :  * is the number of days between 01/01/0001 and the date
     631             :  * this function returns this internal Date value for the document null date
     632             :  *
     633             :  */
     634             : 
     635           0 : sal_Int32 GetNullDate( const uno::Reference< beans::XPropertySet >& xOptions )
     636             :         throw( uno::RuntimeException )
     637             : {
     638           0 :     if (xOptions.is())
     639             :     {
     640             :         try
     641             :         {
     642           0 :             uno::Any aAny = xOptions->getPropertyValue(
     643           0 :                                         OUString(RTL_CONSTASCII_USTRINGPARAM( "NullDate" )) );
     644           0 :             util::Date aDate;
     645           0 :             if ( aAny >>= aDate )
     646           0 :                 return DateToDays( aDate.Day, aDate.Month, aDate.Year );
     647             :         }
     648           0 :         catch (uno::Exception&)
     649             :         {
     650             :         }
     651             :     }
     652             : 
     653             :     // no null date available -> no calculations possible
     654           0 :     throw uno::RuntimeException();
     655             : }
     656             : 
     657             : }
     658             : // XDateFunctions
     659             : 
     660             : /**
     661             :  * Get week difference between 2 dates
     662             :  *
     663             :  * new Weeks(date1,date2,mode) function for StarCalc
     664             :  *
     665             :  * Two modes of operation are provided.
     666             :  * The first is just a simple division by 7 calculation.
     667             :  *
     668             :  * The second calculates the diffence by week of year.
     669             :  *
     670             :  * The International Standard IS-8601 has decreed that Monday
     671             :  * shall be the first day of the week.
     672             :  *
     673             :  * A week that lies partly in one year and partly in annother
     674             :  * is assigned a number in the the year in which most of its days lie.
     675             :  *
     676             :  * That means that week 1 of any year is the week that contains the 4. January
     677             :  *
     678             :  * The internal representation of a Date used in the Addin is the number of days based on 01/01/0001
     679             :  *
     680             :  * A WeekDay can be then calculated by substracting 1 and calculating the rest of
     681             :  * a division by 7, which gives a 0 - 6 value for Monday - Sunday
     682             :  *
     683             :  * Using the 4. January rule explained above the formula
     684             :  *
     685             :  *  nWeek1= ( nDays1 - nJan4 + ( (nJan4-1) % 7 ) ) / 7 + 1;
     686             :  *
     687             :  * calculates a number between 0-53 for each day which is in the same year as nJan4
     688             :  * where 0 means that this week belonged to the year before.
     689             :  *
     690             :  * If a day in the same or annother year is used in this formula this calculates
     691             :  * an calendar week offset from a given 4. January
     692             :  *
     693             :  *  nWeek2 = ( nDays2 - nJan4 + ( (nJan4-1) % 7 ) ) / 7 + 1;
     694             :  *
     695             :  * The 4.January of first Date Argument can thus be used to calculate
     696             :  * the week difference by calendar weeks which is then nWeek = nWeek2 - nWeek1
     697             :  *
     698             :  * which can be optimized to
     699             :  *
     700             :  * nWeek = ( (nDays2-nJan4+((nJan4-1)%7))/7 ) - ( (nDays1-nJan4+((nJan4-1)%7))/7 )
     701             :  *
     702             :  * Note: All calculations are operating on the long integer data type
     703             :  * % is the modulo operator in C which calculates the rest of an Integer division
     704             :  *
     705             :  *
     706             :  * mode 0 is the interval between the dates in month, that is days / 7
     707             :  *
     708             :  * mode 1 is the difference by week of year
     709             :  *
     710             :  */
     711             : 
     712           0 : sal_Int32 SAL_CALL ScaDateAddIn::getDiffWeeks(
     713             :         const uno::Reference< beans::XPropertySet >& xOptions,
     714             :         sal_Int32 nStartDate, sal_Int32 nEndDate,
     715             :         sal_Int32 nMode ) throw( uno::RuntimeException, lang::IllegalArgumentException )
     716             : {
     717           0 :     sal_Int32 nNullDate = GetNullDate( xOptions );
     718             : 
     719           0 :     sal_Int32 nDays1 = nStartDate + nNullDate;
     720           0 :     sal_Int32 nDays2 = nEndDate + nNullDate;
     721             : 
     722             :     sal_Int32 nRet;
     723             : 
     724           0 :     if ( nMode == 1 )
     725             :     {
     726             :         sal_uInt16 nDay,nMonth,nYear;
     727           0 :         DaysToDate( nDays1, nDay, nMonth, nYear );
     728           0 :         sal_Int32 nJan4 = DateToDays( 4, 1, nYear );
     729             : 
     730           0 :         nRet = ( (nDays2-nJan4+((nJan4-1)%7))/7 ) - ( (nDays1-nJan4+((nJan4-1)%7))/7 );
     731             :     }
     732             :     else
     733             :     {
     734           0 :         nRet = (nDays2 - nDays1) / 7;
     735             :     }
     736           0 :     return nRet;
     737             : }
     738             : 
     739             : /**
     740             :  * Get month difference between 2 dates
     741             :  * =Month(start, end, mode) Function for StarCalc
     742             :  *
     743             :  * two modes are provided
     744             :  *
     745             :  * mode 0 is the interval between the dates in month
     746             :  *
     747             :  * mode 1 is the difference in calendar month
     748             :  */
     749             : 
     750           0 : sal_Int32 SAL_CALL ScaDateAddIn::getDiffMonths(
     751             :         const uno::Reference< beans::XPropertySet >& xOptions,
     752             :         sal_Int32 nStartDate, sal_Int32 nEndDate,
     753             :         sal_Int32 nMode ) throw( uno::RuntimeException, lang::IllegalArgumentException )
     754             : {
     755           0 :     sal_Int32 nNullDate = GetNullDate( xOptions );
     756             : 
     757           0 :     sal_Int32 nDays1 = nStartDate + nNullDate;
     758           0 :     sal_Int32 nDays2 = nEndDate + nNullDate;
     759             : 
     760             :     sal_uInt16 nDay1,nMonth1,nYear1;
     761             :     sal_uInt16 nDay2,nMonth2,nYear2;
     762           0 :     DaysToDate(nDays1,nDay1,nMonth1,nYear1);
     763           0 :     DaysToDate(nDays2,nDay2,nMonth2,nYear2);
     764             : 
     765           0 :     sal_Int32 nRet = nMonth2 - nMonth1 + (nYear2 - nYear1) * 12;
     766           0 :     if ( nMode == 1 || nDays1 == nDays2 ) return nRet;
     767             : 
     768           0 :     if ( nDays1 < nDays2 )
     769             :     {
     770           0 :         if ( nDay1 > nDay2 )
     771             :         {
     772           0 :             nRet -= 1;
     773             :         }
     774             :     }
     775             :     else
     776             :     {
     777           0 :         if ( nDay1 < nDay2 )
     778             :         {
     779           0 :             nRet += 1;
     780             :         }
     781             :     }
     782             : 
     783           0 :     return nRet;
     784             : }
     785             : 
     786             : /**
     787             :  * Get Year difference between 2 dates
     788             :  *
     789             :  * two modes are provided
     790             :  *
     791             :  * mode 0 is the interval between the dates in years
     792             :  *
     793             :  * mode 1 is the difference in calendar years
     794             :  */
     795             : 
     796           0 : sal_Int32 SAL_CALL ScaDateAddIn::getDiffYears(
     797             :         const uno::Reference< beans::XPropertySet >& xOptions,
     798             :         sal_Int32 nStartDate, sal_Int32 nEndDate,
     799             :         sal_Int32 nMode ) throw( uno::RuntimeException, lang::IllegalArgumentException )
     800             : {
     801           0 :     if ( nMode != 1 )
     802           0 :         return getDiffMonths( xOptions, nStartDate, nEndDate, nMode ) / 12;
     803             : 
     804           0 :     sal_Int32 nNullDate = GetNullDate( xOptions );
     805             : 
     806           0 :     sal_Int32 nDays1 = nStartDate + nNullDate;
     807           0 :     sal_Int32 nDays2 = nEndDate + nNullDate;
     808             : 
     809             :     sal_uInt16 nDay1,nMonth1,nYear1;
     810             :     sal_uInt16 nDay2,nMonth2,nYear2;
     811           0 :     DaysToDate(nDays1,nDay1,nMonth1,nYear1);
     812           0 :     DaysToDate(nDays2,nDay2,nMonth2,nYear2);
     813             : 
     814           0 :     return nYear2 - nYear1;
     815             : }
     816             : 
     817             : /**
     818             :  * Check if a Date is in a leap year in the Gregorian calendar
     819             :  */
     820             : 
     821           0 : sal_Int32 SAL_CALL ScaDateAddIn::getIsLeapYear(
     822             :         const uno::Reference< beans::XPropertySet >& xOptions,
     823             :         sal_Int32 nDate ) throw( uno::RuntimeException, lang::IllegalArgumentException )
     824             : {
     825           0 :     sal_Int32 nNullDate = GetNullDate( xOptions );
     826           0 :     sal_Int32 nDays = nDate + nNullDate;
     827             : 
     828             :     sal_uInt16 nDay, nMonth, nYear;
     829           0 :     DaysToDate(nDays,nDay,nMonth,nYear);
     830             : 
     831           0 :     return (sal_Int32)IsLeapYear(nYear);
     832             : }
     833             : 
     834             : /**
     835             :  * Get the Number of Days in the month for a date
     836             :  */
     837             : 
     838           0 : sal_Int32 SAL_CALL ScaDateAddIn::getDaysInMonth(
     839             :         const uno::Reference<beans::XPropertySet>& xOptions,
     840             :         sal_Int32 nDate ) throw( uno::RuntimeException, lang::IllegalArgumentException )
     841             : {
     842           0 :     sal_Int32 nNullDate = GetNullDate( xOptions );
     843           0 :     sal_Int32 nDays = nDate + nNullDate;
     844             : 
     845             :     sal_uInt16 nDay, nMonth, nYear;
     846           0 :     DaysToDate(nDays,nDay,nMonth,nYear);
     847             : 
     848           0 :     return DaysInMonth( nMonth, nYear );
     849             : }
     850             : 
     851             : /**
     852             :  * Get number of days in the year of a date specified
     853             :  */
     854             : 
     855           0 : sal_Int32 SAL_CALL ScaDateAddIn::getDaysInYear(
     856             :         const uno::Reference< beans::XPropertySet >& xOptions,
     857             :         sal_Int32 nDate ) throw( uno::RuntimeException, lang::IllegalArgumentException )
     858             : {
     859           0 :     sal_Int32 nNullDate = GetNullDate( xOptions );
     860           0 :     sal_Int32 nDays = nDate + nNullDate;
     861             : 
     862             :     sal_uInt16 nDay, nMonth, nYear;
     863           0 :     DaysToDate(nDays,nDay,nMonth,nYear);
     864             : 
     865           0 :     return ( IsLeapYear(nYear) ? 366 : 365 );
     866             : }
     867             : 
     868             : /**
     869             :  * Get number of weeks in the year for a date
     870             :  *
     871             :  * Most years have 52 weeks, but years that start on a Thursday
     872             :  * and leep years that start on a Wednesday have 53 weeks
     873             :  *
     874             :  * The International Standard IS-8601 has decreed that Monday
     875             :  * shall be the first day of the week.
     876             :  *
     877             :  * A WeekDay can be calculated by substracting 1 and calculating the rest of
     878             :  * a division by 7 from the internal date represention
     879             :  * which gives a 0 - 6 value for Monday - Sunday
     880             :  *
     881             :  * @see #IsLeapYear #WeekNumber
     882             :  */
     883             : 
     884           0 : sal_Int32 SAL_CALL ScaDateAddIn::getWeeksInYear(
     885             :         const uno::Reference< beans::XPropertySet >& xOptions,
     886             :         sal_Int32 nDate ) throw( uno::RuntimeException, lang::IllegalArgumentException )
     887             : {
     888           0 :     sal_Int32 nNullDate = GetNullDate( xOptions );
     889           0 :     sal_Int32 nDays = nDate + nNullDate;
     890             : 
     891             :     sal_uInt16 nDay, nMonth, nYear;
     892           0 :     DaysToDate(nDays,nDay,nMonth,nYear);
     893             : 
     894           0 :     sal_Int32 nJan1WeekDay = ( DateToDays(1,1,nYear) - 1) % 7;
     895             : 
     896             :     sal_Int32 nRet;
     897           0 :     if ( nJan1WeekDay == 3 )        /* Thursday */
     898           0 :         nRet = 53;
     899           0 :     else if ( nJan1WeekDay == 2 )   /* Wednesday */
     900           0 :         nRet = ( IsLeapYear(nYear) ? 53 : 52 );
     901             :     else
     902           0 :         nRet = 52;
     903             : 
     904           0 :     return nRet;
     905             : }
     906             : 
     907             : /**
     908             :  * Encrypt or decrypt a string using ROT13 algorithm
     909             :  *
     910             :  * This function rotates each character by 13 in the alphabet.
     911             :  * Only the characters 'a' ... 'z' and 'A' ... 'Z' are modified.
     912             :  */
     913             : 
     914           0 : OUString SAL_CALL ScaDateAddIn::getRot13( const OUString& aSrcString ) throw( uno::RuntimeException, lang::IllegalArgumentException )
     915             : {
     916           0 :     OUStringBuffer aBuffer( aSrcString );
     917           0 :     for( sal_Int32 nIndex = 0; nIndex < aBuffer.getLength(); nIndex++ )
     918             :     {
     919           0 :         sal_Unicode cChar = aBuffer[nIndex];
     920           0 :         if( ((cChar >= 'a') && (cChar <= 'z') && ((cChar += 13) > 'z')) ||
     921             :             ((cChar >= 'A') && (cChar <= 'Z') && ((cChar += 13) > 'Z')) )
     922           0 :             cChar -= 26;
     923           0 :         aBuffer[nIndex] = cChar;
     924             :     }
     925           0 :     return aBuffer.makeStringAndClear();
     926             : }
     927             : 
     928             : //------------------------------------------------------------------
     929             : 
     930             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10