xref: /aoo42x/main/sc/workben/addin.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifdef _MSC_VER
29 #pragma hdrstop
30 #endif
31 
32 #include <usr/factoryhlp.hxx>
33 #include <usr/macros.hxx>
34 #include <usr/reflserv.hxx>
35 #include <vos/mutex.hxx>
36 #include <vcl/svapp.hxx>
37 #include <tools/debug.hxx>
38 #include <tools/date.hxx>
39 #include <svl/itemprop.hxx>
40 #include <usr/proptypehlp.hxx>
41 #include <cppuhelper/factory.hxx>
42 #include <uno/lbnames.h>
43 #include <osl/diagnose.h>
44 
45 #include <com/sun/star/util/date.hpp>
46 
47 #include "addin.hxx"
48 #include "result.hxx"
49 
50 using namespace com::sun::star;
51 
52 //------------------------------------------------------------------------
53 
54 
55 //------------------------------------------------------------------------
56 
57 SMART_UNO_IMPLEMENTATION( ScTestAddIn, UsrObject );
58 
59 #define SCADDIN_SERVICE			L"com.sun.star.sheet.AddIn"
60 #define SCTESTADDIN_SERVICE		L"stardiv.one.sheet.DemoAddIn"
61 
62 //------------------------------------------------------------------------
63 
64 extern "C" {
65 
66 void SAL_CALL component_getImplementationEnvironment(
67 	const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv )
68 {
69 	*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
70 }
71 
72 sal_Bool SAL_CALL component_writeInfo(
73 	void * pServiceManager, registry::XRegistryKey * pRegistryKey )
74 {
75 	if (pRegistryKey)
76 	{
77 		try
78 		{
79 			UString aImpl = L"/";
80 			aImpl += ScTestAddIn::getImplementationName_Static();
81 			aImpl += L"/UNO/SERVICES";
82 
83 			uno::Reference<registry::XRegistryKey> xNewKey(
84 				reinterpret_cast<registry::XRegistryKey*>(pRegistryKey)->createKey(aImpl) );
85 
86 			uno::Sequence <rtl::OUString> aSequ = ScTestAddIn::getSupportedServiceNames_Static();
87 			const rtl::OUString * pArray = aSequ.getConstArray();
88 			for( INT32 i = 0; i < aSequ.getLength(); i++ )
89 				xNewKey->createKey( pArray[i] );
90 
91 			return sal_True;
92 		}
93 		catch (registry::InvalidRegistryException&)
94 		{
95 			OSL_ENSHURE( sal_False, "### InvalidRegistryException!" );
96 		}
97 	}
98 	return sal_False;
99 }
100 
101 void * SAL_CALL component_getFactory(
102 	const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
103 {
104 	void* pRet = 0;
105 
106 	if ( pServiceManager && UString(pImplName) == ScTestAddIn::getImplementationName_Static() )
107 	{
108 		uno::Reference<lang::XSingleServiceFactory> xFactory( cppu::createOneInstanceFactory(
109 				reinterpret_cast<lang::XMultiServiceFactory*>(pServiceManager),
110 				ScTestAddIn::getImplementationName_Static(),
111 				ScTestAddIn_CreateInstance,
112 				ScTestAddIn::getSupportedServiceNames_Static() ) );
113 
114 		if (xFactory.is())
115 		{
116 			xFactory->acquire();
117 			pRet = xFactory.get();
118 		}
119 	}
120 
121 	return pRet;
122 }
123 
124 }	// extern C
125 
126 //------------------------------------------------------------------------
127 
128 ScTestAddIn::ScTestAddIn()
129 {
130 }
131 
132 ScTestAddIn::~ScTestAddIn()
133 {
134 }
135 
136 UString ScTestAddIn::getImplementationName_Static()
137 {
138 	return L"stardiv.StarCalc.ScTestAddIn";
139 }
140 
141 ::com::sun::star::uno::Sequence< ::rtl::OUString > ScTestAddIn::getSupportedServiceNames_Static()
142 {
143 	uno::Sequence< rtl::OUString > aRet(2);
144 	rtl::OUString* pArray = aRet.getArray();
145 	pArray[0] = SCADDIN_SERVICE;
146 	pArray[1] = SCTESTADDIN_SERVICE;
147 	return aRet;
148 }
149 
150 uno::Reference<uno::XInterface> ScTestAddIn_CreateInstance(
151 		const uno::Reference<lang::XMultiServiceFactory>& )
152 {
153 	static uno::Reference<uno::XInterface> xInst = (cppu::OWeakObject*)new ScTestAddIn();
154 	return xInst;
155 }
156 
157 
158 // XAddIn
159 
160 UString ScTestAddIn::getProgrammaticFuntionName(const UString& aDisplayName)
161 								THROWS( (UsrSystemException) )
162 {
163 	//!...
164 	return UString();
165 }
166 
167 UString ScTestAddIn::getDisplayFunctionName(const UString& aProgrammaticName)
168 								THROWS( (UsrSystemException) )
169 {
170 	//	return translated strings
171 
172 	UString aRet;
173 	if ( aProgrammaticName == L"countParams" )		  aRet = L"ParamAnzahl";
174 	else if ( aProgrammaticName == L"addOne" )		  aRet = L"PlusEins";
175 	else if ( aProgrammaticName == L"repeatStr" )	  aRet = L"WiederholeString";
176 	else if ( aProgrammaticName == L"getDateString" ) aRet = L"Datumsstring";
177 	else if ( aProgrammaticName == L"getColorValue" ) aRet = L"Farbwert";
178 	else if ( aProgrammaticName == L"transpose" )	  aRet = L"Transponieren";
179 	else if ( aProgrammaticName == L"transposeInt" )  aRet = L"IntegerTransponieren";
180 	else if ( aProgrammaticName == L"repeatMultiple" )aRet = L"Mehrfach";
181 	else if ( aProgrammaticName == L"getStrOrVal" )	  aRet = L"StringOderWert";
182 	else if ( aProgrammaticName == L"callAsync" )	  aRet = L"Asynchron";
183 	return aRet;
184 }
185 
186 UString ScTestAddIn::getFunctionDescription(const UString& aProgrammaticName)
187 								THROWS( (UsrSystemException) )
188 {
189 	//	return translated strings
190 
191 	UString aRet;
192 	if ( aProgrammaticName == L"countParams" )		  aRet = L"Gibt die Anzahl der Parameter zurueck.";
193 	else if ( aProgrammaticName == L"addOne" )		  aRet = L"Addiert 1 zur uebergebenen Zahl.";
194 	else if ( aProgrammaticName == L"repeatStr" )	  aRet = L"Wiederholt eine Zeichenkette.";
195 	else if ( aProgrammaticName == L"getDateString" ) aRet = L"Wandelt ein Datum in eine Zeichenkette.";
196 	else if ( aProgrammaticName == L"getColorValue" ) aRet = L"Gibt den Farbwert eines Zellbereichs zurueck. Bei transparentem Hintergrund wird -1 zurueckgegeben";
197 	else if ( aProgrammaticName == L"transpose" )	  aRet = L"Transponiert eine Matrix.";
198 	else if ( aProgrammaticName == L"transposeInt" )  aRet = L"Transponiert eine Matrix mit Ganzzahlen.";
199 	else if ( aProgrammaticName == L"repeatMultiple" )aRet = L"Wiederholt mehrere Bestandteile.";
200 	else if ( aProgrammaticName == L"getStrOrVal" )	  aRet = L"Gibt einen String oder einen Wert zurueck.";
201 	else if ( aProgrammaticName == L"callAsync" )	  aRet = L"Test fuer asynchrone Funktion.";
202 	return aRet;
203 }
204 
205 UString ScTestAddIn::getDisplayArgumentName(const UString& aProgrammaticFunctionName,
206 								INT32 nArgument) THROWS( (UsrSystemException) )
207 {
208 	//	return translated strings
209 
210 	UString aRet;
211 	if ( aProgrammaticFunctionName == L"countParams" )
212 	{
213 		if ( nArgument == 0 )		aRet = L"Parameter";
214 	}
215 	else if ( aProgrammaticFunctionName == L"addOne" )
216 	{
217 		if ( nArgument == 0 )		aRet = L"Wert";
218 	}
219 	else if ( aProgrammaticFunctionName == L"repeatStr" )
220 	{
221 		if ( nArgument == 0 )		aRet = L"String";
222 		else if ( nArgument == 1 )	aRet = L"Anzahl";
223 	}
224 	else if ( aProgrammaticFunctionName == L"getDateString" )
225 	{
226 		if ( nArgument == 0 )		aRet = L"Dokument";
227 		else if ( nArgument == 1 )	aRet = L"Wert";
228 	}
229 	else if ( aProgrammaticFunctionName == L"getColorValue" )
230 	{
231 		if ( nArgument == 0 )		aRet = L"Bereich";
232 	}
233 	else if ( aProgrammaticFunctionName == L"transpose" )
234 	{
235 		if ( nArgument == 0 )		aRet = L"Matrix";
236 	}
237 	else if ( aProgrammaticFunctionName == L"transposeInt" )
238 	{
239 		if ( nArgument == 0 )		aRet = L"Matrix";
240 	}
241 	else if ( aProgrammaticFunctionName == L"repeatMultiple" )
242 	{
243 		if ( nArgument == 0 )		aRet = L"Anzahl";
244 		else if ( nArgument == 1 )	aRet = L"Trenner";
245 		else if ( nArgument == 2 )	aRet = L"Inhalt";
246 	}
247 	else if ( aProgrammaticFunctionName == L"getStrOrVal" )
248 	{
249 		if ( nArgument == 0 )		aRet = L"Flag";
250 	}
251 	else if ( aProgrammaticFunctionName == L"callAsync" )
252 	{
253 		if ( nArgument == 0 )		aRet = L"Name";
254 	}
255 	return aRet;
256 }
257 
258 UString ScTestAddIn::getArgumentDescription(const UString& aProgrammaticFunctionName,
259 								INT32 nArgument) THROWS( (UsrSystemException) )
260 {
261 	//	return translated strings
262 
263 	UString aRet;
264 	if ( aProgrammaticFunctionName == L"countParams" )
265 	{
266 		if ( nArgument == 0 )		aRet = L"Beliebiger Parameter";
267 	}
268 	else if ( aProgrammaticFunctionName == L"addOne" )
269 	{
270 		if ( nArgument == 0 )		aRet = L"Der Wert, zu dem 1 addiert wird";
271 	}
272 	else if ( aProgrammaticFunctionName == L"repeatStr" )
273 	{
274 		if ( nArgument == 0 )		aRet = L"Der Text, der wiederholt wird";
275 		else if ( nArgument == 1 )	aRet = L"Die Anzahl der Wiederholungen";
276 	}
277 	else if ( aProgrammaticFunctionName == L"getDateString" )
278 	{
279 		if ( nArgument == 0 )		aRet = L"(intern)";
280 		else if ( nArgument == 1 )	aRet = L"Der Wert, der als Datum formatiert wird";
281 	}
282 	else if ( aProgrammaticFunctionName == L"getColorValue" )
283 	{
284 		if ( nArgument == 0 )		aRet = L"Der Bereich, dessen Hintergrundfarbe abgefragt wird";
285 	}
286 	else if ( aProgrammaticFunctionName == L"transpose" )
287 	{
288 		if ( nArgument == 0 )		aRet = L"Die Matrix, die transponiert werden soll";
289 	}
290 	else if ( aProgrammaticFunctionName == L"transposeInt" )
291 	{
292 		if ( nArgument == 0 )		aRet = L"Die Matrix, die transponiert werden soll";
293 	}
294 	else if ( aProgrammaticFunctionName == L"repeatMultiple" )
295 	{
296 		if ( nArgument == 0 )		aRet = L"Anzahl der Wiederholungen";
297 		else if ( nArgument == 1 )	aRet = L"Text, der zwischen den Inhalten erscheint";
298 		else if ( nArgument == 2 )	aRet = L"Mehrere Inhalte";
299 	}
300 	else if ( aProgrammaticFunctionName == L"getStrOrVal" )
301 	{
302 		if ( nArgument == 0 )		aRet = L"Wenn Flag 0 ist, wird ein Wert zurueckgegeben, sonst ein String.";
303 	}
304 	else if ( aProgrammaticFunctionName == L"callAsync" )
305 	{
306 		if ( nArgument == 0 )		aRet = L"Ein String";
307 	}
308 	return aRet;
309 }
310 
311 UString ScTestAddIn::getProgrammaticCategoryName(const UString& aProgrammaticFunctionName)
312 								THROWS( (UsrSystemException) )
313 {
314 	//	return non-translated strings
315 
316 	UString aRet;
317 	if ( aProgrammaticFunctionName == L"countParams" )		  aRet = L"Information";
318 	else if ( aProgrammaticFunctionName == L"addOne" )		  aRet = L"Mathematical";
319 	else if ( aProgrammaticFunctionName == L"repeatStr" )	  aRet = L"Text";
320 	else if ( aProgrammaticFunctionName == L"getDateString" ) aRet = L"Date&Time";
321 	else if ( aProgrammaticFunctionName == L"getColorValue" ) aRet = L"Spreadsheet";
322 	else if ( aProgrammaticFunctionName == L"transpose" )	  aRet = L"Matrix";
323 	else if ( aProgrammaticFunctionName == L"transposeInt" )  aRet = L"Matrix";
324 	else if ( aProgrammaticFunctionName == L"repeatMultiple" )aRet = L"Text";
325 	else if ( aProgrammaticFunctionName == L"getStrOrVal" )	  aRet = L"Add-In";
326 	else if ( aProgrammaticFunctionName == L"callAsync" )	  aRet = L"Realtime";		// new group
327 	return aRet;
328 }
329 
330 UString ScTestAddIn::getDisplayCategoryName(const UString& aProgrammaticFunctionName)
331 								THROWS( (UsrSystemException) )
332 {
333 	//	return translated strings
334 
335 	return L"irgendwas";	// not used for predefined categories
336 }
337 
338 // XLocalizable
339 
340 void ScTestAddIn::setLocale(const lang::Locale& eLocale) THROWS( (UsrSystemException) )
341 {
342 	aFuncLoc = eLocale;
343 //	DBG_ERROR( UStringToString(aFuncLoc.Language, CHARSET_SYSTEM) + String("-") +
344 //			   UStringToString(aFuncLoc.Country, CHARSET_SYSTEM) );
345 }
346 
347 ::com::sun::star::lang::Locale SAL_CALL ScTestAddIn::getLocale(  ) throw(::com::sun::star::uno::RuntimeException)
348 {
349 	return aFuncLoc;
350 }
351 
352 // XTestAddIn
353 
354 sal_Int32 SAL_CALL ScTestAddIn::countParams( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArgs ) throw(::com::sun::star::uno::RuntimeException)
355 {
356 	return aArgs.getLength();
357 }
358 
359 double SAL_CALL ScTestAddIn::addOne( double fValue ) throw(::com::sun::star::uno::RuntimeException)
360 {
361 	return fValue + 1.0;
362 }
363 
364 ::rtl::OUString SAL_CALL ScTestAddIn::repeatStr( const ::rtl::OUString& aStr, sal_Int32 nCount ) throw(::com::sun::star::uno::RuntimeException)
365 {
366 	String aRet;
367 	String aStrStr = OUStringToString( aStr, CHARSET_SYSTEM );
368 	for (long i=0; i<nCount; i++)
369 		aRet += aStrStr;
370 
371 	return StringToOUString( aRet, CHARSET_SYSTEM );
372 }
373 
374 ::rtl::OUString SAL_CALL ScTestAddIn::getDateString( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xCaller, double fValue ) throw(::com::sun::star::uno::RuntimeException)
375 {
376 	uno::Any aDateAny = xCaller->getPropertyValue( L"NullDate" );
377 //!	if ( aDateAny.getReflection()->equals( *Date_getReflection() ) )
378 	{
379 		util::Date aDate;
380 		aDateAny >>= aDate;
381 		//const Date* pDate = (const Date*)aDateAny.get();
382 		//if (pDate)
383 		{
384 			//Date aNewDate = *pDate;
385 			Date aNewDate( aDate.Day, aDate.Month, aDate.Year );
386 
387 			aNewDate += (long)(fValue+0.5);
388 
389 			String aRet;
390 			aRet += aNewDate.GetDay();
391 			aRet += '.';
392 			aRet += aNewDate.GetMonth();
393 			aRet += '.';
394 			aRet += aNewDate.GetYear();
395 			return StringToOUString( aRet, CHARSET_SYSTEM );
396 		}
397 	}
398 
399 	return L"**ERROR**";
400 }
401 
402 sal_Int32 SAL_CALL ScTestAddIn::getColorValue( const ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange >& xRange ) throw(::com::sun::star::uno::RuntimeException)
403 {
404 	uno::Reference<beans::XPropertySet> xProp( xRange, uno::UNO_QUERY );
405 	if (xProp.is())
406 	{
407 		long nRet = -1;
408 		uno::Any aTrans = xProp->getPropertyValue( L"IsCellBackgroundTransparent" );
409 		BOOL bIsTrans;
410 		aTrans >>= bIsTrans;		//! dont use >>= for BOOL
411 		if (!bIsTrans)
412 		{
413 			uno::Any aCol = xProp->getPropertyValue( L"CellBackColor" );
414 			//nRet = NAMESPACE_USR(OPropertyTypeConversion)::toINT32( aCol );
415 			aCol >>= nRet;
416 		}
417 		return nRet;
418 	}
419 	return 0;
420 }
421 
422 double lcl_GetDoubleElement( const uno::Sequence< uno::Sequence<double> >& aMatrix, long nCol, long nRow )
423 {
424 	if ( nRow < aMatrix.getLength() )
425 	{
426 		const uno::Sequence<double>& rRowSeq = aMatrix.getConstArray()[nRow];
427 		if ( nCol < rRowSeq.getLength() )
428 			return rRowSeq.getConstArray()[nCol];
429 	}
430 	return 0.0;		// error
431 }
432 
433 INT32 lcl_GetLongElement( const uno::Sequence< uno::Sequence<INT32> >& aMatrix, long nCol, long nRow )
434 {
435 	if ( nRow < aMatrix.getLength() )
436 	{
437 		const uno::Sequence<INT32>& rRowSeq = aMatrix.getConstArray()[nRow];
438 		if ( nCol < rRowSeq.getLength() )
439 			return rRowSeq.getConstArray()[nCol];
440 	}
441 	return 0.0;		// error
442 }
443 
444 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< double > > SAL_CALL ScTestAddIn::transpose( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< double > >& aMatrix ) throw(::com::sun::star::uno::RuntimeException)
445 {
446 	long nRowCount = aMatrix.getLength();
447 	long nColCount = 0;
448 	if ( nRowCount )
449 		nColCount = aMatrix.getConstArray()[0].getLength();
450 
451 	uno::Sequence< uno::Sequence<double> > aRet( nColCount );
452 	for (long nCol=0; nCol<nColCount; nCol++)
453 	{
454 		uno::Sequence<double> aSubSeq(nRowCount);
455 		for (long nRow=0; nRow<nRowCount; nRow++)
456 			aSubSeq.getArray()[nRow] = lcl_GetDoubleElement( aMatrix, nCol, nRow );
457 
458 		aRet.getArray()[nCol] = aSubSeq;
459 	}
460 
461 	return aRet;
462 }
463 
464 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< sal_Int32 > > SAL_CALL ScTestAddIn::transposeInt( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< sal_Int32 > >& aMatrix ) throw(::com::sun::star::uno::RuntimeException)
465 {
466 	long nRowCount = aMatrix.getLength();
467 	long nColCount = 0;
468 	if ( nRowCount )
469 		nColCount = aMatrix.getConstArray()[0].getLength();
470 
471 	uno::Sequence< uno::Sequence<INT32> > aRet( nColCount );
472 	for (long nCol=0; nCol<nColCount; nCol++)
473 	{
474 		uno::Sequence<INT32> aSubSeq(nRowCount);
475 		for (long nRow=0; nRow<nRowCount; nRow++)
476 			aSubSeq.getArray()[nRow] = lcl_GetLongElement( aMatrix, nCol, nRow );
477 
478 		aRet.getArray()[nCol] = aSubSeq;
479 	}
480 
481 	return aRet;
482 }
483 
484 ::rtl::OUString SAL_CALL ScTestAddIn::repeatMultiple( sal_Int32 nCount, const ::com::sun::star::uno::Any& aFirst, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aFollow ) throw(::com::sun::star::uno::RuntimeException)
485 {
486 	String aSeparator;
487 	if ( !aFirst.hasValue() )	// not specified
488 		aSeparator = ';';
489 	else
490 	{
491 		rtl::OUString aUStr;
492 		aFirst >>= aUStr;
493 		aSeparator = OUStringToString( aUStr, CHARSET_SYSTEM );
494 	}
495 
496 	String aContent;
497 	long nContCount = aFollow.getLength();
498 	const uno::Any* pArr = aFollow.getConstArray();
499 	for (long nPos=0; nPos<nContCount; nPos++)
500 	{
501 		if ( nPos > 0 )
502 			aContent += ' ';
503 		rtl::OUString aUStr;
504 		pArr[nPos] >>= aUStr;
505 		aContent += OUStringToString( aUStr, CHARSET_SYSTEM );
506 	}
507 
508 	String aRet;
509 
510 	for (long i=0; i<nCount; i++)
511 	{
512 		if (i>0)
513 			aRet += aSeparator;
514 		aRet += aContent;
515 	}
516 
517 	return StringToOUString(aRet, CHARSET_SYSTEM);
518 }
519 
520 ::com::sun::star::uno::Any SAL_CALL ScTestAddIn::getStrOrVal( sal_Int32 nFlag ) throw(::com::sun::star::uno::RuntimeException)
521 {
522 	uno::Any aRet;
523 
524 	//! Test
525 	if ( nFlag == 42 )
526 	{
527 		uno::Sequence<rtl::OUString> aInner(3);
528 		aInner.getArray()[0] = L"Bla";
529 		aInner.getArray()[1] = L"Fasel";
530 		aInner.getArray()[2] = L"Suelz";
531 		uno::Sequence< uno::Sequence<rtl::OUString> > aOuter( &aInner, 1 );
532 
533 		//return uno::Any( &aOuter, Sequence< Sequence<UString> >::getReflection() );
534 
535 		aRet <<= aOuter;
536 		return aRet;
537 	}
538 	//! Test
539 
540 	if ( nFlag )
541 		aRet <<= UString(L"This is a string.");
542 	else
543 		aRet <<= (INT32)42;
544 
545 	return aRet;
546 }
547 
548 ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XVolatileResult > SAL_CALL ScTestAddIn::callAsync( const ::rtl::OUString& aString ) throw(::com::sun::star::uno::RuntimeException)
549 {
550 	String aStr = OUStringToString( aString, CHARSET_SYSTEM );
551 	char c = (char) aStr;
552 	if ( c >= '0' && c <= '9' )
553 	{
554 		if (!xNumResult.is())
555 			xNumResult = new ScAddInResult( "Num" );
556 		return xNumResult;
557 	}
558 	else
559 	{
560 		if (!xAlphaResult.is())
561 			xAlphaResult = new ScAddInResult( "Str" );
562 		return xAlphaResult;
563 	}
564 }
565 
566 
567 // XServiceName
568 
569 ::rtl::OUString SAL_CALL ScTestAddIn::getServiceName(  ) throw(::com::sun::star::uno::RuntimeException)
570 {
571 	return SCTESTADDIN_SERVICE;		// name of specific AddIn service
572 }
573 
574 // XServiceInfo
575 
576 ::rtl::OUString SAL_CALL ScTestAddIn::getImplementationName(  ) throw(::com::sun::star::uno::RuntimeException)
577 {
578 	return getImplementationName_Static();
579 }
580 
581 sal_Bool SAL_CALL ScTestAddIn::supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException)
582 {
583 	return ServiceName == SCADDIN_SERVICE ||
584 			ServiceName == SCTESTADDIN_SERVICE;
585 }
586 
587 ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL ScTestAddIn::getSupportedServiceNames(  ) throw(::com::sun::star::uno::RuntimeException)
588 {
589 	return getSupportedServiceNames_Static();
590 }
591 
592 //------------------------------------------------------------------------
593 
594 
595 
596