Branch data 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 : 153 : ScaList::ScaList() :
54 : 153 : pData( new void*[ nStartSize ] ),
55 : : nSize( nStartSize ),
56 : : nCount( 0 ),
57 : 306 : nCurr( 0 )
58 : : {
59 : 153 : }
60 : :
61 : 63 : ScaList::~ScaList()
62 : : {
63 [ + - ]: 63 : delete[] pData;
64 [ - + ]: 63 : }
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 : 56 : ScaStringList::~ScaStringList()
80 : : {
81 [ + + ]: 168 : for( OUString* pStr = First(); pStr; pStr = Next() )
82 [ + - ]: 112 : delete pStr;
83 [ - + ]: 56 : }
84 : :
85 : : //------------------------------------------------------------------
86 : :
87 : 2380 : ScaResId::ScaResId( sal_uInt16 nId, ResMgr& rResMgr ) :
88 : 2380 : ResId( nId, rResMgr )
89 : : {
90 : 2380 : }
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 : 136 : 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 [ + - ]: 136 : bWithOpt( rBaseData.bWithOpt )
130 : : {
131 [ + - ]: 136 : ScaResStringArrLoader aArrLoader( RID_DATE_DEFFUNCTION_NAMES, nCompListID, rResMgr );
132 : 136 : const ResStringArray& rArr = aArrLoader.GetStringArray();
133 : :
134 [ + + ]: 408 : for( sal_uInt16 nIndex = 0; nIndex < rArr.Count(); nIndex++ )
135 [ + - ][ + - ]: 408 : aCompList.Append( rArr.GetString( nIndex ) );
[ + - ]
136 : 136 : }
137 : :
138 : 56 : ScaFuncData::~ScaFuncData()
139 : : {
140 [ - + ]: 112 : }
141 : :
142 : 476 : sal_uInt16 ScaFuncData::GetStrIndex( sal_uInt16 nParam ) const
143 : : {
144 [ + + ]: 476 : if( !bWithOpt )
145 : 34 : nParam++;
146 [ - + ]: 476 : return (nParam > nParamCount) ? (nParamCount * 2) : (nParam * 2);
147 : : }
148 : :
149 : :
150 : : //------------------------------------------------------------------
151 : :
152 : 17 : ScaFuncDataList::ScaFuncDataList( ResMgr& rResMgr ) :
153 : 17 : nLast( 0xFFFFFFFF )
154 : : {
155 [ + + ]: 153 : for( sal_uInt16 nIndex = 0; nIndex < SAL_N_ELEMENTS(pFuncDataArr); nIndex++ )
156 [ + - ][ + - ]: 136 : Append( new ScaFuncData( pFuncDataArr[ nIndex ], rResMgr ) );
[ + - ]
157 : 17 : }
158 : :
159 : 7 : ScaFuncDataList::~ScaFuncDataList()
160 : : {
161 [ + + ]: 63 : for( ScaFuncData* pFData = First(); pFData; pFData = Next() )
162 [ + - ][ + - ]: 56 : delete pFData;
163 [ - + ]: 14 : }
164 : :
165 : 892 : const ScaFuncData* ScaFuncDataList::Get( const OUString& rProgrammaticName ) const
166 : : {
167 [ + + ]: 892 : if( aLastName == rProgrammaticName )
168 : 748 : return Get( nLast );
169 : :
170 [ + - ]: 648 : for( sal_uInt32 nIndex = 0; nIndex < Count(); nIndex++ )
171 : : {
172 : 648 : const ScaFuncData* pCurr = Get( nIndex );
173 [ + + ]: 648 : if( pCurr->Is( rProgrammaticName ) )
174 : : {
175 : 144 : const_cast< ScaFuncDataList* >( this )->aLastName = rProgrammaticName;
176 : 144 : const_cast< ScaFuncDataList* >( this )->nLast = nIndex;
177 : 144 : return pCurr;
178 : : }
179 : : }
180 : 892 : return NULL;
181 : : }
182 : :
183 : :
184 : : //------------------------------------------------------------------
185 : :
186 : 612 : ScaFuncRes::ScaFuncRes( ResId& rResId, ResMgr& rResMgr, sal_uInt16 nIndex, OUString& rRet ) :
187 : 612 : Resource( rResId )
188 : : {
189 [ + - ][ + - ]: 612 : rRet = String( ScaResId( nIndex, rResMgr ) );
[ + - ]
190 [ + - ]: 612 : FreeResource();
191 : 612 : }
192 : :
193 : :
194 : : //------------------------------------------------------------------
195 : : //
196 : : // entry points for service registration / instantiation
197 : : //
198 : : //------------------------------------------------------------------
199 : :
200 : 17 : uno::Reference< uno::XInterface > SAL_CALL ScaDateAddIn_CreateInstance(
201 : : const uno::Reference< lang::XMultiServiceFactory >& )
202 : : {
203 [ + - ][ + - ]: 17 : static uno::Reference< uno::XInterface > xInst = (cppu::OWeakObject*) new ScaDateAddIn();
[ + - ][ + - ]
[ # # ]
204 : 17 : return xInst;
205 : : }
206 : :
207 : :
208 : : //------------------------------------------------------------------------
209 : :
210 : : extern "C" {
211 : :
212 : 17 : SAL_DLLPUBLIC_EXPORT void * SAL_CALL date_component_getFactory(
213 : : const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ )
214 : : {
215 : 17 : void* pRet = 0;
216 : :
217 [ + - + - ]: 51 : if ( pServiceManager &&
[ + - ]
218 [ + - ][ + - ]: 34 : 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 [ + - ][ + - ]: 17 : ScaDateAddIn::getSupportedServiceNames_Static() ) );
[ + - ][ + - ]
[ + - ]
225 : :
226 [ + - ]: 17 : if (xFactory.is())
227 : : {
228 [ + - ]: 17 : xFactory->acquire();
229 [ + - ]: 17 : pRet = xFactory.get();
230 : 17 : }
231 : : }
232 : :
233 : 17 : return pRet;
234 : : }
235 : :
236 : : } // extern C
237 : :
238 : : //------------------------------------------------------------------------
239 : : //
240 : : // "normal" service implementation
241 : : //
242 : : //------------------------------------------------------------------------
243 : :
244 : 17 : ScaDateAddIn::ScaDateAddIn() :
245 : : pDefLocales( NULL ),
246 : : pResMgr( NULL ),
247 : 17 : pFuncDataList( NULL )
248 : : {
249 : 17 : }
250 : :
251 : 7 : ScaDateAddIn::~ScaDateAddIn()
252 : : {
253 [ + - ]: 7 : if( pFuncDataList )
254 [ + - ][ + - ]: 7 : delete pFuncDataList;
255 [ + + ]: 7 : if( pDefLocales )
256 [ + - ][ + + ]: 3 : delete[] pDefLocales;
257 : :
258 : : // pResMgr already deleted (_all_ resource managers are deleted _before_ this dtor is called)
259 [ - + ]: 14 : }
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 [ + + ]: 3 : 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 : 1972 : ResMgr& ScaDateAddIn::GetResMgr() throw( uno::RuntimeException )
285 : : {
286 [ - + ]: 1972 : if( !pResMgr )
287 : : {
288 : 0 : InitData(); // try to get resource manager
289 [ # # ]: 0 : if( !pResMgr )
290 [ # # ]: 0 : throw uno::RuntimeException();
291 : : }
292 : 1972 : return *pResMgr;
293 : : }
294 : :
295 : 17 : void ScaDateAddIn::InitData()
296 : : {
297 [ - + ]: 17 : if( pResMgr )
298 [ # # ][ # # ]: 0 : delete pResMgr;
299 : :
300 : 17 : OString aModName( "date" );
301 [ + - ]: 17 : pResMgr = ResMgr::CreateResMgr( aModName.getStr(), aFuncLoc );
302 : :
303 [ - + ]: 17 : if( pFuncDataList )
304 [ # # ][ # # ]: 0 : delete pFuncDataList;
305 : :
306 [ + - ][ + - ]: 17 : pFuncDataList = pResMgr ? new ScaFuncDataList( *pResMgr ) : NULL;
[ + - ]
307 : :
308 [ - + ]: 17 : if( pDefLocales )
309 : : {
310 [ # # ]: 0 : delete pDefLocales;
311 : 0 : pDefLocales = NULL;
312 : 17 : }
313 : 17 : }
314 : :
315 : 136 : OUString ScaDateAddIn::GetDisplFuncStr( sal_uInt16 nResId ) throw( uno::RuntimeException )
316 : : {
317 [ + - ]: 136 : return ScaResStringLoader( RID_DATE_FUNCTION_NAMES, nResId, GetResMgr() ).GetString();
318 : : }
319 : :
320 : 612 : OUString ScaDateAddIn::GetFuncDescrStr( sal_uInt16 nResId, sal_uInt16 nStrIndex ) throw( uno::RuntimeException )
321 : : {
322 : 612 : OUString aRet;
323 : :
324 [ + - ][ + - ]: 612 : ScaResPublisher aResPubl( ScaResId( RID_DATE_FUNCTION_DESCRIPTIONS, GetResMgr() ) );
325 [ + - ]: 612 : ScaResId aResId( nResId, GetResMgr() );
326 : 612 : aResId.SetRT( RSC_RESOURCE );
327 : :
328 [ + - ][ + - ]: 612 : if( aResPubl.IsAvailableRes( aResId ) )
329 [ + - ][ + - ]: 612 : ScaFuncRes aSubRes( aResId, GetResMgr(), nStrIndex, aRet );
330 : :
331 [ + - ]: 612 : aResPubl.FreeResource();
332 : 612 : return aRet;
333 : : }
334 : :
335 : :
336 : : //------------------------------------------------------------------------
337 : :
338 : 34 : OUString ScaDateAddIn::getImplementationName_Static()
339 : : {
340 : 34 : return OUString(RTL_CONSTASCII_USTRINGPARAM( MY_IMPLNAME ));
341 : : }
342 : :
343 : 17 : uno::Sequence< OUString > ScaDateAddIn::getSupportedServiceNames_Static()
344 : : {
345 : 17 : uno::Sequence< OUString > aRet( 2 );
346 [ + - ]: 17 : OUString* pArray = aRet.getArray();
347 [ + - ]: 17 : pArray[0] = OUString(RTL_CONSTASCII_USTRINGPARAM( ADDIN_SERVICE ));
348 [ + - ]: 17 : pArray[1] = OUString(RTL_CONSTASCII_USTRINGPARAM( MY_SERVICE ));
349 : 17 : return aRet;
350 : : }
351 : :
352 : : // XServiceName
353 : :
354 : 34 : OUString SAL_CALL ScaDateAddIn::getServiceName() throw( uno::RuntimeException )
355 : : {
356 : : // name of specific AddIn service
357 : 34 : 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 : 17 : void SAL_CALL ScaDateAddIn::setLocale( const lang::Locale& eLocale ) throw( uno::RuntimeException )
380 : : {
381 : 17 : aFuncLoc = eLocale;
382 : 17 : InitData(); // change of locale invalidates resources!
383 : 17 : }
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 : 136 : OUString SAL_CALL ScaDateAddIn::getDisplayFunctionName( const OUString& aProgrammaticName ) throw( uno::RuntimeException )
406 : : {
407 : 136 : OUString aRet;
408 : :
409 : 136 : const ScaFuncData* pFData = pFuncDataList->Get( aProgrammaticName );
410 [ + - ]: 136 : if( pFData )
411 : : {
412 [ + - ]: 136 : aRet = GetDisplFuncStr( pFData->GetUINameID() );
413 [ - + ]: 136 : 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 : 136 : return aRet;
423 : : }
424 : :
425 : 136 : OUString SAL_CALL ScaDateAddIn::getFunctionDescription( const OUString& aProgrammaticName ) throw( uno::RuntimeException )
426 : : {
427 : 136 : OUString aRet;
428 : :
429 : 136 : const ScaFuncData* pFData = pFuncDataList->Get( aProgrammaticName );
430 [ + - ]: 136 : if( pFData )
431 [ + - ]: 136 : aRet = GetFuncDescrStr( pFData->GetDescrID(), 1 );
432 : :
433 : 136 : return aRet;
434 : : }
435 : :
436 : 238 : OUString SAL_CALL ScaDateAddIn::getDisplayArgumentName(
437 : : const OUString& aProgrammaticName, sal_Int32 nArgument ) throw( uno::RuntimeException )
438 : : {
439 : 238 : OUString aRet;
440 : :
441 : 238 : const ScaFuncData* pFData = pFuncDataList->Get( aProgrammaticName );
442 [ + - ][ + - ]: 238 : if( pFData && (nArgument <= 0xFFFF) )
443 : : {
444 : 238 : sal_uInt16 nStr = pFData->GetStrIndex( static_cast< sal_uInt16 >( nArgument ) );
445 [ + - ]: 238 : if( nStr )
446 [ + - ]: 238 : aRet = GetFuncDescrStr( pFData->GetDescrID(), nStr );
447 : : else
448 [ # # ]: 0 : aRet = STR_FROM_ANSI( "internal" );
449 : : }
450 : :
451 : 238 : return aRet;
452 : : }
453 : :
454 : 238 : OUString SAL_CALL ScaDateAddIn::getArgumentDescription(
455 : : const OUString& aProgrammaticName, sal_Int32 nArgument ) throw( uno::RuntimeException )
456 : : {
457 : 238 : OUString aRet;
458 : :
459 : 238 : const ScaFuncData* pFData = pFuncDataList->Get( aProgrammaticName );
460 [ + - ][ + - ]: 238 : if( pFData && (nArgument <= 0xFFFF) )
461 : : {
462 : 238 : sal_uInt16 nStr = pFData->GetStrIndex( static_cast< sal_uInt16 >( nArgument ) );
463 [ + - ]: 238 : if( nStr )
464 [ + - ]: 238 : aRet = GetFuncDescrStr( pFData->GetDescrID(), nStr + 1 );
465 : : else
466 [ # # ]: 0 : aRet = STR_FROM_ANSI( "for internal use only" );
467 : : }
468 : :
469 : 238 : return aRet;
470 : : }
471 : :
472 : 136 : OUString SAL_CALL ScaDateAddIn::getProgrammaticCategoryName(
473 : : const OUString& aProgrammaticName ) throw( uno::RuntimeException )
474 : : {
475 : 136 : OUString aRet;
476 : :
477 : 136 : const ScaFuncData* pFData = pFuncDataList->Get( aProgrammaticName );
478 [ + - ]: 136 : if( pFData )
479 : : {
480 [ + + - - : 136 : switch( pFData->GetCategory() )
- - - ]
481 : : {
482 [ + - ]: 119 : case ScaCat_DateTime: aRet = STR_FROM_ANSI( "Date&Time" ); break;
483 [ + - ]: 17 : 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 : 136 : break;
490 : : }
491 : : }
492 : :
493 [ - + ]: 136 : if( aRet.isEmpty() )
494 [ # # ]: 0 : aRet = STR_FROM_ANSI( "Add-In" );
495 : 136 : 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 : :
527 : : //------------------------------------------------------------------
528 : : //
529 : : // function implementation starts here
530 : : //
531 : : //------------------------------------------------------------------
532 : :
533 : : // auxiliary functions
534 : :
535 : 0 : sal_Bool IsLeapYear( sal_uInt16 nYear )
536 : : {
537 [ # # ][ # # ]: 0 : return ((((nYear % 4) == 0) && ((nYear % 100) != 0)) || ((nYear % 400) == 0));
[ # # ]
538 : : }
539 : :
540 : 0 : sal_uInt16 DaysInMonth( sal_uInt16 nMonth, sal_uInt16 nYear )
541 : : {
542 : : static sal_uInt16 aDaysInMonth[12] = { 31, 28, 31, 30, 31, 30,
543 : : 31, 31, 30, 31, 30, 31 };
544 : :
545 [ # # ]: 0 : if ( nMonth != 2 )
546 : 0 : return aDaysInMonth[nMonth-1];
547 : : else
548 : : {
549 [ # # ]: 0 : if ( IsLeapYear(nYear) )
550 : 0 : return aDaysInMonth[nMonth-1] + 1;
551 : : else
552 : 0 : return aDaysInMonth[nMonth-1];
553 : : }
554 : : }
555 : :
556 : : /**
557 : : * Convert a date to a count of days starting from 01/01/0001
558 : : *
559 : : * The internal representation of a Date used in this Addin
560 : : * is the number of days between 01/01/0001 and the date
561 : : * this function converts a Day , Month, Year representation
562 : : * to this internal Date value.
563 : : */
564 : :
565 : 0 : sal_Int32 DateToDays( sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear )
566 : : {
567 : 0 : sal_Int32 nDays = ((sal_Int32)nYear-1) * 365;
568 : 0 : nDays += ((nYear-1) / 4) - ((nYear-1) / 100) + ((nYear-1) / 400);
569 : :
570 [ # # ]: 0 : for( sal_uInt16 i = 1; i < nMonth; i++ )
571 : 0 : nDays += DaysInMonth(i,nYear);
572 : 0 : nDays += nDay;
573 : :
574 : 0 : return nDays;
575 : : }
576 : :
577 : : /**
578 : : * Convert a count of days starting from 01/01/0001 to a date
579 : : *
580 : : * The internal representation of a Date used in this Addin
581 : : * is the number of days between 01/01/0001 and the date
582 : : * this function converts this internal Date value
583 : : * to a Day , Month, Year representation of a Date.
584 : : */
585 : :
586 : 0 : void DaysToDate( sal_Int32 nDays,
587 : : sal_uInt16& rDay, sal_uInt16& rMonth, sal_uInt16& rYear )
588 : : throw( lang::IllegalArgumentException )
589 : : {
590 [ # # ]: 0 : if( nDays < 0 )
591 [ # # ]: 0 : throw lang::IllegalArgumentException();
592 : :
593 : : sal_Int32 nTempDays;
594 : 0 : sal_Int32 i = 0;
595 : : sal_Bool bCalc;
596 : :
597 [ # # ]: 0 : do
598 : : {
599 : 0 : nTempDays = nDays;
600 : 0 : rYear = (sal_uInt16)((nTempDays / 365) - i);
601 : 0 : nTempDays -= ((sal_Int32) rYear -1) * 365;
602 : 0 : nTempDays -= (( rYear -1) / 4) - (( rYear -1) / 100) + ((rYear -1) / 400);
603 : 0 : bCalc = sal_False;
604 [ # # ]: 0 : if ( nTempDays < 1 )
605 : : {
606 : 0 : i++;
607 : 0 : bCalc = sal_True;
608 : : }
609 : : else
610 : : {
611 [ # # ]: 0 : if ( nTempDays > 365 )
612 : : {
613 [ # # ][ # # ]: 0 : if ( (nTempDays != 366) || !IsLeapYear( rYear ) )
[ # # ]
614 : : {
615 : 0 : i--;
616 : 0 : bCalc = sal_True;
617 : : }
618 : : }
619 : : }
620 : : }
621 : : while ( bCalc );
622 : :
623 : 0 : rMonth = 1;
624 [ # # ]: 0 : while ( (sal_Int32)nTempDays > DaysInMonth( rMonth, rYear ) )
625 : : {
626 : 0 : nTempDays -= DaysInMonth( rMonth, rYear );
627 : 0 : rMonth++;
628 : : }
629 : 0 : rDay = (sal_uInt16)nTempDays;
630 : 0 : }
631 : :
632 : : /**
633 : : * Get the null date used by the spreadsheet document
634 : : *
635 : : * The internal representation of a Date used in this Addin
636 : : * is the number of days between 01/01/0001 and the date
637 : : * this function returns this internal Date value for the document null date
638 : : *
639 : : */
640 : :
641 : 0 : sal_Int32 GetNullDate( const uno::Reference< beans::XPropertySet >& xOptions )
642 : : throw( uno::RuntimeException )
643 : : {
644 [ # # ]: 0 : if (xOptions.is())
645 : : {
646 : : try
647 : : {
648 [ # # ]: 0 : uno::Any aAny = xOptions->getPropertyValue(
649 [ # # ][ # # ]: 0 : OUString(RTL_CONSTASCII_USTRINGPARAM( "NullDate" )) );
650 : 0 : util::Date aDate;
651 [ # # ][ # # ]: 0 : if ( aAny >>= aDate )
652 [ # # ][ # # ]: 0 : return DateToDays( aDate.Day, aDate.Month, aDate.Year );
653 : : }
654 : 0 : catch (uno::Exception&)
655 : : {
656 : : }
657 : : }
658 : :
659 : : // no null date available -> no calculations possible
660 [ # # ]: 0 : throw uno::RuntimeException();
661 : : }
662 : :
663 : : // XDateFunctions
664 : :
665 : : /**
666 : : * Get week difference between 2 dates
667 : : *
668 : : * new Weeks(date1,date2,mode) function for StarCalc
669 : : *
670 : : * Two modes of operation are provided.
671 : : * The first is just a simple division by 7 calculation.
672 : : *
673 : : * The second calculates the diffence by week of year.
674 : : *
675 : : * The International Standard IS-8601 has decreed that Monday
676 : : * shall be the first day of the week.
677 : : *
678 : : * A week that lies partly in one year and partly in annother
679 : : * is assigned a number in the the year in which most of its days lie.
680 : : *
681 : : * That means that week 1 of any year is the week that contains the 4. January
682 : : *
683 : : * The internal representation of a Date used in the Addin is the number of days based on 01/01/0001
684 : : *
685 : : * A WeekDay can be then calculated by substracting 1 and calculating the rest of
686 : : * a division by 7, which gives a 0 - 6 value for Monday - Sunday
687 : : *
688 : : * Using the 4. January rule explained above the formula
689 : : *
690 : : * nWeek1= ( nDays1 - nJan4 + ( (nJan4-1) % 7 ) ) / 7 + 1;
691 : : *
692 : : * calculates a number between 0-53 for each day which is in the same year as nJan4
693 : : * where 0 means that this week belonged to the year before.
694 : : *
695 : : * If a day in the same or annother year is used in this formula this calculates
696 : : * an calendar week offset from a given 4. January
697 : : *
698 : : * nWeek2 = ( nDays2 - nJan4 + ( (nJan4-1) % 7 ) ) / 7 + 1;
699 : : *
700 : : * The 4.January of first Date Argument can thus be used to calculate
701 : : * the week difference by calendar weeks which is then nWeek = nWeek2 - nWeek1
702 : : *
703 : : * which can be optimized to
704 : : *
705 : : * nWeek = ( (nDays2-nJan4+((nJan4-1)%7))/7 ) - ( (nDays1-nJan4+((nJan4-1)%7))/7 )
706 : : *
707 : : * Note: All calculations are operating on the long integer data type
708 : : * % is the modulo operator in C which calculates the rest of an Integer division
709 : : *
710 : : *
711 : : * mode 0 is the interval between the dates in month, that is days / 7
712 : : *
713 : : * mode 1 is the difference by week of year
714 : : *
715 : : */
716 : :
717 : 0 : sal_Int32 SAL_CALL ScaDateAddIn::getDiffWeeks(
718 : : const uno::Reference< beans::XPropertySet >& xOptions,
719 : : sal_Int32 nStartDate, sal_Int32 nEndDate,
720 : : sal_Int32 nMode ) throw( uno::RuntimeException, lang::IllegalArgumentException )
721 : : {
722 : 0 : sal_Int32 nNullDate = GetNullDate( xOptions );
723 : :
724 : 0 : sal_Int32 nDays1 = nStartDate + nNullDate;
725 : 0 : sal_Int32 nDays2 = nEndDate + nNullDate;
726 : :
727 : : sal_Int32 nRet;
728 : :
729 [ # # ]: 0 : if ( nMode == 1 )
730 : : {
731 : : sal_uInt16 nDay,nMonth,nYear;
732 [ # # ]: 0 : DaysToDate( nDays1, nDay, nMonth, nYear );
733 : 0 : sal_Int32 nJan4 = DateToDays( 4, 1, nYear );
734 : :
735 : 0 : nRet = ( (nDays2-nJan4+((nJan4-1)%7))/7 ) - ( (nDays1-nJan4+((nJan4-1)%7))/7 );
736 : : }
737 : : else
738 : : {
739 : 0 : nRet = (nDays2 - nDays1) / 7;
740 : : }
741 : 0 : return nRet;
742 : : }
743 : :
744 : : /**
745 : : * Get month difference between 2 dates
746 : : * =Month(start, end, mode) Function for StarCalc
747 : : *
748 : : * two modes are provided
749 : : *
750 : : * mode 0 is the interval between the dates in month
751 : : *
752 : : * mode 1 is the difference in calendar month
753 : : */
754 : :
755 : 0 : sal_Int32 SAL_CALL ScaDateAddIn::getDiffMonths(
756 : : const uno::Reference< beans::XPropertySet >& xOptions,
757 : : sal_Int32 nStartDate, sal_Int32 nEndDate,
758 : : sal_Int32 nMode ) throw( uno::RuntimeException, lang::IllegalArgumentException )
759 : : {
760 [ # # ]: 0 : sal_Int32 nNullDate = GetNullDate( xOptions );
761 : :
762 : 0 : sal_Int32 nDays1 = nStartDate + nNullDate;
763 : 0 : sal_Int32 nDays2 = nEndDate + nNullDate;
764 : :
765 : : sal_uInt16 nDay1,nMonth1,nYear1;
766 : : sal_uInt16 nDay2,nMonth2,nYear2;
767 [ # # ]: 0 : DaysToDate(nDays1,nDay1,nMonth1,nYear1);
768 [ # # ]: 0 : DaysToDate(nDays2,nDay2,nMonth2,nYear2);
769 : :
770 : 0 : sal_Int32 nRet = nMonth2 - nMonth1 + (nYear2 - nYear1) * 12;
771 [ # # ][ # # ]: 0 : if ( nMode == 1 || nDays1 == nDays2 ) return nRet;
772 : :
773 [ # # ]: 0 : if ( nDays1 < nDays2 )
774 : : {
775 [ # # ]: 0 : if ( nDay1 > nDay2 )
776 : : {
777 : 0 : nRet -= 1;
778 : : }
779 : : }
780 : : else
781 : : {
782 [ # # ]: 0 : if ( nDay1 < nDay2 )
783 : : {
784 : 0 : nRet += 1;
785 : : }
786 : : }
787 : :
788 : 0 : return nRet;
789 : : }
790 : :
791 : : /**
792 : : * Get Year difference between 2 dates
793 : : *
794 : : * two modes are provided
795 : : *
796 : : * mode 0 is the interval between the dates in years
797 : : *
798 : : * mode 1 is the difference in calendar years
799 : : */
800 : :
801 : 0 : sal_Int32 SAL_CALL ScaDateAddIn::getDiffYears(
802 : : const uno::Reference< beans::XPropertySet >& xOptions,
803 : : sal_Int32 nStartDate, sal_Int32 nEndDate,
804 : : sal_Int32 nMode ) throw( uno::RuntimeException, lang::IllegalArgumentException )
805 : : {
806 [ # # ]: 0 : if ( nMode != 1 )
807 [ # # ]: 0 : return getDiffMonths( xOptions, nStartDate, nEndDate, nMode ) / 12;
808 : :
809 [ # # ]: 0 : sal_Int32 nNullDate = GetNullDate( xOptions );
810 : :
811 : 0 : sal_Int32 nDays1 = nStartDate + nNullDate;
812 : 0 : sal_Int32 nDays2 = nEndDate + nNullDate;
813 : :
814 : : sal_uInt16 nDay1,nMonth1,nYear1;
815 : : sal_uInt16 nDay2,nMonth2,nYear2;
816 [ # # ]: 0 : DaysToDate(nDays1,nDay1,nMonth1,nYear1);
817 [ # # ]: 0 : DaysToDate(nDays2,nDay2,nMonth2,nYear2);
818 : :
819 : 0 : return nYear2 - nYear1;
820 : : }
821 : :
822 : : /**
823 : : * Check if a Date is in a leap year in the Gregorian calendar
824 : : */
825 : :
826 : 0 : sal_Int32 SAL_CALL ScaDateAddIn::getIsLeapYear(
827 : : const uno::Reference< beans::XPropertySet >& xOptions,
828 : : sal_Int32 nDate ) throw( uno::RuntimeException, lang::IllegalArgumentException )
829 : : {
830 [ # # ]: 0 : sal_Int32 nNullDate = GetNullDate( xOptions );
831 : 0 : sal_Int32 nDays = nDate + nNullDate;
832 : :
833 : : sal_uInt16 nDay, nMonth, nYear;
834 [ # # ]: 0 : DaysToDate(nDays,nDay,nMonth,nYear);
835 : :
836 : 0 : return (sal_Int32)IsLeapYear(nYear);
837 : : }
838 : :
839 : : /**
840 : : * Get the Number of Days in the month for a date
841 : : */
842 : :
843 : 0 : sal_Int32 SAL_CALL ScaDateAddIn::getDaysInMonth(
844 : : const uno::Reference<beans::XPropertySet>& xOptions,
845 : : sal_Int32 nDate ) throw( uno::RuntimeException, lang::IllegalArgumentException )
846 : : {
847 [ # # ]: 0 : sal_Int32 nNullDate = GetNullDate( xOptions );
848 : 0 : sal_Int32 nDays = nDate + nNullDate;
849 : :
850 : : sal_uInt16 nDay, nMonth, nYear;
851 [ # # ]: 0 : DaysToDate(nDays,nDay,nMonth,nYear);
852 : :
853 : 0 : return DaysInMonth( nMonth, nYear );
854 : : }
855 : :
856 : : /**
857 : : * Get number of days in the year of a date specified
858 : : */
859 : :
860 : 0 : sal_Int32 SAL_CALL ScaDateAddIn::getDaysInYear(
861 : : const uno::Reference< beans::XPropertySet >& xOptions,
862 : : sal_Int32 nDate ) throw( uno::RuntimeException, lang::IllegalArgumentException )
863 : : {
864 [ # # ]: 0 : sal_Int32 nNullDate = GetNullDate( xOptions );
865 : 0 : sal_Int32 nDays = nDate + nNullDate;
866 : :
867 : : sal_uInt16 nDay, nMonth, nYear;
868 [ # # ]: 0 : DaysToDate(nDays,nDay,nMonth,nYear);
869 : :
870 [ # # ]: 0 : return ( IsLeapYear(nYear) ? 366 : 365 );
871 : : }
872 : :
873 : : /**
874 : : * Get number of weeks in the year for a date
875 : : *
876 : : * Most years have 52 weeks, but years that start on a Thursday
877 : : * and leep years that start on a Wednesday have 53 weeks
878 : : *
879 : : * The International Standard IS-8601 has decreed that Monday
880 : : * shall be the first day of the week.
881 : : *
882 : : * A WeekDay can be calculated by substracting 1 and calculating the rest of
883 : : * a division by 7 from the internal date represention
884 : : * which gives a 0 - 6 value for Monday - Sunday
885 : : *
886 : : * @see #IsLeapYear #WeekNumber
887 : : */
888 : :
889 : 0 : sal_Int32 SAL_CALL ScaDateAddIn::getWeeksInYear(
890 : : const uno::Reference< beans::XPropertySet >& xOptions,
891 : : sal_Int32 nDate ) throw( uno::RuntimeException, lang::IllegalArgumentException )
892 : : {
893 [ # # ]: 0 : sal_Int32 nNullDate = GetNullDate( xOptions );
894 : 0 : sal_Int32 nDays = nDate + nNullDate;
895 : :
896 : : sal_uInt16 nDay, nMonth, nYear;
897 [ # # ]: 0 : DaysToDate(nDays,nDay,nMonth,nYear);
898 : :
899 : 0 : sal_Int32 nJan1WeekDay = ( DateToDays(1,1,nYear) - 1) % 7;
900 : :
901 : : sal_Int32 nRet;
902 [ # # ]: 0 : if ( nJan1WeekDay == 3 ) /* Thursday */
903 : 0 : nRet = 53;
904 [ # # ]: 0 : else if ( nJan1WeekDay == 2 ) /* Wednesday */
905 [ # # ]: 0 : nRet = ( IsLeapYear(nYear) ? 53 : 52 );
906 : : else
907 : 0 : nRet = 52;
908 : :
909 : 0 : return nRet;
910 : : }
911 : :
912 : : /**
913 : : * Encrypt or decrypt a string using ROT13 algorithm
914 : : *
915 : : * This function rotates each character by 13 in the alphabet.
916 : : * Only the characters 'a' ... 'z' and 'A' ... 'Z' are modified.
917 : : */
918 : :
919 : 0 : OUString SAL_CALL ScaDateAddIn::getRot13( const OUString& aSrcString ) throw( uno::RuntimeException, lang::IllegalArgumentException )
920 : : {
921 [ # # ]: 0 : OUStringBuffer aBuffer( aSrcString );
922 [ # # ]: 0 : for( sal_Int32 nIndex = 0; nIndex < aBuffer.getLength(); nIndex++ )
923 : : {
924 : 0 : sal_Unicode cChar = aBuffer[nIndex];
925 [ # # ][ # # ]: 0 : if( ((cChar >= 'a') && (cChar <= 'z') && ((cChar += 13) > 'z')) ||
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
926 : : ((cChar >= 'A') && (cChar <= 'Z') && ((cChar += 13) > 'Z')) )
927 : 0 : cChar -= 26;
928 : 0 : aBuffer[nIndex] = cChar;
929 : : }
930 [ # # ]: 0 : return aBuffer.makeStringAndClear();
931 : : }
932 : :
933 : : //------------------------------------------------------------------
934 : :
935 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|