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