xref: /AOO41X/main/sc/source/core/tool/callform.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 
32 
33 // INCLUDE ---------------------------------------------------------------
34 #include <vcl/svapp.hxx>
35 #include <osl/module.hxx>
36 #include <osl/file.hxx>
37 #include <unotools/transliterationwrapper.hxx>
38 
39 #include "callform.hxx"
40 #include "global.hxx"
41 #include "adiasync.hxx"
42 
43 //------------------------------------------------------------------------
44 
45 extern "C" {
46 
47 typedef void (CALLTYPE* ExFuncPtr1)(void*);
48 typedef void (CALLTYPE* ExFuncPtr2)(void*, void*);
49 typedef void (CALLTYPE* ExFuncPtr3)(void*, void*, void*);
50 typedef void (CALLTYPE* ExFuncPtr4)(void*, void*, void*, void*);
51 typedef void (CALLTYPE* ExFuncPtr5)(void*, void*, void*, void*, void*);
52 typedef void (CALLTYPE* ExFuncPtr6)(void*, void*, void*, void*, void*, void*);
53 typedef void (CALLTYPE* ExFuncPtr7)(void*, void*, void*, void*, void*, void*, void*);
54 typedef void (CALLTYPE* ExFuncPtr8)(void*, void*, void*, void*, void*, void*, void*, void*);
55 typedef void (CALLTYPE* ExFuncPtr9)(void*, void*, void*, void*, void*, void*, void*, void*, void*);
56 typedef void (CALLTYPE* ExFuncPtr10)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
57 typedef void (CALLTYPE* ExFuncPtr11)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
58 typedef void (CALLTYPE* ExFuncPtr12)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
59 typedef void (CALLTYPE* ExFuncPtr13)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
60 typedef void (CALLTYPE* ExFuncPtr14)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
61 typedef void (CALLTYPE* ExFuncPtr15)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
62 typedef void (CALLTYPE* ExFuncPtr16)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
63 
64 typedef void (CALLTYPE* GetFuncCountPtr)(sal_uInt16& nCount);
65 typedef void (CALLTYPE* GetFuncDataPtr)
66 	(sal_uInt16& nNo, sal_Char* pFuncName, sal_uInt16& nParamCount, ParamType* peType, sal_Char* pInternalName);
67 
68 typedef void (CALLTYPE* SetLanguagePtr)( sal_uInt16& nLanguage );
69 typedef void (CALLTYPE* GetParamDesc)
70 	(sal_uInt16& nNo, sal_uInt16& nParam, sal_Char* pName, sal_Char* pDesc );
71 
72 typedef void (CALLTYPE* IsAsync) ( sal_uInt16&		nNo,
73 								   ParamType*	peType );
74 typedef void (CALLTYPE* Advice)  ( sal_uInt16&		nNo,
75 								   AdvData&		pfCallback );
76 typedef void (CALLTYPE* Unadvice)( double&		nHandle );
77 
78 typedef void (CALLTYPE* FARPROC) ( void );
79 
80 }
81 
82 #if defined(OS2) && defined(BLC)
83 #define GETFUNCTIONCOUNT		"_GetFunctionCount"
84 #define GETFUNCTIONDATA			"_GetFunctionData"
85 #define SETLANGUAGE				"_SetLanguage"
86 #define GETPARAMDESC			"_GetParameterDescription"
87 #define ISASYNC					"_IsAsync"
88 #define ADVICE					"_Advice"
89 #define UNADVICE				"_Unadvice"
90 #else // Pascal oder extern "C"
91 #define GETFUNCTIONCOUNT		"GetFunctionCount"
92 #define GETFUNCTIONDATA			"GetFunctionData"
93 #define SETLANGUAGE				"SetLanguage"
94 #define GETPARAMDESC			"GetParameterDescription"
95 #define ISASYNC					"IsAsync"
96 #define ADVICE					"Advice"
97 #define UNADVICE				"Unadvice"
98 #endif
99 
100 #define LIBFUNCNAME( name ) \
101 	(String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( name ) ))
102 
103 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
104 
105 FuncData::FuncData(const String& rIName) :
106 	pModuleData		(NULL),
107 	aInternalName   (rIName),
108 //  aFuncName		(""),
109 	nNumber			(0),
110 	nParamCount		(0),
111 	eAsyncType		(NONE)
112 {
113 	for (sal_uInt16 i = 0; i < MAXFUNCPARAM; i++)
114 		eParamType[i] = PTR_DOUBLE;
115 }
116 
117 //------------------------------------------------------------------------
118 
119 FuncData::FuncData(const ModuleData*pModule,
120 				   const String&	rIName,
121 				   const String&	rFName,
122 						 sal_uInt16	nNo,
123 					sal_uInt16	nCount,
124 				   const ParamType* peType,
125 					ParamType  eType) :
126 	pModuleData		(pModule),
127 	aInternalName   (rIName),
128 	aFuncName		(rFName),
129 	nNumber			(nNo),
130 	nParamCount		(nCount),
131 	eAsyncType		(eType)
132 {
133 	for (sal_uInt16 i = 0; i < MAXFUNCPARAM; i++)
134 		eParamType[i] = peType[i];
135 }
136 
137 //------------------------------------------------------------------------
138 
139 FuncData::FuncData(const FuncData& rData) :
140     ScDataObject(),
141 	pModuleData		(rData.pModuleData),
142 	aInternalName   (rData.aInternalName),
143 	aFuncName		(rData.aFuncName),
144 	nNumber			(rData.nNumber),
145 	nParamCount		(rData.nParamCount),
146 	eAsyncType		(rData.eAsyncType)
147 {
148 	for (sal_uInt16 i = 0; i < MAXFUNCPARAM; i++)
149 		eParamType[i] = rData.eParamType[i];
150 }
151 
152 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
153 
154 short FuncCollection::Compare(ScDataObject* pKey1, ScDataObject* pKey2) const
155 {
156     return (short) ScGlobal::GetpTransliteration()->compareString(
157 		((FuncData*)pKey1)->aInternalName, ((FuncData*)pKey2)->aInternalName );
158 }
159 
160 //------------------------------------------------------------------------
161 
162 sal_Bool FuncCollection::SearchFunc( const String& rName, sal_uInt16& rIndex ) const
163 {
164 	FuncData aDataObj(rName);
165 	return Search( &aDataObj, rIndex );
166 }
167 
168 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
169 class ModuleData : public ScDataObject
170 {
171 friend class ModuleCollection;
172 	String		aName;
173     osl::Module* pInstance;
174 public:
175     ModuleData(const String& rStr, osl::Module* pInst) : aName (rStr), pInstance (pInst) {}
176     ModuleData(const ModuleData& rData) : ScDataObject(), aName (rData.aName) {pInstance = new osl::Module(aName);}
177 	~ModuleData() { delete pInstance; }
178 	virtual ScDataObject*	Clone() const { return new ModuleData(*this); }
179 
180 	const   String&			GetName() const { return aName; }
181             osl::Module*    GetInstance() const { return pInstance; }
182 			void			FreeInstance() { delete pInstance; pInstance = 0; }
183 };
184 
185 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
186 class ModuleCollection : public ScSortedCollection
187 {
188 public:
189 	ModuleCollection(sal_uInt16 nLim = 4, sal_uInt16 nDel = 4, sal_Bool bDup = sal_False) : ScSortedCollection ( nLim, nDel, bDup ) {}
190 	ModuleCollection(const ModuleCollection& rModuleCollection) : ScSortedCollection ( rModuleCollection ) {}
191 
192 	virtual ScDataObject*		Clone() const { return new ModuleCollection(*this); }
193 			ModuleData*		operator[]( const sal_uInt16 nIndex) const {return (ModuleData*)At(nIndex);}
194 	virtual short			Compare(ScDataObject* pKey1, ScDataObject* pKey2) const;
195 			sal_Bool			SearchModule( const String& rName,
196 										  const ModuleData*& rpModule ) const;
197 };
198 
199 static ModuleCollection aModuleCollection;
200 
201 //------------------------------------------------------------------------
202 
203 short ModuleCollection::Compare(ScDataObject* pKey1, ScDataObject* pKey2) const
204 {
205     return (short) ScGlobal::GetpTransliteration()->compareString(
206 		((ModuleData*)pKey1)->aName, ((ModuleData*)pKey2)->aName );
207 }
208 
209 //------------------------------------------------------------------------
210 
211 sal_Bool ModuleCollection::SearchModule( const String& rName,
212 									 const ModuleData*& rpModule ) const
213 {
214 	sal_uInt16 nIndex;
215 	ModuleData aSearchModule(rName, 0);
216 	sal_Bool bFound = Search( &aSearchModule, nIndex );
217 	if (bFound)
218 		rpModule = (ModuleData*)At(nIndex);
219 	else
220 		rpModule = 0;
221 	return bFound;
222 }
223 
224 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
225 
226 sal_Bool InitExternalFunc(const rtl::OUString& rModuleName)
227 {
228 	String aModuleName( rModuleName );
229 
230 	// Module schon geladen?
231 	const ModuleData* pTemp;
232 	if (aModuleCollection.SearchModule(aModuleName, pTemp))
233 		return sal_False;
234 
235 	rtl::OUString aNP;
236 	aNP = rModuleName;
237 
238 	sal_Bool bRet = sal_False;
239     osl::Module* pLib = new osl::Module( aNP );
240     if (pLib->is())
241 	{
242         FARPROC fpGetCount = (FARPROC)pLib->getFunctionSymbol(LIBFUNCNAME(GETFUNCTIONCOUNT));
243         FARPROC fpGetData = (FARPROC)pLib->getFunctionSymbol(LIBFUNCNAME(GETFUNCTIONDATA));
244 		if ((fpGetCount != NULL) && (fpGetData != NULL))
245 		{
246             FARPROC fpIsAsync = (FARPROC)pLib->getFunctionSymbol(LIBFUNCNAME(ISASYNC));
247             FARPROC fpAdvice = (FARPROC)pLib->getFunctionSymbol(LIBFUNCNAME(ADVICE));
248             FARPROC fpSetLanguage = (FARPROC)pLib->getFunctionSymbol(LIBFUNCNAME(SETLANGUAGE));
249 			if ( fpSetLanguage )
250 			{
251                 LanguageType eLanguage = Application::GetSettings().GetUILanguage();
252 				sal_uInt16 nLanguage = (sal_uInt16) eLanguage;
253 				(*((SetLanguagePtr)fpSetLanguage))( nLanguage );
254 			}
255 
256 			// Module in die Collection aufnehmen
257 			ModuleData* pModuleData = new ModuleData(aModuleName, pLib);
258 			aModuleCollection.Insert(pModuleData);
259 
260 			// Schnittstelle initialisieren
261 			AdvData pfCallBack = &ScAddInAsyncCallBack;
262 			FuncData* pFuncData;
263 			FuncCollection* pFuncCol = ScGlobal::GetFuncCollection();
264 			sal_uInt16 nCount;
265 			(*((GetFuncCountPtr)fpGetCount))(nCount);
266 			for (sal_uInt16 i=0; i < nCount; i++)
267 			{
268 				sal_Char cFuncName[256];
269 				sal_Char cInternalName[256];
270 				sal_uInt16 nParamCount;
271 				ParamType eParamType[MAXFUNCPARAM];
272 				ParamType eAsyncType = NONE;
273 				// #62113# alles initialisieren, falls das AddIn sich schlecht verhaelt
274 				cFuncName[0] = 0;
275 				cInternalName[0] = 0;
276 				nParamCount = 0;
277 				for ( sal_uInt16 j=0; j<MAXFUNCPARAM; j++ )
278 				{
279 					eParamType[j] = NONE;
280 				}
281 				(*((GetFuncDataPtr)fpGetData))(i, cFuncName, nParamCount,
282 											   eParamType, cInternalName);
283 				if( fpIsAsync )
284 				{
285 					(*((IsAsync)fpIsAsync))(i, &eAsyncType);
286 					if ( fpAdvice && eAsyncType != NONE )
287 						(*((Advice)fpAdvice))( i, pfCallBack );
288 				}
289 				String aInternalName( cInternalName, osl_getThreadTextEncoding() );
290 				String aFuncName( cFuncName, osl_getThreadTextEncoding() );
291 				pFuncData = new FuncData( pModuleData,
292 										  aInternalName,
293 										  aFuncName,
294 										  i,
295 										  nParamCount,
296 										  eParamType,
297 										  eAsyncType );
298 				pFuncCol->Insert(pFuncData);
299 			}
300 			bRet = sal_True;
301 		}
302 		else
303 			delete pLib;
304 	}
305 	else
306 		delete pLib;
307 	return bRet;
308 }
309 
310 //------------------------------------------------------------------------
311 
312 void ExitExternalFunc()
313 {
314 	sal_uInt16 nCount = aModuleCollection.GetCount();
315 	for (sal_uInt16 i=0; i<nCount; i++)
316 	{
317 		ModuleData* pData = aModuleCollection[i];
318 		pData->FreeInstance();
319 	}
320 }
321 
322 //------------------------------------------------------------------------
323 
324 sal_Bool FuncData::Call(void** ppParam)
325 {
326 	sal_Bool bRet = sal_False;
327     osl::Module* pLib = pModuleData->GetInstance();
328     FARPROC fProc = (FARPROC)pLib->getFunctionSymbol(aFuncName);
329 	if (fProc != NULL)
330 	{
331 		switch (nParamCount)
332 		{
333 			case 1 :
334 				(*((ExFuncPtr1)fProc))(ppParam[0]);
335 				bRet = sal_True;
336 				break;
337 			case 2 :
338 				(*((ExFuncPtr2)fProc))(ppParam[0], ppParam[1]);
339 				bRet = sal_True;
340 				break;
341 			case 3 :
342 				(*((ExFuncPtr3)fProc))(ppParam[0], ppParam[1], ppParam[2]);
343 				bRet = sal_True;
344 				break;
345 			case 4 :
346 				(*((ExFuncPtr4)fProc))(ppParam[0], ppParam[1], ppParam[2], ppParam[3]);
347 				bRet = sal_True;
348 				break;
349 			case 5 :
350 				(*((ExFuncPtr5)fProc))(ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4]);
351 				bRet = sal_True;
352 				break;
353 			case 6 :
354 				(*((ExFuncPtr6)fProc))(ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5]);
355 				bRet = sal_True;
356 				break;
357 			case 7 :
358 				(*((ExFuncPtr7)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
359 										ppParam[6]);
360 				bRet = sal_True;
361 				break;
362 			case 8 :
363 				(*((ExFuncPtr8)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
364 										ppParam[6], ppParam[7]);
365 				bRet = sal_True;
366 				break;
367 			case 9 :
368 				(*((ExFuncPtr9)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
369 										ppParam[6], ppParam[7], ppParam[8]);
370 				bRet = sal_True;
371 				break;
372 			case 10 :
373 				(*((ExFuncPtr10)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
374 										ppParam[6], ppParam[7], ppParam[8], ppParam[9]);
375 				bRet = sal_True;
376 				break;
377 			case 11 :
378 				(*((ExFuncPtr11)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
379 										ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10]);
380 				bRet = sal_True;
381 				break;
382 			case 12:
383 				(*((ExFuncPtr12)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
384 										ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11]);
385 				bRet = sal_True;
386 				break;
387 			case 13:
388 				(*((ExFuncPtr13)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
389 										ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11],
390 										ppParam[12]);
391 				bRet = sal_True;
392 				break;
393 			case 14 :
394 				(*((ExFuncPtr14)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
395 										ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11],
396 										ppParam[12], ppParam[13]);
397 				bRet = sal_True;
398 				break;
399 			case 15 :
400 				(*((ExFuncPtr15)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
401 										ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11],
402 										ppParam[12], ppParam[13], ppParam[14]);
403 				bRet = sal_True;
404 				break;
405 			case 16 :
406 				(*((ExFuncPtr16)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
407 										ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11],
408 										ppParam[12], ppParam[13], ppParam[14], ppParam[15]);
409 				bRet = sal_True;
410 				break;
411 			default : break;
412 		}
413 	}
414 	return bRet;
415 }
416 
417 //------------------------------------------------------------------------
418 
419 sal_Bool FuncData::Unadvice( double nHandle )
420 {
421 	sal_Bool bRet = sal_False;
422     osl::Module* pLib = pModuleData->GetInstance();
423     FARPROC fProc = (FARPROC)pLib->getFunctionSymbol(LIBFUNCNAME(UNADVICE));
424 	if (fProc != NULL)
425 	{
426 		((::Unadvice)fProc)(nHandle);
427 		bRet = sal_True;
428 	}
429 	return bRet;
430 }
431 
432 //------------------------------------------------------------------------
433 
434 const String& FuncData::GetModuleName() const
435 {
436 	// DBG_ASSERT( pModuleData, "Keine Arme, keine Kekse" ):
437 	return pModuleData->GetName();
438 }
439 
440 //------------------------------------------------------------------------
441 
442 sal_Bool FuncData::GetParamDesc( String& aName, String& aDesc, sal_uInt16 nParam )
443 {
444 	sal_Bool bRet = sal_False;
445 	if ( nParam <= nParamCount )
446 	{
447         osl::Module* pLib = pModuleData->GetInstance();
448         FARPROC fProc = (FARPROC) pLib->getFunctionSymbol( LIBFUNCNAME(GETPARAMDESC) );
449 		if ( fProc != NULL )
450 		{
451 			sal_Char pcName[256];
452 			sal_Char pcDesc[256];
453 			*pcName = *pcDesc = 0;
454 			sal_uInt16 nFuncNo = nNumber;	// nicht per Reference versauen lassen..
455 			((::GetParamDesc)fProc)( nFuncNo, nParam, pcName, pcDesc );
456 			aName = String( pcName, osl_getThreadTextEncoding() );
457 			aDesc = String( pcDesc, osl_getThreadTextEncoding() );
458 			bRet = sal_True;
459 		}
460 	}
461 	if ( !bRet )
462 	{
463 		aName.Erase();
464 		aDesc.Erase();
465 	}
466 	return bRet;
467 }
468 
469 
470