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

Generated by: LCOV version 1.10