xref: /trunk/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