xref: /AOO41X/main/sc/source/core/tool/addincol.cxx (revision b3f79822e811ac3493b185030a72c3c5a51f32d8)
1*b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*b3f79822SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*b3f79822SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*b3f79822SAndrew Rist  * distributed with this work for additional information
6*b3f79822SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*b3f79822SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*b3f79822SAndrew Rist  * "License"); you may not use this file except in compliance
9*b3f79822SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*b3f79822SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*b3f79822SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*b3f79822SAndrew Rist  * software distributed under the License is distributed on an
15*b3f79822SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b3f79822SAndrew Rist  * KIND, either express or implied.  See the License for the
17*b3f79822SAndrew Rist  * specific language governing permissions and limitations
18*b3f79822SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*b3f79822SAndrew Rist  *************************************************************/
21*b3f79822SAndrew Rist 
22*b3f79822SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sc.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir 
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
30cdf0e10cSrcweir #include <tools/debug.hxx>
31cdf0e10cSrcweir #include <i18npool/mslangid.hxx>
32cdf0e10cSrcweir #include <vcl/svapp.hxx>
33cdf0e10cSrcweir #include <vos/xception.hxx>
34cdf0e10cSrcweir #include <sfx2/objsh.hxx>
35cdf0e10cSrcweir #include <unotools/charclass.hxx>
36cdf0e10cSrcweir 
37cdf0e10cSrcweir #include <com/sun/star/container/XContentEnumerationAccess.hpp>
38cdf0e10cSrcweir #include <com/sun/star/lang/XServiceName.hpp>
39cdf0e10cSrcweir #include <com/sun/star/lang/XSingleServiceFactory.hpp>
40cdf0e10cSrcweir #include <com/sun/star/lang/XSingleComponentFactory.hpp>
41cdf0e10cSrcweir #include <com/sun/star/reflection/XIdlClass.hpp>
42cdf0e10cSrcweir #include <com/sun/star/reflection/XIdlClassProvider.hpp>
43cdf0e10cSrcweir #include <com/sun/star/beans/XIntrospectionAccess.hpp>
44cdf0e10cSrcweir #include <com/sun/star/beans/XIntrospection.hpp>
45cdf0e10cSrcweir #include <com/sun/star/beans/MethodConcept.hpp>
46cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
47cdf0e10cSrcweir #include <com/sun/star/table/XCellRange.hpp>
48cdf0e10cSrcweir #include <com/sun/star/lang/Locale.hpp>
49cdf0e10cSrcweir #include <com/sun/star/sheet/XCompatibilityNames.hpp>
50cdf0e10cSrcweir #include <com/sun/star/sheet/NoConvergenceException.hpp>
51cdf0e10cSrcweir 
52cdf0e10cSrcweir #include "addincol.hxx"
53cdf0e10cSrcweir #include "addinhelpid.hxx"
54cdf0e10cSrcweir #include "compiler.hxx"
55cdf0e10cSrcweir #include "scmatrix.hxx"
56cdf0e10cSrcweir #include "addinlis.hxx"
57cdf0e10cSrcweir #include "formula/errorcodes.hxx"
58cdf0e10cSrcweir #include "scfuncs.hrc"
59cdf0e10cSrcweir #include "optutil.hxx"
60cdf0e10cSrcweir #include "addincfg.hxx"
61cdf0e10cSrcweir #include "scmod.hxx"
62cdf0e10cSrcweir #include "rangeseq.hxx"
63cdf0e10cSrcweir #include "funcdesc.hxx"
64cdf0e10cSrcweir 
65cdf0e10cSrcweir using namespace com::sun::star;
66cdf0e10cSrcweir 
67cdf0e10cSrcweir //------------------------------------------------------------------------
68cdf0e10cSrcweir 
69cdf0e10cSrcweir #define SC_CALLERPOS_NONE   (-1)
70cdf0e10cSrcweir 
71cdf0e10cSrcweir #define SCADDINSUPPLIER_SERVICE "com.sun.star.sheet.AddIn"
72cdf0e10cSrcweir 
73cdf0e10cSrcweir //------------------------------------------------------------------------
74cdf0e10cSrcweir 
75cdf0e10cSrcweir 
76cdf0e10cSrcweir 
77cdf0e10cSrcweir 
78cdf0e10cSrcweir //------------------------------------------------------------------------
79cdf0e10cSrcweir 
ScUnoAddInFuncData(const String & rNam,const String & rLoc,const String & rDesc,sal_uInt16 nCat,const rtl::OString & sHelp,const uno::Reference<reflection::XIdlMethod> & rFunc,const uno::Any & rO,long nAC,const ScAddInArgDesc * pAD,long nCP)80cdf0e10cSrcweir ScUnoAddInFuncData::ScUnoAddInFuncData( const String& rNam, const String& rLoc,
81cdf0e10cSrcweir                                         const String& rDesc,
82cdf0e10cSrcweir                                         sal_uInt16 nCat, const rtl::OString& sHelp,
83cdf0e10cSrcweir                                         const uno::Reference<reflection::XIdlMethod>& rFunc,
84cdf0e10cSrcweir                                         const uno::Any& rO,
85cdf0e10cSrcweir                                         long nAC, const ScAddInArgDesc* pAD,
86cdf0e10cSrcweir                                         long nCP ) :
87cdf0e10cSrcweir     aOriginalName( rNam ),
88cdf0e10cSrcweir     aLocalName( rLoc ),
89cdf0e10cSrcweir     aUpperName( rNam ),
90cdf0e10cSrcweir     aUpperLocal( rLoc ),
91cdf0e10cSrcweir     aDescription( rDesc ),
92cdf0e10cSrcweir     xFunction( rFunc ),
93cdf0e10cSrcweir     aObject( rO ),
94cdf0e10cSrcweir     nArgCount( nAC ),
95cdf0e10cSrcweir     nCallerPos( nCP ),
96cdf0e10cSrcweir     nCategory( nCat ),
97cdf0e10cSrcweir     sHelpId( sHelp ),
98cdf0e10cSrcweir     bCompInitialized( sal_False )
99cdf0e10cSrcweir {
100cdf0e10cSrcweir     if ( nArgCount )
101cdf0e10cSrcweir     {
102cdf0e10cSrcweir         pArgDescs = new ScAddInArgDesc[nArgCount];
103cdf0e10cSrcweir         for (long i=0; i<nArgCount; i++)
104cdf0e10cSrcweir             pArgDescs[i] = pAD[i];
105cdf0e10cSrcweir     }
106cdf0e10cSrcweir     else
107cdf0e10cSrcweir         pArgDescs = NULL;
108cdf0e10cSrcweir 
109cdf0e10cSrcweir     ScGlobal::pCharClass->toUpper(aUpperName);
110cdf0e10cSrcweir     ScGlobal::pCharClass->toUpper(aUpperLocal);
111cdf0e10cSrcweir }
112cdf0e10cSrcweir 
~ScUnoAddInFuncData()113cdf0e10cSrcweir ScUnoAddInFuncData::~ScUnoAddInFuncData()
114cdf0e10cSrcweir {
115cdf0e10cSrcweir     delete[] pArgDescs;
116cdf0e10cSrcweir }
117cdf0e10cSrcweir 
GetCompNames() const118cdf0e10cSrcweir const uno::Sequence<sheet::LocalizedName>& ScUnoAddInFuncData::GetCompNames() const
119cdf0e10cSrcweir {
120cdf0e10cSrcweir     if ( !bCompInitialized )
121cdf0e10cSrcweir     {
122cdf0e10cSrcweir         //  read sequence of compatibility names on demand
123cdf0e10cSrcweir 
124cdf0e10cSrcweir         uno::Reference<sheet::XAddIn> xAddIn;
125cdf0e10cSrcweir         if ( aObject >>= xAddIn )
126cdf0e10cSrcweir         {
127cdf0e10cSrcweir             uno::Reference<sheet::XCompatibilityNames> xComp( xAddIn, uno::UNO_QUERY );
128cdf0e10cSrcweir             if ( xComp.is() && xFunction.is() )
129cdf0e10cSrcweir             {
130cdf0e10cSrcweir                 rtl::OUString aMethodName = xFunction->getName();
131cdf0e10cSrcweir                 aCompNames = xComp->getCompatibilityNames( aMethodName );
132cdf0e10cSrcweir 
133cdf0e10cSrcweir                 //  change all locale entries to default case
134cdf0e10cSrcweir                 //  (language in lower case, country in upper case)
135cdf0e10cSrcweir                 //  for easier searching
136cdf0e10cSrcweir 
137cdf0e10cSrcweir                 long nSeqLen = aCompNames.getLength();
138cdf0e10cSrcweir                 if ( nSeqLen )
139cdf0e10cSrcweir                 {
140cdf0e10cSrcweir                     sheet::LocalizedName* pArray = aCompNames.getArray();
141cdf0e10cSrcweir                     for (long i=0; i<nSeqLen; i++)
142cdf0e10cSrcweir                     {
143cdf0e10cSrcweir                         lang::Locale& rLocale = pArray[i].Locale;
144cdf0e10cSrcweir                         rLocale.Language = rLocale.Language.toAsciiLowerCase();
145cdf0e10cSrcweir                         rLocale.Country  = rLocale.Country.toAsciiUpperCase();
146cdf0e10cSrcweir                     }
147cdf0e10cSrcweir                 }
148cdf0e10cSrcweir             }
149cdf0e10cSrcweir         }
150cdf0e10cSrcweir 
151cdf0e10cSrcweir         bCompInitialized = sal_True;        // also if not successful
152cdf0e10cSrcweir     }
153cdf0e10cSrcweir     return aCompNames;
154cdf0e10cSrcweir }
155cdf0e10cSrcweir 
SetCompNames(const uno::Sequence<sheet::LocalizedName> & rNew)156cdf0e10cSrcweir void ScUnoAddInFuncData::SetCompNames( const uno::Sequence< sheet::LocalizedName>& rNew )
157cdf0e10cSrcweir {
158cdf0e10cSrcweir     DBG_ASSERT( !bCompInitialized, "SetCompNames after initializing" );
159cdf0e10cSrcweir 
160cdf0e10cSrcweir     aCompNames = rNew;
161cdf0e10cSrcweir 
162cdf0e10cSrcweir     //  change all locale entries to default case
163cdf0e10cSrcweir     //  (language in lower case, country in upper case)
164cdf0e10cSrcweir     //  for easier searching
165cdf0e10cSrcweir 
166cdf0e10cSrcweir     long nSeqLen = aCompNames.getLength();
167cdf0e10cSrcweir     if ( nSeqLen )
168cdf0e10cSrcweir     {
169cdf0e10cSrcweir         sheet::LocalizedName* pArray = aCompNames.getArray();
170cdf0e10cSrcweir         for (long i=0; i<nSeqLen; i++)
171cdf0e10cSrcweir         {
172cdf0e10cSrcweir             lang::Locale& rLocale = pArray[i].Locale;
173cdf0e10cSrcweir             rLocale.Language = rLocale.Language.toAsciiLowerCase();
174cdf0e10cSrcweir             rLocale.Country  = rLocale.Country.toAsciiUpperCase();
175cdf0e10cSrcweir         }
176cdf0e10cSrcweir     }
177cdf0e10cSrcweir 
178cdf0e10cSrcweir     bCompInitialized = sal_True;
179cdf0e10cSrcweir }
180cdf0e10cSrcweir 
GetExcelName(LanguageType eDestLang,String & rRetExcelName) const181cdf0e10cSrcweir sal_Bool ScUnoAddInFuncData::GetExcelName( LanguageType eDestLang, String& rRetExcelName ) const
182cdf0e10cSrcweir {
183cdf0e10cSrcweir     const uno::Sequence<sheet::LocalizedName>& rSequence = GetCompNames();
184cdf0e10cSrcweir     long nSeqLen = rSequence.getLength();
185cdf0e10cSrcweir     if ( nSeqLen )
186cdf0e10cSrcweir     {
187cdf0e10cSrcweir         const sheet::LocalizedName* pArray = rSequence.getConstArray();
188cdf0e10cSrcweir         long i;
189cdf0e10cSrcweir 
190cdf0e10cSrcweir         rtl::OUString aLangStr, aCountryStr;
191cdf0e10cSrcweir         MsLangId::convertLanguageToIsoNames( eDestLang, aLangStr, aCountryStr );
192cdf0e10cSrcweir         rtl::OUString aUserLang = aLangStr.toAsciiLowerCase();
193cdf0e10cSrcweir         rtl::OUString aUserCountry = aCountryStr.toAsciiUpperCase();
194cdf0e10cSrcweir 
195cdf0e10cSrcweir         //  first check for match of both language and country
196cdf0e10cSrcweir 
197cdf0e10cSrcweir         for ( i=0; i<nSeqLen; i++)
198cdf0e10cSrcweir             if ( pArray[i].Locale.Language == aUserLang &&
199cdf0e10cSrcweir                     pArray[i].Locale.Country  == aUserCountry )
200cdf0e10cSrcweir             {
201cdf0e10cSrcweir                 rRetExcelName = pArray[i].Name;
202cdf0e10cSrcweir                 return sal_True;
203cdf0e10cSrcweir             }
204cdf0e10cSrcweir 
205cdf0e10cSrcweir         //  second: check only language
206cdf0e10cSrcweir 
207cdf0e10cSrcweir         for ( i=0; i<nSeqLen; i++)
208cdf0e10cSrcweir             if ( pArray[i].Locale.Language == aUserLang )
209cdf0e10cSrcweir             {
210cdf0e10cSrcweir                 rRetExcelName = pArray[i].Name;
211cdf0e10cSrcweir                 return sal_True;
212cdf0e10cSrcweir             }
213cdf0e10cSrcweir 
214cdf0e10cSrcweir         // third: #i57772# fall-back to en-US
215cdf0e10cSrcweir 
216cdf0e10cSrcweir         if ( eDestLang != LANGUAGE_ENGLISH_US )
217cdf0e10cSrcweir             return GetExcelName( LANGUAGE_ENGLISH_US, rRetExcelName );
218cdf0e10cSrcweir 
219cdf0e10cSrcweir         //  forth: use first (default) entry
220cdf0e10cSrcweir 
221cdf0e10cSrcweir         rRetExcelName = pArray[0].Name;
222cdf0e10cSrcweir         return sal_True;
223cdf0e10cSrcweir     }
224cdf0e10cSrcweir     return sal_False;
225cdf0e10cSrcweir }
226cdf0e10cSrcweir 
SetFunction(const uno::Reference<reflection::XIdlMethod> & rNewFunc,const uno::Any & rNewObj)227cdf0e10cSrcweir void ScUnoAddInFuncData::SetFunction( const uno::Reference< reflection::XIdlMethod>& rNewFunc, const uno::Any& rNewObj )
228cdf0e10cSrcweir {
229cdf0e10cSrcweir     xFunction = rNewFunc;
230cdf0e10cSrcweir     aObject = rNewObj;
231cdf0e10cSrcweir }
232cdf0e10cSrcweir 
SetArguments(long nNewCount,const ScAddInArgDesc * pNewDescs)233cdf0e10cSrcweir void ScUnoAddInFuncData::SetArguments( long nNewCount, const ScAddInArgDesc* pNewDescs )
234cdf0e10cSrcweir {
235cdf0e10cSrcweir     delete[] pArgDescs;
236cdf0e10cSrcweir 
237cdf0e10cSrcweir     nArgCount = nNewCount;
238cdf0e10cSrcweir     if ( nArgCount )
239cdf0e10cSrcweir     {
240cdf0e10cSrcweir         pArgDescs = new ScAddInArgDesc[nArgCount];
241cdf0e10cSrcweir         for (long i=0; i<nArgCount; i++)
242cdf0e10cSrcweir             pArgDescs[i] = pNewDescs[i];
243cdf0e10cSrcweir     }
244cdf0e10cSrcweir     else
245cdf0e10cSrcweir         pArgDescs = NULL;
246cdf0e10cSrcweir }
247cdf0e10cSrcweir 
SetCallerPos(long nNewPos)248cdf0e10cSrcweir void ScUnoAddInFuncData::SetCallerPos( long nNewPos )
249cdf0e10cSrcweir {
250cdf0e10cSrcweir     nCallerPos = nNewPos;
251cdf0e10cSrcweir }
252cdf0e10cSrcweir 
253cdf0e10cSrcweir //------------------------------------------------------------------------
254cdf0e10cSrcweir 
ScUnoAddInCollection()255cdf0e10cSrcweir ScUnoAddInCollection::ScUnoAddInCollection() :
256cdf0e10cSrcweir     nFuncCount( 0 ),
257cdf0e10cSrcweir     ppFuncData( NULL ),
258cdf0e10cSrcweir     pExactHashMap( NULL ),
259cdf0e10cSrcweir     pNameHashMap( NULL ),
260cdf0e10cSrcweir     pLocalHashMap( NULL ),
261cdf0e10cSrcweir     bInitialized( sal_False )
262cdf0e10cSrcweir {
263cdf0e10cSrcweir }
264cdf0e10cSrcweir 
~ScUnoAddInCollection()265cdf0e10cSrcweir ScUnoAddInCollection::~ScUnoAddInCollection()
266cdf0e10cSrcweir {
267cdf0e10cSrcweir     Clear();
268cdf0e10cSrcweir }
269cdf0e10cSrcweir 
Clear()270cdf0e10cSrcweir void ScUnoAddInCollection::Clear()
271cdf0e10cSrcweir {
272cdf0e10cSrcweir     DELETEZ( pExactHashMap );
273cdf0e10cSrcweir     DELETEZ( pNameHashMap );
274cdf0e10cSrcweir     DELETEZ( pLocalHashMap );
275cdf0e10cSrcweir     if ( ppFuncData )
276cdf0e10cSrcweir     {
277cdf0e10cSrcweir         for ( long i=0; i<nFuncCount; i++ )
278cdf0e10cSrcweir             delete ppFuncData[i];
279cdf0e10cSrcweir         delete[] ppFuncData;
280cdf0e10cSrcweir     }
281cdf0e10cSrcweir     ppFuncData = NULL;
282cdf0e10cSrcweir     nFuncCount = 0;
283cdf0e10cSrcweir 
284cdf0e10cSrcweir     bInitialized = sal_False;
285cdf0e10cSrcweir }
286cdf0e10cSrcweir 
getContext(uno::Reference<lang::XMultiServiceFactory> xMSF)287cdf0e10cSrcweir uno::Reference<uno::XComponentContext> getContext(uno::Reference<lang::XMultiServiceFactory> xMSF)
288cdf0e10cSrcweir {
289cdf0e10cSrcweir     uno::Reference<uno::XComponentContext> xCtx;
290cdf0e10cSrcweir     try {
291cdf0e10cSrcweir         uno::Reference<beans::XPropertySet> xPropset(xMSF, uno::UNO_QUERY);
292cdf0e10cSrcweir         xPropset->getPropertyValue(
293cdf0e10cSrcweir             ::rtl::OUString::createFromAscii("DefaultContext")) >>= xCtx;
294cdf0e10cSrcweir     }
295cdf0e10cSrcweir     catch ( uno::Exception & ) {
296cdf0e10cSrcweir     }
297cdf0e10cSrcweir     return xCtx;
298cdf0e10cSrcweir }
299cdf0e10cSrcweir 
Initialize()300cdf0e10cSrcweir void ScUnoAddInCollection::Initialize()
301cdf0e10cSrcweir {
302cdf0e10cSrcweir     DBG_ASSERT( !bInitialized, "Initialize twice?" );
303cdf0e10cSrcweir 
304cdf0e10cSrcweir     uno::Reference<lang::XMultiServiceFactory> xManager = comphelper::getProcessServiceFactory();
305cdf0e10cSrcweir     uno::Reference<container::XContentEnumerationAccess> xEnAc( xManager, uno::UNO_QUERY );
306cdf0e10cSrcweir     if ( xEnAc.is() )
307cdf0e10cSrcweir     {
308cdf0e10cSrcweir         uno::Reference<container::XEnumeration> xEnum =
309cdf0e10cSrcweir                         xEnAc->createContentEnumeration(
310cdf0e10cSrcweir                             rtl::OUString::createFromAscii(SCADDINSUPPLIER_SERVICE) );
311cdf0e10cSrcweir         if ( xEnum.is() )
312cdf0e10cSrcweir         {
313cdf0e10cSrcweir             //  loop through all AddIns
314cdf0e10cSrcweir             while ( xEnum->hasMoreElements() )
315cdf0e10cSrcweir             {
316cdf0e10cSrcweir                 uno::Any aAddInAny = xEnum->nextElement();
317cdf0e10cSrcweir //?             if ( aAddInAny.getReflection()->getTypeClass() == uno::TypeClass_INTERFACE )
318cdf0e10cSrcweir                 {
319cdf0e10cSrcweir                     uno::Reference<uno::XInterface> xIntFac;
320cdf0e10cSrcweir                     aAddInAny >>= xIntFac;
321cdf0e10cSrcweir                     if ( xIntFac.is() )
322cdf0e10cSrcweir                     {
323cdf0e10cSrcweir                         // #i59984# try XSingleComponentFactory in addition to (old) XSingleServiceFactory,
324cdf0e10cSrcweir                         // passing the context to the component
325cdf0e10cSrcweir 
326cdf0e10cSrcweir                         uno::Reference<uno::XInterface> xInterface;
327cdf0e10cSrcweir                         uno::Reference<uno::XComponentContext> xCtx = getContext(xManager);
328cdf0e10cSrcweir                         uno::Reference<lang::XSingleComponentFactory> xCFac( xIntFac, uno::UNO_QUERY );
329cdf0e10cSrcweir                         if (xCtx.is() && xCFac.is())
330cdf0e10cSrcweir                         {
331cdf0e10cSrcweir                             xInterface = xCFac->createInstanceWithContext(xCtx);
332cdf0e10cSrcweir                             if (xInterface.is())
333cdf0e10cSrcweir                                 ReadFromAddIn( xInterface );
334cdf0e10cSrcweir                         }
335cdf0e10cSrcweir 
336cdf0e10cSrcweir                         if (!xInterface.is())
337cdf0e10cSrcweir                         {
338cdf0e10cSrcweir                             uno::Reference<lang::XSingleServiceFactory> xFac( xIntFac, uno::UNO_QUERY );
339cdf0e10cSrcweir                             if ( xFac.is() )
340cdf0e10cSrcweir                             {
341cdf0e10cSrcweir                                 xInterface = xFac->createInstance();
342cdf0e10cSrcweir                                 if (xInterface.is())
343cdf0e10cSrcweir                                     ReadFromAddIn( xInterface );
344cdf0e10cSrcweir                             }
345cdf0e10cSrcweir                         }
346cdf0e10cSrcweir                     }
347cdf0e10cSrcweir                 }
348cdf0e10cSrcweir             }
349cdf0e10cSrcweir         }
350cdf0e10cSrcweir     }
351cdf0e10cSrcweir 
352cdf0e10cSrcweir     // ReadConfiguration is called after looking at the AddIn implementations.
353cdf0e10cSrcweir     // Duplicated are skipped (by using the service information, they don't have to be updated again
354cdf0e10cSrcweir     // when argument information is needed).
355cdf0e10cSrcweir     ReadConfiguration();
356cdf0e10cSrcweir 
357cdf0e10cSrcweir     bInitialized = sal_True;        // with or without functions
358cdf0e10cSrcweir }
359cdf0e10cSrcweir // -----------------------------------------------------------------------------
360cdf0e10cSrcweir 
lcl_GetCategory(const String & rName)361cdf0e10cSrcweir sal_uInt16 lcl_GetCategory( const String& rName )
362cdf0e10cSrcweir {
363cdf0e10cSrcweir     static const sal_Char* aFuncNames[SC_FUNCGROUP_COUNT] =
364cdf0e10cSrcweir     {
365cdf0e10cSrcweir         //  array index = ID - 1 (ID starts at 1)
366cdf0e10cSrcweir         //  all upper case
367cdf0e10cSrcweir         "Database",         // ID_FUNCTION_GRP_DATABASE
368cdf0e10cSrcweir         "Date&Time",        // ID_FUNCTION_GRP_DATETIME
369cdf0e10cSrcweir         "Financial",        // ID_FUNCTION_GRP_FINANZ
370cdf0e10cSrcweir         "Information",      // ID_FUNCTION_GRP_INFO
371cdf0e10cSrcweir         "Logical",          // ID_FUNCTION_GRP_LOGIC
372cdf0e10cSrcweir         "Mathematical",     // ID_FUNCTION_GRP_MATH
373cdf0e10cSrcweir         "Matrix",           // ID_FUNCTION_GRP_MATRIX
374cdf0e10cSrcweir         "Statistical",      // ID_FUNCTION_GRP_STATISTIC
375cdf0e10cSrcweir         "Spreadsheet",      // ID_FUNCTION_GRP_TABLE
376cdf0e10cSrcweir         "Text",             // ID_FUNCTION_GRP_TEXT
377cdf0e10cSrcweir         "Add-In"            // ID_FUNCTION_GRP_ADDINS
378cdf0e10cSrcweir     };
379cdf0e10cSrcweir     for (sal_uInt16 i=0; i<SC_FUNCGROUP_COUNT; i++)
380cdf0e10cSrcweir         if ( rName.EqualsAscii( aFuncNames[i] ) )
381cdf0e10cSrcweir             return i+1;                             // IDs start at 1
382cdf0e10cSrcweir 
383cdf0e10cSrcweir     return ID_FUNCTION_GRP_ADDINS;  // if not found, use Add-In group
384cdf0e10cSrcweir }
385cdf0e10cSrcweir 
386cdf0e10cSrcweir 
387cdf0e10cSrcweir #define CFGPATH_ADDINS              "Office.CalcAddIns/AddInInfo"
388cdf0e10cSrcweir #define CFGSTR_ADDINFUNCTIONS       "AddInFunctions"
389cdf0e10cSrcweir 
390cdf0e10cSrcweir #define CFG_FUNCPROP_DISPLAYNAME    0
391cdf0e10cSrcweir #define CFG_FUNCPROP_DESCRIPTION    1
392cdf0e10cSrcweir #define CFG_FUNCPROP_CATEGORY       2
393cdf0e10cSrcweir #define CFG_FUNCPROP_COUNT          3
394cdf0e10cSrcweir #define CFGSTR_DISPLAYNAME          "DisplayName"
395cdf0e10cSrcweir #define CFGSTR_DESCRIPTION          "Description"
396cdf0e10cSrcweir #define CFGSTR_CATEGORY             "Category"
397cdf0e10cSrcweir // CategoryDisplayName is ignored for now
398cdf0e10cSrcweir 
399cdf0e10cSrcweir #define CFGSTR_COMPATIBILITYNAME    "CompatibilityName"
400cdf0e10cSrcweir #define CFGSTR_PARAMETERS           "Parameters"
401cdf0e10cSrcweir 
402cdf0e10cSrcweir 
ReadConfiguration()403cdf0e10cSrcweir void ScUnoAddInCollection::ReadConfiguration()
404cdf0e10cSrcweir {
405cdf0e10cSrcweir     // called only from Initialize
406cdf0e10cSrcweir 
407cdf0e10cSrcweir     ScAddInCfg& rAddInConfig = SC_MOD()->GetAddInCfg();
408cdf0e10cSrcweir 
409cdf0e10cSrcweir     // additional, temporary config item for the compatibility names
410cdf0e10cSrcweir     ScLinkConfigItem aAllLocalesConfig( rtl::OUString::createFromAscii( CFGPATH_ADDINS ), CONFIG_MODE_ALL_LOCALES );
411cdf0e10cSrcweir     // CommitLink is not used (only reading values)
412cdf0e10cSrcweir 
413cdf0e10cSrcweir     const rtl::OUString sSlash('/');
414cdf0e10cSrcweir 
415cdf0e10cSrcweir     // get the list of add-ins (services)
416cdf0e10cSrcweir     rtl::OUString aEmptyString;
417cdf0e10cSrcweir     uno::Sequence<rtl::OUString> aServiceNames = rAddInConfig.GetNodeNames( aEmptyString );
418cdf0e10cSrcweir 
419cdf0e10cSrcweir     sal_Int32 nServiceCount = aServiceNames.getLength();
420cdf0e10cSrcweir     for ( sal_Int32 nService = 0; nService < nServiceCount; nService++ )
421cdf0e10cSrcweir     {
422cdf0e10cSrcweir         rtl::OUString aServiceName = aServiceNames[nService];
423cdf0e10cSrcweir         ScUnoAddInHelpIdGenerator aHelpIdGenerator( aServiceName );
424cdf0e10cSrcweir 
425cdf0e10cSrcweir         rtl::OUString aFunctionsPath = aServiceName;
426cdf0e10cSrcweir         aFunctionsPath += sSlash;
427cdf0e10cSrcweir         aFunctionsPath += rtl::OUString::createFromAscii( CFGSTR_ADDINFUNCTIONS );
428cdf0e10cSrcweir 
429cdf0e10cSrcweir         uno::Sequence<rtl::OUString> aFunctionNames = rAddInConfig.GetNodeNames( aFunctionsPath );
430cdf0e10cSrcweir         sal_Int32 nNewCount = aFunctionNames.getLength();
431cdf0e10cSrcweir 
432cdf0e10cSrcweir         // allocate pointers
433cdf0e10cSrcweir 
434cdf0e10cSrcweir         long nOld = nFuncCount;
435cdf0e10cSrcweir         nFuncCount = nNewCount+nOld;
436cdf0e10cSrcweir         if ( nOld )
437cdf0e10cSrcweir         {
438cdf0e10cSrcweir             ScUnoAddInFuncData** ppNew = new ScUnoAddInFuncData*[nFuncCount];
439cdf0e10cSrcweir             for (long i=0; i<nOld; i++)
440cdf0e10cSrcweir                 ppNew[i] = ppFuncData[i];
441cdf0e10cSrcweir             delete[] ppFuncData;
442cdf0e10cSrcweir             ppFuncData = ppNew;
443cdf0e10cSrcweir         }
444cdf0e10cSrcweir         else
445cdf0e10cSrcweir             ppFuncData = new ScUnoAddInFuncData*[nFuncCount];
446cdf0e10cSrcweir 
447cdf0e10cSrcweir         //! TODO: adjust bucket count?
448cdf0e10cSrcweir         if ( !pExactHashMap )
449cdf0e10cSrcweir             pExactHashMap = new ScAddInHashMap;
450cdf0e10cSrcweir         if ( !pNameHashMap )
451cdf0e10cSrcweir             pNameHashMap = new ScAddInHashMap;
452cdf0e10cSrcweir         if ( !pLocalHashMap )
453cdf0e10cSrcweir             pLocalHashMap = new ScAddInHashMap;
454cdf0e10cSrcweir 
455cdf0e10cSrcweir         //! get the function information in a single call for all functions?
456cdf0e10cSrcweir 
457cdf0e10cSrcweir         const rtl::OUString* pFuncNameArray = aFunctionNames.getConstArray();
458cdf0e10cSrcweir         for ( sal_Int32 nFuncPos = 0; nFuncPos < nNewCount; nFuncPos++ )
459cdf0e10cSrcweir         {
460cdf0e10cSrcweir             ppFuncData[nFuncPos+nOld] = NULL;
461cdf0e10cSrcweir 
462cdf0e10cSrcweir             // stored function name: (service name).(function)
463cdf0e10cSrcweir             String aFuncName( aServiceName );
464cdf0e10cSrcweir             aFuncName += '.';
465cdf0e10cSrcweir             aFuncName += String( pFuncNameArray[nFuncPos] );
466cdf0e10cSrcweir 
467cdf0e10cSrcweir             // skip the function if already known (read from old AddIn service)
468cdf0e10cSrcweir 
469cdf0e10cSrcweir             if ( pExactHashMap->find( aFuncName ) == pExactHashMap->end() )
470cdf0e10cSrcweir             {
471cdf0e10cSrcweir                 rtl::OUString aLocalName;
472cdf0e10cSrcweir                 rtl::OUString aDescription;
473cdf0e10cSrcweir                 sal_uInt16 nCategory = ID_FUNCTION_GRP_ADDINS;
474cdf0e10cSrcweir 
475cdf0e10cSrcweir                 // get direct information on the function
476cdf0e10cSrcweir 
477cdf0e10cSrcweir                 rtl::OUString aFuncPropPath = aFunctionsPath;
478cdf0e10cSrcweir                 aFuncPropPath += sSlash;
479cdf0e10cSrcweir                 aFuncPropPath += pFuncNameArray[nFuncPos];
480cdf0e10cSrcweir                 aFuncPropPath += sSlash;
481cdf0e10cSrcweir 
482cdf0e10cSrcweir                 uno::Sequence<rtl::OUString> aFuncPropNames(CFG_FUNCPROP_COUNT);
483cdf0e10cSrcweir                 rtl::OUString* pNameArray = aFuncPropNames.getArray();
484cdf0e10cSrcweir                 pNameArray[CFG_FUNCPROP_DISPLAYNAME] = aFuncPropPath;
485cdf0e10cSrcweir                 pNameArray[CFG_FUNCPROP_DISPLAYNAME] += rtl::OUString::createFromAscii( CFGSTR_DISPLAYNAME );
486cdf0e10cSrcweir                 pNameArray[CFG_FUNCPROP_DESCRIPTION] = aFuncPropPath;
487cdf0e10cSrcweir                 pNameArray[CFG_FUNCPROP_DESCRIPTION] += rtl::OUString::createFromAscii( CFGSTR_DESCRIPTION );
488cdf0e10cSrcweir                 pNameArray[CFG_FUNCPROP_CATEGORY] = aFuncPropPath;
489cdf0e10cSrcweir                 pNameArray[CFG_FUNCPROP_CATEGORY] += rtl::OUString::createFromAscii( CFGSTR_CATEGORY );
490cdf0e10cSrcweir 
491cdf0e10cSrcweir                 uno::Sequence<uno::Any> aFuncProperties = rAddInConfig.GetProperties( aFuncPropNames );
492cdf0e10cSrcweir                 if ( aFuncProperties.getLength() == CFG_FUNCPROP_COUNT )
493cdf0e10cSrcweir                 {
494cdf0e10cSrcweir                     aFuncProperties[CFG_FUNCPROP_DISPLAYNAME] >>= aLocalName;
495cdf0e10cSrcweir                     aFuncProperties[CFG_FUNCPROP_DESCRIPTION] >>= aDescription;
496cdf0e10cSrcweir 
497cdf0e10cSrcweir                     rtl::OUString aCategoryName;
498cdf0e10cSrcweir                     aFuncProperties[CFG_FUNCPROP_CATEGORY] >>= aCategoryName;
499cdf0e10cSrcweir                     nCategory = lcl_GetCategory( aCategoryName );
500cdf0e10cSrcweir                 }
501cdf0e10cSrcweir 
502cdf0e10cSrcweir                 // get compatibility names
503cdf0e10cSrcweir 
504cdf0e10cSrcweir                 uno::Sequence<sheet::LocalizedName> aCompNames;
505cdf0e10cSrcweir 
506cdf0e10cSrcweir                 rtl::OUString aCompPath = aFuncPropPath;
507cdf0e10cSrcweir                 aCompPath += rtl::OUString::createFromAscii( CFGSTR_COMPATIBILITYNAME );
508cdf0e10cSrcweir                 uno::Sequence<rtl::OUString> aCompPropNames( &aCompPath, 1 );
509cdf0e10cSrcweir 
510cdf0e10cSrcweir                 uno::Sequence<uno::Any> aCompProperties = aAllLocalesConfig.GetProperties( aCompPropNames );
511cdf0e10cSrcweir                 if ( aCompProperties.getLength() == 1 )
512cdf0e10cSrcweir                 {
513cdf0e10cSrcweir                     uno::Sequence<beans::PropertyValue> aLocalEntries;
514cdf0e10cSrcweir                     if ( aCompProperties[0] >>= aLocalEntries )
515cdf0e10cSrcweir                     {
516cdf0e10cSrcweir                         sal_Int32 nLocaleCount = aLocalEntries.getLength();
517cdf0e10cSrcweir                         aCompNames.realloc( nLocaleCount );
518cdf0e10cSrcweir                         const beans::PropertyValue* pConfigArray = aLocalEntries.getConstArray();
519cdf0e10cSrcweir                         sheet::LocalizedName* pCompArray = aCompNames.getArray();
520cdf0e10cSrcweir 
521cdf0e10cSrcweir                         for ( sal_Int32 nLocale = 0; nLocale < nLocaleCount; nLocale++ )
522cdf0e10cSrcweir                         {
523cdf0e10cSrcweir                             const sal_Unicode cLocaleSep = '-';     // separator in configuration locale strings
524cdf0e10cSrcweir 
525cdf0e10cSrcweir                             // PropertyValue name is the locale (convert from string to Locale struct)
526cdf0e10cSrcweir 
527cdf0e10cSrcweir                             const rtl::OUString& rLocaleStr = pConfigArray[nLocale].Name;
528cdf0e10cSrcweir                             lang::Locale& rLocale = pCompArray[nLocale].Locale;
529cdf0e10cSrcweir                             sal_Int32 nSepPos = rLocaleStr.indexOf( cLocaleSep );
530cdf0e10cSrcweir                             if ( nSepPos >= 0 )
531cdf0e10cSrcweir                             {
532cdf0e10cSrcweir                                 rLocale.Language = rLocaleStr.copy( 0, nSepPos );
533cdf0e10cSrcweir                                 rLocale.Country = rLocaleStr.copy( nSepPos+1 );
534cdf0e10cSrcweir                             }
535cdf0e10cSrcweir                             else
536cdf0e10cSrcweir                                 rLocale.Language = rLocaleStr;      // leave country empty (default ctor from sequence)
537cdf0e10cSrcweir 
538cdf0e10cSrcweir                             // PropertyValue value is the localized value (string in this case)
539cdf0e10cSrcweir 
540cdf0e10cSrcweir                             pConfigArray[nLocale].Value >>= pCompArray[nLocale].Name;
541cdf0e10cSrcweir                         }
542cdf0e10cSrcweir                     }
543cdf0e10cSrcweir                 }
544cdf0e10cSrcweir 
545cdf0e10cSrcweir                 // get argument info
546cdf0e10cSrcweir 
547cdf0e10cSrcweir                 ScAddInArgDesc* pVisibleArgs = NULL;
548cdf0e10cSrcweir                 long nVisibleCount = 0;
549cdf0e10cSrcweir                 long nCallerPos = SC_CALLERPOS_NONE;
550cdf0e10cSrcweir 
551cdf0e10cSrcweir                 rtl::OUString aArgumentsPath = aFuncPropPath;
552cdf0e10cSrcweir                 aArgumentsPath += rtl::OUString::createFromAscii( CFGSTR_PARAMETERS );
553cdf0e10cSrcweir 
554cdf0e10cSrcweir                 uno::Sequence<rtl::OUString> aArgumentNames = rAddInConfig.GetNodeNames( aArgumentsPath );
555cdf0e10cSrcweir                 sal_Int32 nArgumentCount = aArgumentNames.getLength();
556cdf0e10cSrcweir                 if ( nArgumentCount )
557cdf0e10cSrcweir                 {
558cdf0e10cSrcweir                     // get DisplayName and Description for each argument
559cdf0e10cSrcweir                     uno::Sequence<rtl::OUString> aArgPropNames( nArgumentCount * 2 );
560cdf0e10cSrcweir                     rtl::OUString* pPropNameArray = aArgPropNames.getArray();
561cdf0e10cSrcweir 
562cdf0e10cSrcweir                     sal_Int32 nArgument;
563cdf0e10cSrcweir                     sal_Int32 nIndex = 0;
564cdf0e10cSrcweir                     const rtl::OUString* pArgNameArray = aArgumentNames.getConstArray();
565cdf0e10cSrcweir                     for ( nArgument = 0; nArgument < nArgumentCount; nArgument++ )
566cdf0e10cSrcweir                     {
567cdf0e10cSrcweir                         rtl::OUString aOneArgPath = aArgumentsPath;
568cdf0e10cSrcweir                         aOneArgPath += sSlash;
569cdf0e10cSrcweir                         aOneArgPath += pArgNameArray[nArgument];
570cdf0e10cSrcweir                         aOneArgPath += sSlash;
571cdf0e10cSrcweir 
572cdf0e10cSrcweir                         pPropNameArray[nIndex] = aOneArgPath;
573cdf0e10cSrcweir                         pPropNameArray[nIndex++] += rtl::OUString::createFromAscii( CFGSTR_DISPLAYNAME );
574cdf0e10cSrcweir                         pPropNameArray[nIndex] = aOneArgPath;
575cdf0e10cSrcweir                         pPropNameArray[nIndex++] += rtl::OUString::createFromAscii( CFGSTR_DESCRIPTION );
576cdf0e10cSrcweir                     }
577cdf0e10cSrcweir 
578cdf0e10cSrcweir                     uno::Sequence<uno::Any> aArgProperties = rAddInConfig.GetProperties( aArgPropNames );
579cdf0e10cSrcweir                     if ( aArgProperties.getLength() == aArgPropNames.getLength() )
580cdf0e10cSrcweir                     {
581cdf0e10cSrcweir                         const uno::Any* pPropArray = aArgProperties.getConstArray();
582cdf0e10cSrcweir                         rtl::OUString sDisplayName;
583cdf0e10cSrcweir                         rtl::OUString sDescription;
584cdf0e10cSrcweir 
585cdf0e10cSrcweir                         ScAddInArgDesc aDesc;
586cdf0e10cSrcweir                         aDesc.eType = SC_ADDINARG_NONE;     // arg type is not in configuration
587cdf0e10cSrcweir                         aDesc.bOptional = sal_False;
588cdf0e10cSrcweir 
589cdf0e10cSrcweir                         nVisibleCount = nArgumentCount;
590cdf0e10cSrcweir                         pVisibleArgs = new ScAddInArgDesc[nVisibleCount];
591cdf0e10cSrcweir 
592cdf0e10cSrcweir                         nIndex = 0;
593cdf0e10cSrcweir                         for ( nArgument = 0; nArgument < nArgumentCount; nArgument++ )
594cdf0e10cSrcweir                         {
595cdf0e10cSrcweir                             pPropArray[nIndex++] >>= sDisplayName;
596cdf0e10cSrcweir                             pPropArray[nIndex++] >>= sDescription;
597cdf0e10cSrcweir 
598cdf0e10cSrcweir                             aDesc.aInternalName = pArgNameArray[nArgument];
599cdf0e10cSrcweir                             aDesc.aName         = sDisplayName;
600cdf0e10cSrcweir                             aDesc.aDescription  = sDescription;
601cdf0e10cSrcweir 
602cdf0e10cSrcweir                             pVisibleArgs[nArgument] = aDesc;
603cdf0e10cSrcweir                         }
604cdf0e10cSrcweir                     }
605cdf0e10cSrcweir                 }
606cdf0e10cSrcweir 
607cdf0e10cSrcweir                 rtl::OString sHelpId = aHelpIdGenerator.GetHelpId( pFuncNameArray[nFuncPos] );
608cdf0e10cSrcweir 
609cdf0e10cSrcweir                 uno::Reference<reflection::XIdlMethod> xFunc;       // remains empty
610cdf0e10cSrcweir                 uno::Any aObject;                                   // also empty
611cdf0e10cSrcweir 
612cdf0e10cSrcweir                 // create and insert into the array
613cdf0e10cSrcweir 
614cdf0e10cSrcweir                 ScUnoAddInFuncData* pData = new ScUnoAddInFuncData(
615cdf0e10cSrcweir                     aFuncName, aLocalName, aDescription,
616cdf0e10cSrcweir                     nCategory, sHelpId,
617cdf0e10cSrcweir                     xFunc, aObject,
618cdf0e10cSrcweir                     nVisibleCount, pVisibleArgs, nCallerPos );
619cdf0e10cSrcweir 
620cdf0e10cSrcweir                 pData->SetCompNames( aCompNames );
621cdf0e10cSrcweir 
622cdf0e10cSrcweir                 ppFuncData[nFuncPos+nOld] = pData;
623cdf0e10cSrcweir 
624cdf0e10cSrcweir                 pExactHashMap->insert(
625cdf0e10cSrcweir                         ScAddInHashMap::value_type(
626cdf0e10cSrcweir                             pData->GetOriginalName(),
627cdf0e10cSrcweir                             pData ) );
628cdf0e10cSrcweir                 pNameHashMap->insert(
629cdf0e10cSrcweir                         ScAddInHashMap::value_type(
630cdf0e10cSrcweir                             pData->GetUpperName(),
631cdf0e10cSrcweir                             pData ) );
632cdf0e10cSrcweir                 pLocalHashMap->insert(
633cdf0e10cSrcweir                         ScAddInHashMap::value_type(
634cdf0e10cSrcweir                             pData->GetUpperLocal(),
635cdf0e10cSrcweir                             pData ) );
636cdf0e10cSrcweir 
637cdf0e10cSrcweir                 delete[] pVisibleArgs;
638cdf0e10cSrcweir             }
639cdf0e10cSrcweir         }
640cdf0e10cSrcweir     }
641cdf0e10cSrcweir }
642cdf0e10cSrcweir 
LoadComponent(const ScUnoAddInFuncData & rFuncData)643cdf0e10cSrcweir void ScUnoAddInCollection::LoadComponent( const ScUnoAddInFuncData& rFuncData )
644cdf0e10cSrcweir {
645cdf0e10cSrcweir     String aFullName = rFuncData.GetOriginalName();
646cdf0e10cSrcweir     xub_StrLen nPos = aFullName.SearchBackward( (sal_Unicode) '.' );
647cdf0e10cSrcweir     if ( nPos != STRING_NOTFOUND && nPos > 0 )
648cdf0e10cSrcweir     {
649cdf0e10cSrcweir         String aServiceName = aFullName.Copy( 0, nPos );
650cdf0e10cSrcweir 
651cdf0e10cSrcweir         uno::Reference<lang::XMultiServiceFactory> xServiceFactory = comphelper::getProcessServiceFactory();
652cdf0e10cSrcweir         uno::Reference<uno::XInterface> xInterface( xServiceFactory->createInstance( aServiceName ) );
653cdf0e10cSrcweir 
654cdf0e10cSrcweir         if (xInterface.is())
655cdf0e10cSrcweir             UpdateFromAddIn( xInterface, aServiceName );
656cdf0e10cSrcweir     }
657cdf0e10cSrcweir }
658cdf0e10cSrcweir 
GetExcelName(const String & rCalcName,LanguageType eDestLang,String & rRetExcelName)659cdf0e10cSrcweir sal_Bool ScUnoAddInCollection::GetExcelName( const String& rCalcName,
660cdf0e10cSrcweir                                         LanguageType eDestLang, String& rRetExcelName )
661cdf0e10cSrcweir {
662cdf0e10cSrcweir     const ScUnoAddInFuncData* pFuncData = GetFuncData( rCalcName );
663cdf0e10cSrcweir     if ( pFuncData )
664cdf0e10cSrcweir         return pFuncData->GetExcelName( eDestLang, rRetExcelName);
665cdf0e10cSrcweir     return sal_False;
666cdf0e10cSrcweir }
667cdf0e10cSrcweir 
GetCalcName(const String & rExcelName,String & rRetCalcName)668cdf0e10cSrcweir sal_Bool ScUnoAddInCollection::GetCalcName( const String& rExcelName, String& rRetCalcName )
669cdf0e10cSrcweir {
670cdf0e10cSrcweir     if (!bInitialized)
671cdf0e10cSrcweir         Initialize();
672cdf0e10cSrcweir 
673cdf0e10cSrcweir     String aUpperCmp = rExcelName;
674cdf0e10cSrcweir     ScGlobal::pCharClass->toUpper(aUpperCmp);
675cdf0e10cSrcweir 
676cdf0e10cSrcweir     for (long i=0; i<nFuncCount; i++)
677cdf0e10cSrcweir     {
678cdf0e10cSrcweir         ScUnoAddInFuncData* pFuncData = ppFuncData[i];
679cdf0e10cSrcweir         if ( pFuncData )
680cdf0e10cSrcweir         {
681cdf0e10cSrcweir             const uno::Sequence<sheet::LocalizedName>& rSequence = pFuncData->GetCompNames();
682cdf0e10cSrcweir             long nSeqLen = rSequence.getLength();
683cdf0e10cSrcweir             if ( nSeqLen )
684cdf0e10cSrcweir             {
685cdf0e10cSrcweir                 const sheet::LocalizedName* pArray = rSequence.getConstArray();
686cdf0e10cSrcweir                 for ( long nName=0; nName<nSeqLen; nName++)
687cdf0e10cSrcweir                     if ( ScGlobal::pCharClass->upper( pArray[nName].Name ) == aUpperCmp )
688cdf0e10cSrcweir                     {
689cdf0e10cSrcweir                         //! store upper case for comparing?
690cdf0e10cSrcweir 
691cdf0e10cSrcweir                         //  use the first function that has this name for any language
692cdf0e10cSrcweir                         rRetCalcName = pFuncData->GetOriginalName();
693cdf0e10cSrcweir                         return sal_True;
694cdf0e10cSrcweir                     }
695cdf0e10cSrcweir             }
696cdf0e10cSrcweir         }
697cdf0e10cSrcweir     }
698cdf0e10cSrcweir     return sal_False;
699cdf0e10cSrcweir }
700cdf0e10cSrcweir 
IsTypeName(const rtl::OUString & rName,const uno::Type & rType)701cdf0e10cSrcweir inline sal_Bool IsTypeName( const rtl::OUString& rName, const uno::Type& rType )
702cdf0e10cSrcweir {
703cdf0e10cSrcweir     return rName == rType.getTypeName();
704cdf0e10cSrcweir }
705cdf0e10cSrcweir 
lcl_ValidReturnType(const uno::Reference<reflection::XIdlClass> & xClass)706cdf0e10cSrcweir sal_Bool lcl_ValidReturnType( const uno::Reference<reflection::XIdlClass>& xClass )
707cdf0e10cSrcweir {
708cdf0e10cSrcweir     //  this must match with ScUnoAddInCall::SetResult
709cdf0e10cSrcweir 
710cdf0e10cSrcweir     if ( !xClass.is() ) return sal_False;
711cdf0e10cSrcweir 
712cdf0e10cSrcweir     switch (xClass->getTypeClass())
713cdf0e10cSrcweir     {
714cdf0e10cSrcweir         // case uno::TypeClass_VOID:
715cdf0e10cSrcweir         //  ???
716cdf0e10cSrcweir 
717cdf0e10cSrcweir         case uno::TypeClass_ANY:                // variable type
718cdf0e10cSrcweir         case uno::TypeClass_ENUM:               //! ???
719cdf0e10cSrcweir         case uno::TypeClass_BOOLEAN:
720cdf0e10cSrcweir         case uno::TypeClass_CHAR:
721cdf0e10cSrcweir         case uno::TypeClass_BYTE:
722cdf0e10cSrcweir         case uno::TypeClass_SHORT:
723cdf0e10cSrcweir         case uno::TypeClass_UNSIGNED_SHORT:
724cdf0e10cSrcweir         case uno::TypeClass_LONG:
725cdf0e10cSrcweir         case uno::TypeClass_UNSIGNED_LONG:
726cdf0e10cSrcweir         case uno::TypeClass_FLOAT:
727cdf0e10cSrcweir         case uno::TypeClass_DOUBLE:
728cdf0e10cSrcweir         case uno::TypeClass_STRING:
729cdf0e10cSrcweir             return sal_True;                        // values or string
730cdf0e10cSrcweir 
731cdf0e10cSrcweir         case uno::TypeClass_INTERFACE:
732cdf0e10cSrcweir             {
733cdf0e10cSrcweir                 //  return type XInterface may contain a XVolatileResult
734cdf0e10cSrcweir                 //! XIdlClass needs getType() method!
735cdf0e10cSrcweir 
736cdf0e10cSrcweir                 rtl::OUString sName = xClass->getName();
737cdf0e10cSrcweir                 return (
738cdf0e10cSrcweir                     IsTypeName( sName, getCppuType((uno::Reference<sheet::XVolatileResult>*)0) ) ||
739cdf0e10cSrcweir                     IsTypeName( sName, getCppuType((uno::Reference<uno::XInterface>*)0) ) );
740cdf0e10cSrcweir             }
741cdf0e10cSrcweir 
742cdf0e10cSrcweir         default:
743cdf0e10cSrcweir             {
744cdf0e10cSrcweir                 //  nested sequences for arrays
745cdf0e10cSrcweir                 //! XIdlClass needs getType() method!
746cdf0e10cSrcweir 
747cdf0e10cSrcweir                 rtl::OUString sName = xClass->getName();
748cdf0e10cSrcweir                 return (
749cdf0e10cSrcweir                     IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<sal_Int32> >*)0) ) ||
750cdf0e10cSrcweir                     IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<double> >*)0) ) ||
751cdf0e10cSrcweir                     IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<rtl::OUString> >*)0) ) ||
752cdf0e10cSrcweir                     IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<uno::Any> >*)0) ) );
753cdf0e10cSrcweir             }
754cdf0e10cSrcweir     }
755cdf0e10cSrcweir     return sal_False;
756cdf0e10cSrcweir }
757cdf0e10cSrcweir 
lcl_GetArgType(const uno::Reference<reflection::XIdlClass> & xClass)758cdf0e10cSrcweir ScAddInArgumentType lcl_GetArgType( const uno::Reference<reflection::XIdlClass>& xClass )
759cdf0e10cSrcweir {
760cdf0e10cSrcweir     if (!xClass.is())
761cdf0e10cSrcweir         return SC_ADDINARG_NONE;
762cdf0e10cSrcweir 
763cdf0e10cSrcweir     uno::TypeClass eType = xClass->getTypeClass();
764cdf0e10cSrcweir 
765cdf0e10cSrcweir     if ( eType == uno::TypeClass_LONG )             //! other integer types?
766cdf0e10cSrcweir         return SC_ADDINARG_INTEGER;
767cdf0e10cSrcweir 
768cdf0e10cSrcweir     if ( eType == uno::TypeClass_DOUBLE )
769cdf0e10cSrcweir         return SC_ADDINARG_DOUBLE;
770cdf0e10cSrcweir 
771cdf0e10cSrcweir     if ( eType == uno::TypeClass_STRING )
772cdf0e10cSrcweir         return SC_ADDINARG_STRING;
773cdf0e10cSrcweir 
774cdf0e10cSrcweir     //! XIdlClass needs getType() method!
775cdf0e10cSrcweir     rtl::OUString sName = xClass->getName();
776cdf0e10cSrcweir 
777cdf0e10cSrcweir     if (IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<sal_Int32> >*)0) ))
778cdf0e10cSrcweir         return SC_ADDINARG_INTEGER_ARRAY;
779cdf0e10cSrcweir 
780cdf0e10cSrcweir     if (IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<double> >*)0) ))
781cdf0e10cSrcweir         return SC_ADDINARG_DOUBLE_ARRAY;
782cdf0e10cSrcweir 
783cdf0e10cSrcweir     if (IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<rtl::OUString> >*)0) ))
784cdf0e10cSrcweir         return SC_ADDINARG_STRING_ARRAY;
785cdf0e10cSrcweir 
786cdf0e10cSrcweir     if (IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<uno::Any> >*)0) ))
787cdf0e10cSrcweir         return SC_ADDINARG_MIXED_ARRAY;
788cdf0e10cSrcweir 
789cdf0e10cSrcweir     if (IsTypeName( sName, getCppuType((uno::Any*)0) ))
790cdf0e10cSrcweir         return SC_ADDINARG_VALUE_OR_ARRAY;
791cdf0e10cSrcweir 
792cdf0e10cSrcweir     if (IsTypeName( sName, getCppuType((uno::Reference<table::XCellRange>*)0) ))
793cdf0e10cSrcweir         return SC_ADDINARG_CELLRANGE;
794cdf0e10cSrcweir 
795cdf0e10cSrcweir     if (IsTypeName( sName, getCppuType((uno::Reference<beans::XPropertySet>*)0) ))
796cdf0e10cSrcweir         return SC_ADDINARG_CALLER;
797cdf0e10cSrcweir 
798cdf0e10cSrcweir     if (IsTypeName( sName, getCppuType((uno::Sequence<uno::Any>*)0) ))
799cdf0e10cSrcweir         return SC_ADDINARG_VARARGS;
800cdf0e10cSrcweir 
801cdf0e10cSrcweir     return SC_ADDINARG_NONE;
802cdf0e10cSrcweir }
803cdf0e10cSrcweir 
ReadFromAddIn(const uno::Reference<uno::XInterface> & xInterface)804cdf0e10cSrcweir void ScUnoAddInCollection::ReadFromAddIn( const uno::Reference<uno::XInterface>& xInterface )
805cdf0e10cSrcweir {
806cdf0e10cSrcweir     uno::Reference<sheet::XAddIn> xAddIn( xInterface, uno::UNO_QUERY );
807cdf0e10cSrcweir     uno::Reference<lang::XServiceName> xName( xInterface, uno::UNO_QUERY );
808cdf0e10cSrcweir     if ( xAddIn.is() && xName.is() )
809cdf0e10cSrcweir     {
810cdf0e10cSrcweir         //  AddIns must use the language for which the office is installed
811cdf0e10cSrcweir         LanguageType eOfficeLang = Application::GetSettings().GetUILanguage();
812cdf0e10cSrcweir 
813cdf0e10cSrcweir         lang::Locale aLocale( MsLangId::convertLanguageToLocale( eOfficeLang ));
814cdf0e10cSrcweir         xAddIn->setLocale( aLocale );
815cdf0e10cSrcweir 
816cdf0e10cSrcweir         String aServiceName = String( xName->getServiceName() );
817cdf0e10cSrcweir         ScUnoAddInHelpIdGenerator aHelpIdGenerator( xName->getServiceName() );
818cdf0e10cSrcweir 
819cdf0e10cSrcweir         //! pass XIntrospection to ReadFromAddIn
820cdf0e10cSrcweir 
821cdf0e10cSrcweir         uno::Reference<lang::XMultiServiceFactory> xManager = comphelper::getProcessServiceFactory();
822cdf0e10cSrcweir         if ( xManager.is() )
823cdf0e10cSrcweir         {
824cdf0e10cSrcweir             uno::Reference<beans::XIntrospection> xIntro(
825cdf0e10cSrcweir                                     xManager->createInstance(rtl::OUString::createFromAscii(
826cdf0e10cSrcweir                                         "com.sun.star.beans.Introspection" )),
827cdf0e10cSrcweir                                     uno::UNO_QUERY );
828cdf0e10cSrcweir             if ( xIntro.is() )
829cdf0e10cSrcweir             {
830cdf0e10cSrcweir                 uno::Any aObject;
831cdf0e10cSrcweir                 aObject <<= xAddIn;
832cdf0e10cSrcweir                 uno::Reference<beans::XIntrospectionAccess> xAcc = xIntro->inspect(aObject);
833cdf0e10cSrcweir                 if (xAcc.is())
834cdf0e10cSrcweir                 {
835cdf0e10cSrcweir                     uno::Sequence< uno::Reference<reflection::XIdlMethod> > aMethods =
836cdf0e10cSrcweir                             xAcc->getMethods( beans::MethodConcept::ALL );
837cdf0e10cSrcweir                     long nNewCount = aMethods.getLength();
838cdf0e10cSrcweir                     if ( nNewCount )
839cdf0e10cSrcweir                     {
840cdf0e10cSrcweir                         long nOld = nFuncCount;
841cdf0e10cSrcweir                         nFuncCount = nNewCount+nOld;
842cdf0e10cSrcweir                         if ( nOld )
843cdf0e10cSrcweir                         {
844cdf0e10cSrcweir                             ScUnoAddInFuncData** ppNew = new ScUnoAddInFuncData*[nFuncCount];
845cdf0e10cSrcweir                             for (long i=0; i<nOld; i++)
846cdf0e10cSrcweir                                 ppNew[i] = ppFuncData[i];
847cdf0e10cSrcweir                             delete[] ppFuncData;
848cdf0e10cSrcweir                             ppFuncData = ppNew;
849cdf0e10cSrcweir                         }
850cdf0e10cSrcweir                         else
851cdf0e10cSrcweir                             ppFuncData = new ScUnoAddInFuncData*[nFuncCount];
852cdf0e10cSrcweir 
853cdf0e10cSrcweir                         //! TODO: adjust bucket count?
854cdf0e10cSrcweir                         if ( !pExactHashMap )
855cdf0e10cSrcweir                             pExactHashMap = new ScAddInHashMap;
856cdf0e10cSrcweir                         if ( !pNameHashMap )
857cdf0e10cSrcweir                             pNameHashMap = new ScAddInHashMap;
858cdf0e10cSrcweir                         if ( !pLocalHashMap )
859cdf0e10cSrcweir                             pLocalHashMap = new ScAddInHashMap;
860cdf0e10cSrcweir 
861cdf0e10cSrcweir                         const uno::Reference<reflection::XIdlMethod>* pArray = aMethods.getConstArray();
862cdf0e10cSrcweir                         for (long nFuncPos=0; nFuncPos<nNewCount; nFuncPos++)
863cdf0e10cSrcweir                         {
864cdf0e10cSrcweir                             ppFuncData[nFuncPos+nOld] = NULL;
865cdf0e10cSrcweir 
866cdf0e10cSrcweir                             uno::Reference<reflection::XIdlMethod> xFunc = pArray[nFuncPos];
867cdf0e10cSrcweir                             if (xFunc.is())
868cdf0e10cSrcweir                             {
869cdf0e10cSrcweir                                 //  leave out internal functions
870cdf0e10cSrcweir                                 uno::Reference<reflection::XIdlClass> xClass =
871cdf0e10cSrcweir                                                 xFunc->getDeclaringClass();
872cdf0e10cSrcweir                                 sal_Bool bSkip = sal_True;
873cdf0e10cSrcweir                                 if ( xClass.is() )
874cdf0e10cSrcweir                                 {
875cdf0e10cSrcweir                                     //! XIdlClass needs getType() method!
876cdf0e10cSrcweir                                     rtl::OUString sName = xClass->getName();
877cdf0e10cSrcweir                                     bSkip = (
878cdf0e10cSrcweir                                         IsTypeName( sName,
879cdf0e10cSrcweir                                             getCppuType((uno::Reference<uno::XInterface>*)0) ) ||
880cdf0e10cSrcweir                                         IsTypeName( sName,
881cdf0e10cSrcweir                                             getCppuType((uno::Reference<reflection::XIdlClassProvider>*)0) ) ||
882cdf0e10cSrcweir                                         IsTypeName( sName,
883cdf0e10cSrcweir                                             getCppuType((uno::Reference<lang::XServiceName>*)0) ) ||
884cdf0e10cSrcweir                                         IsTypeName( sName,
885cdf0e10cSrcweir                                             getCppuType((uno::Reference<lang::XServiceInfo>*)0) ) ||
886cdf0e10cSrcweir                                         IsTypeName( sName,
887cdf0e10cSrcweir                                             getCppuType((uno::Reference<sheet::XAddIn>*)0) ) );
888cdf0e10cSrcweir                                 }
889cdf0e10cSrcweir                                 if (!bSkip)
890cdf0e10cSrcweir                                 {
891cdf0e10cSrcweir                                     uno::Reference<reflection::XIdlClass> xReturn =
892cdf0e10cSrcweir                                                 xFunc->getReturnType();
893cdf0e10cSrcweir                                     if ( !lcl_ValidReturnType( xReturn ) )
894cdf0e10cSrcweir                                         bSkip = sal_True;
895cdf0e10cSrcweir                                 }
896cdf0e10cSrcweir                                 if (!bSkip)
897cdf0e10cSrcweir                                 {
898cdf0e10cSrcweir                                     rtl::OUString aFuncU = xFunc->getName();
899cdf0e10cSrcweir 
900cdf0e10cSrcweir                                     // stored function name: (service name).(function)
901cdf0e10cSrcweir                                     String aFuncName = aServiceName;
902cdf0e10cSrcweir                                     aFuncName += '.';
903cdf0e10cSrcweir                                     aFuncName += String( aFuncU );
904cdf0e10cSrcweir 
905cdf0e10cSrcweir                                     sal_Bool bValid = sal_True;
906cdf0e10cSrcweir                                     long nVisibleCount = 0;
907cdf0e10cSrcweir                                     long nCallerPos = SC_CALLERPOS_NONE;
908cdf0e10cSrcweir 
909cdf0e10cSrcweir                                     uno::Sequence<reflection::ParamInfo> aParams =
910cdf0e10cSrcweir                                             xFunc->getParameterInfos();
911cdf0e10cSrcweir                                     long nParamCount = aParams.getLength();
912cdf0e10cSrcweir                                     const reflection::ParamInfo* pParArr = aParams.getConstArray();
913cdf0e10cSrcweir                                     long nParamPos;
914cdf0e10cSrcweir                                     for (nParamPos=0; nParamPos<nParamCount; nParamPos++)
915cdf0e10cSrcweir                                     {
916cdf0e10cSrcweir                                         if ( pParArr[nParamPos].aMode != reflection::ParamMode_IN )
917cdf0e10cSrcweir                                             bValid = sal_False;
918cdf0e10cSrcweir                                         uno::Reference<reflection::XIdlClass> xParClass =
919cdf0e10cSrcweir                                                     pParArr[nParamPos].aType;
920cdf0e10cSrcweir                                         ScAddInArgumentType eArgType = lcl_GetArgType( xParClass );
921cdf0e10cSrcweir                                         if ( eArgType == SC_ADDINARG_NONE )
922cdf0e10cSrcweir                                             bValid = sal_False;
923cdf0e10cSrcweir                                         else if ( eArgType == SC_ADDINARG_CALLER )
924cdf0e10cSrcweir                                             nCallerPos = nParamPos;
925cdf0e10cSrcweir                                         else
926cdf0e10cSrcweir                                             ++nVisibleCount;
927cdf0e10cSrcweir                                     }
928cdf0e10cSrcweir                                     if (bValid)
929cdf0e10cSrcweir                                     {
930cdf0e10cSrcweir                                         sal_uInt16 nCategory = lcl_GetCategory(
931cdf0e10cSrcweir                                             String(
932cdf0e10cSrcweir                                             xAddIn->getProgrammaticCategoryName(
933cdf0e10cSrcweir                                             aFuncU ) ) );
934cdf0e10cSrcweir 
935cdf0e10cSrcweir                                         rtl::OString sHelpId = aHelpIdGenerator.GetHelpId( aFuncU );
936cdf0e10cSrcweir 
937cdf0e10cSrcweir                                         rtl::OUString aLocalU;
938cdf0e10cSrcweir                                         try
939cdf0e10cSrcweir                                         {
940cdf0e10cSrcweir                                             aLocalU = xAddIn->
941cdf0e10cSrcweir                                                 getDisplayFunctionName( aFuncU );
942cdf0e10cSrcweir                                         }
943cdf0e10cSrcweir                                         catch(uno::Exception&)
944cdf0e10cSrcweir                                         {
945cdf0e10cSrcweir                                             aLocalU = rtl::OUString::createFromAscii( "###" );
946cdf0e10cSrcweir                                         }
947cdf0e10cSrcweir                                         String aLocalName = String( aLocalU );
948cdf0e10cSrcweir 
949cdf0e10cSrcweir                                         rtl::OUString aDescU;
950cdf0e10cSrcweir                                         try
951cdf0e10cSrcweir                                         {
952cdf0e10cSrcweir                                             aDescU = xAddIn->
953cdf0e10cSrcweir                                                 getFunctionDescription( aFuncU );
954cdf0e10cSrcweir                                         }
955cdf0e10cSrcweir                                         catch(uno::Exception&)
956cdf0e10cSrcweir                                         {
957cdf0e10cSrcweir                                             aDescU = rtl::OUString::createFromAscii( "###" );
958cdf0e10cSrcweir                                         }
959cdf0e10cSrcweir                                         String aDescription = String( aDescU );
960cdf0e10cSrcweir 
961cdf0e10cSrcweir                                         ScAddInArgDesc* pVisibleArgs = NULL;
962cdf0e10cSrcweir                                         if ( nVisibleCount > 0 )
963cdf0e10cSrcweir                                         {
964cdf0e10cSrcweir                                             ScAddInArgDesc aDesc;
965cdf0e10cSrcweir                                             pVisibleArgs = new ScAddInArgDesc[nVisibleCount];
966cdf0e10cSrcweir                                             long nDestPos = 0;
967cdf0e10cSrcweir                                             for (nParamPos=0; nParamPos<nParamCount; nParamPos++)
968cdf0e10cSrcweir                                             {
969cdf0e10cSrcweir                                                 uno::Reference<reflection::XIdlClass> xParClass =
970cdf0e10cSrcweir                                                     pParArr[nParamPos].aType;
971cdf0e10cSrcweir                                                 ScAddInArgumentType eArgType = lcl_GetArgType( xParClass );
972cdf0e10cSrcweir                                                 if ( eArgType != SC_ADDINARG_CALLER )
973cdf0e10cSrcweir                                                 {
974cdf0e10cSrcweir                                                     rtl::OUString aArgName;
975cdf0e10cSrcweir                                                     try
976cdf0e10cSrcweir                                                     {
977cdf0e10cSrcweir                                                         aArgName = xAddIn->
978cdf0e10cSrcweir                                                             getDisplayArgumentName( aFuncU, nParamPos );
979cdf0e10cSrcweir                                                     }
980cdf0e10cSrcweir                                                     catch(uno::Exception&)
981cdf0e10cSrcweir                                                     {
982cdf0e10cSrcweir                                                         aArgName = rtl::OUString::createFromAscii( "###" );
983cdf0e10cSrcweir                                                     }
984cdf0e10cSrcweir                                                     rtl::OUString aArgDesc;
985cdf0e10cSrcweir                                                     try
986cdf0e10cSrcweir                                                     {
987cdf0e10cSrcweir                                                         aArgDesc = xAddIn->
988cdf0e10cSrcweir                                                             getArgumentDescription( aFuncU, nParamPos );
989cdf0e10cSrcweir                                                     }
990cdf0e10cSrcweir                                                     catch(uno::Exception&)
991cdf0e10cSrcweir                                                     {
992cdf0e10cSrcweir                                                         aArgName = rtl::OUString::createFromAscii( "###" );
993cdf0e10cSrcweir                                                     }
994cdf0e10cSrcweir 
995cdf0e10cSrcweir                                                     sal_Bool bOptional =
996cdf0e10cSrcweir                                                         ( eArgType == SC_ADDINARG_VALUE_OR_ARRAY ||
997cdf0e10cSrcweir                                                           eArgType == SC_ADDINARG_VARARGS );
998cdf0e10cSrcweir 
999cdf0e10cSrcweir                                                     aDesc.eType = eArgType;
1000cdf0e10cSrcweir                                                     aDesc.aName = String( aArgName );
1001cdf0e10cSrcweir                                                     aDesc.aDescription = String( aArgDesc );
1002cdf0e10cSrcweir                                                     aDesc.bOptional = bOptional;
1003cdf0e10cSrcweir                                                     //! initialize aInternalName only from config?
1004cdf0e10cSrcweir                                                     aDesc.aInternalName = pParArr[nParamPos].aName;
1005cdf0e10cSrcweir 
1006cdf0e10cSrcweir                                                     pVisibleArgs[nDestPos++] = aDesc;
1007cdf0e10cSrcweir                                                 }
1008cdf0e10cSrcweir                                             }
1009cdf0e10cSrcweir                                             DBG_ASSERT( nDestPos==nVisibleCount, "wrong count" );
1010cdf0e10cSrcweir                                         }
1011cdf0e10cSrcweir 
1012cdf0e10cSrcweir                                         ppFuncData[nFuncPos+nOld] = new ScUnoAddInFuncData(
1013cdf0e10cSrcweir                                             aFuncName, aLocalName, aDescription,
1014cdf0e10cSrcweir                                             nCategory, sHelpId,
1015cdf0e10cSrcweir                                             xFunc, aObject,
1016cdf0e10cSrcweir                                             nVisibleCount, pVisibleArgs, nCallerPos );
1017cdf0e10cSrcweir 
1018cdf0e10cSrcweir                                         const ScUnoAddInFuncData* pData =
1019cdf0e10cSrcweir                                             ppFuncData[nFuncPos+nOld];
1020cdf0e10cSrcweir                                         pExactHashMap->insert(
1021cdf0e10cSrcweir                                                 ScAddInHashMap::value_type(
1022cdf0e10cSrcweir                                                     pData->GetOriginalName(),
1023cdf0e10cSrcweir                                                     pData ) );
1024cdf0e10cSrcweir                                         pNameHashMap->insert(
1025cdf0e10cSrcweir                                                 ScAddInHashMap::value_type(
1026cdf0e10cSrcweir                                                     pData->GetUpperName(),
1027cdf0e10cSrcweir                                                     pData ) );
1028cdf0e10cSrcweir                                         pLocalHashMap->insert(
1029cdf0e10cSrcweir                                                 ScAddInHashMap::value_type(
1030cdf0e10cSrcweir                                                     pData->GetUpperLocal(),
1031cdf0e10cSrcweir                                                     pData ) );
1032cdf0e10cSrcweir 
1033cdf0e10cSrcweir                                         delete[] pVisibleArgs;
1034cdf0e10cSrcweir                                     }
1035cdf0e10cSrcweir                                 }
1036cdf0e10cSrcweir                             }
1037cdf0e10cSrcweir                         }
1038cdf0e10cSrcweir                     }
1039cdf0e10cSrcweir                 }
1040cdf0e10cSrcweir             }
1041cdf0e10cSrcweir         }
1042cdf0e10cSrcweir     }
1043cdf0e10cSrcweir }
1044cdf0e10cSrcweir 
lcl_UpdateFunctionList(ScFunctionList & rFunctionList,const ScUnoAddInFuncData & rFuncData)1045cdf0e10cSrcweir void lcl_UpdateFunctionList( ScFunctionList& rFunctionList, const ScUnoAddInFuncData& rFuncData )
1046cdf0e10cSrcweir {
1047cdf0e10cSrcweir     String aCompare = rFuncData.GetUpperLocal();    // as used in FillFunctionDescFromData
1048cdf0e10cSrcweir 
1049cdf0e10cSrcweir     sal_uLong nCount = rFunctionList.GetCount();
1050cdf0e10cSrcweir     for (sal_uLong nPos=0; nPos<nCount; nPos++)
1051cdf0e10cSrcweir     {
1052cdf0e10cSrcweir         const ScFuncDesc* pDesc = rFunctionList.GetFunction( nPos );
1053cdf0e10cSrcweir         if ( pDesc && pDesc->pFuncName && *pDesc->pFuncName == aCompare )
1054cdf0e10cSrcweir         {
1055cdf0e10cSrcweir             ScUnoAddInCollection::FillFunctionDescFromData( rFuncData, *const_cast<ScFuncDesc*>(pDesc) );
1056cdf0e10cSrcweir             break;
1057cdf0e10cSrcweir         }
1058cdf0e10cSrcweir     }
1059cdf0e10cSrcweir }
1060cdf0e10cSrcweir 
lcl_FindArgDesc(const ScUnoAddInFuncData & rFuncData,const String & rArgIntName)1061cdf0e10cSrcweir const ScAddInArgDesc* lcl_FindArgDesc( const ScUnoAddInFuncData& rFuncData, const String& rArgIntName )
1062cdf0e10cSrcweir {
1063cdf0e10cSrcweir     long nArgCount = rFuncData.GetArgumentCount();
1064cdf0e10cSrcweir     const ScAddInArgDesc* pArguments = rFuncData.GetArguments();
1065cdf0e10cSrcweir     for (long nPos=0; nPos<nArgCount; nPos++)
1066cdf0e10cSrcweir     {
1067cdf0e10cSrcweir         if ( pArguments[nPos].aInternalName == rArgIntName )
1068cdf0e10cSrcweir             return &pArguments[nPos];
1069cdf0e10cSrcweir     }
1070cdf0e10cSrcweir     return NULL;
1071cdf0e10cSrcweir }
1072cdf0e10cSrcweir 
UpdateFromAddIn(const uno::Reference<uno::XInterface> & xInterface,const String & rServiceName)1073cdf0e10cSrcweir void ScUnoAddInCollection::UpdateFromAddIn( const uno::Reference<uno::XInterface>& xInterface,
1074cdf0e10cSrcweir                                             const String& rServiceName )
1075cdf0e10cSrcweir {
1076cdf0e10cSrcweir     uno::Reference<lang::XLocalizable> xLoc( xInterface, uno::UNO_QUERY );
1077cdf0e10cSrcweir     if ( xLoc.is() )        // optional in new add-ins
1078cdf0e10cSrcweir     {
1079cdf0e10cSrcweir         LanguageType eOfficeLang = Application::GetSettings().GetUILanguage();
1080cdf0e10cSrcweir         lang::Locale aLocale( MsLangId::convertLanguageToLocale( eOfficeLang ));
1081cdf0e10cSrcweir         xLoc->setLocale( aLocale );
1082cdf0e10cSrcweir     }
1083cdf0e10cSrcweir 
1084cdf0e10cSrcweir     // if function list was already initialized, it must be updated
1085cdf0e10cSrcweir 
1086cdf0e10cSrcweir     ScFunctionList* pFunctionList = NULL;
1087cdf0e10cSrcweir     if ( ScGlobal::HasStarCalcFunctionList() )
1088cdf0e10cSrcweir         pFunctionList = ScGlobal::GetStarCalcFunctionList();
1089cdf0e10cSrcweir 
1090cdf0e10cSrcweir     // only get the function information from Introspection
1091cdf0e10cSrcweir 
1092cdf0e10cSrcweir     uno::Reference<lang::XMultiServiceFactory> xManager = comphelper::getProcessServiceFactory();
1093cdf0e10cSrcweir     if ( xManager.is() )
1094cdf0e10cSrcweir     {
1095cdf0e10cSrcweir         uno::Reference<beans::XIntrospection> xIntro(
1096cdf0e10cSrcweir                                 xManager->createInstance(rtl::OUString::createFromAscii(
1097cdf0e10cSrcweir                                     "com.sun.star.beans.Introspection" )),
1098cdf0e10cSrcweir                                 uno::UNO_QUERY );
1099cdf0e10cSrcweir         if ( xIntro.is() )
1100cdf0e10cSrcweir         {
1101cdf0e10cSrcweir             uno::Any aObject;
1102cdf0e10cSrcweir             aObject <<= xInterface;
1103cdf0e10cSrcweir             uno::Reference<beans::XIntrospectionAccess> xAcc = xIntro->inspect(aObject);
1104cdf0e10cSrcweir             if (xAcc.is())
1105cdf0e10cSrcweir             {
1106cdf0e10cSrcweir                 uno::Sequence< uno::Reference<reflection::XIdlMethod> > aMethods =
1107cdf0e10cSrcweir                         xAcc->getMethods( beans::MethodConcept::ALL );
1108cdf0e10cSrcweir                 long nMethodCount = aMethods.getLength();
1109cdf0e10cSrcweir                 const uno::Reference<reflection::XIdlMethod>* pArray = aMethods.getConstArray();
1110cdf0e10cSrcweir                 for (long nFuncPos=0; nFuncPos<nMethodCount; nFuncPos++)
1111cdf0e10cSrcweir                 {
1112cdf0e10cSrcweir                     uno::Reference<reflection::XIdlMethod> xFunc = pArray[nFuncPos];
1113cdf0e10cSrcweir                     if (xFunc.is())
1114cdf0e10cSrcweir                     {
1115cdf0e10cSrcweir                         rtl::OUString aFuncU = xFunc->getName();
1116cdf0e10cSrcweir 
1117cdf0e10cSrcweir                         // stored function name: (service name).(function)
1118cdf0e10cSrcweir                         String aFuncName = rServiceName;
1119cdf0e10cSrcweir                         aFuncName += '.';
1120cdf0e10cSrcweir                         aFuncName += String( aFuncU );
1121cdf0e10cSrcweir 
1122cdf0e10cSrcweir                         // internal names are skipped because no FuncData exists
1123cdf0e10cSrcweir                         ScUnoAddInFuncData* pOldData = const_cast<ScUnoAddInFuncData*>( GetFuncData( aFuncName ) );
1124cdf0e10cSrcweir                         if ( pOldData )
1125cdf0e10cSrcweir                         {
1126cdf0e10cSrcweir                             // Create new (complete) argument info.
1127cdf0e10cSrcweir                             // As in ReadFromAddIn, the reflection information is authoritative.
1128cdf0e10cSrcweir                             // Local names and descriptions from pOldData are looked up using the
1129cdf0e10cSrcweir                             // internal argument name.
1130cdf0e10cSrcweir 
1131cdf0e10cSrcweir                             sal_Bool bValid = sal_True;
1132cdf0e10cSrcweir                             long nVisibleCount = 0;
1133cdf0e10cSrcweir                             long nCallerPos = SC_CALLERPOS_NONE;
1134cdf0e10cSrcweir 
1135cdf0e10cSrcweir                             uno::Sequence<reflection::ParamInfo> aParams =
1136cdf0e10cSrcweir                                     xFunc->getParameterInfos();
1137cdf0e10cSrcweir                             long nParamCount = aParams.getLength();
1138cdf0e10cSrcweir                             const reflection::ParamInfo* pParArr = aParams.getConstArray();
1139cdf0e10cSrcweir                             long nParamPos;
1140cdf0e10cSrcweir                             for (nParamPos=0; nParamPos<nParamCount; nParamPos++)
1141cdf0e10cSrcweir                             {
1142cdf0e10cSrcweir                                 if ( pParArr[nParamPos].aMode != reflection::ParamMode_IN )
1143cdf0e10cSrcweir                                     bValid = sal_False;
1144cdf0e10cSrcweir                                 uno::Reference<reflection::XIdlClass> xParClass =
1145cdf0e10cSrcweir                                             pParArr[nParamPos].aType;
1146cdf0e10cSrcweir                                 ScAddInArgumentType eArgType = lcl_GetArgType( xParClass );
1147cdf0e10cSrcweir                                 if ( eArgType == SC_ADDINARG_NONE )
1148cdf0e10cSrcweir                                     bValid = sal_False;
1149cdf0e10cSrcweir                                 else if ( eArgType == SC_ADDINARG_CALLER )
1150cdf0e10cSrcweir                                     nCallerPos = nParamPos;
1151cdf0e10cSrcweir                                 else
1152cdf0e10cSrcweir                                     ++nVisibleCount;
1153cdf0e10cSrcweir                             }
1154cdf0e10cSrcweir                             if (bValid)
1155cdf0e10cSrcweir                             {
1156cdf0e10cSrcweir                                 ScAddInArgDesc* pVisibleArgs = NULL;
1157cdf0e10cSrcweir                                 if ( nVisibleCount > 0 )
1158cdf0e10cSrcweir                                 {
1159cdf0e10cSrcweir                                     ScAddInArgDesc aDesc;
1160cdf0e10cSrcweir                                     pVisibleArgs = new ScAddInArgDesc[nVisibleCount];
1161cdf0e10cSrcweir                                     long nDestPos = 0;
1162cdf0e10cSrcweir                                     for (nParamPos=0; nParamPos<nParamCount; nParamPos++)
1163cdf0e10cSrcweir                                     {
1164cdf0e10cSrcweir                                         uno::Reference<reflection::XIdlClass> xParClass =
1165cdf0e10cSrcweir                                             pParArr[nParamPos].aType;
1166cdf0e10cSrcweir                                         ScAddInArgumentType eArgType = lcl_GetArgType( xParClass );
1167cdf0e10cSrcweir                                         if ( eArgType != SC_ADDINARG_CALLER )
1168cdf0e10cSrcweir                                         {
1169cdf0e10cSrcweir                                             const ScAddInArgDesc* pOldArgDesc =
1170cdf0e10cSrcweir                                                 lcl_FindArgDesc( *pOldData, pParArr[nParamPos].aName );
1171cdf0e10cSrcweir                                             if ( pOldArgDesc )
1172cdf0e10cSrcweir                                             {
1173cdf0e10cSrcweir                                                 aDesc.aName = pOldArgDesc->aName;
1174cdf0e10cSrcweir                                                 aDesc.aDescription = pOldArgDesc->aDescription;
1175cdf0e10cSrcweir                                             }
1176cdf0e10cSrcweir                                             else
1177cdf0e10cSrcweir                                                 aDesc.aName = aDesc.aDescription = String::CreateFromAscii( "###" );
1178cdf0e10cSrcweir 
1179cdf0e10cSrcweir                                             sal_Bool bOptional =
1180cdf0e10cSrcweir                                                 ( eArgType == SC_ADDINARG_VALUE_OR_ARRAY ||
1181cdf0e10cSrcweir                                                   eArgType == SC_ADDINARG_VARARGS );
1182cdf0e10cSrcweir 
1183cdf0e10cSrcweir                                             aDesc.eType = eArgType;
1184cdf0e10cSrcweir                                             aDesc.bOptional = bOptional;
1185cdf0e10cSrcweir                                             //! initialize aInternalName only from config?
1186cdf0e10cSrcweir                                             aDesc.aInternalName = pParArr[nParamPos].aName;
1187cdf0e10cSrcweir 
1188cdf0e10cSrcweir                                             pVisibleArgs[nDestPos++] = aDesc;
1189cdf0e10cSrcweir                                         }
1190cdf0e10cSrcweir                                     }
1191cdf0e10cSrcweir                                     DBG_ASSERT( nDestPos==nVisibleCount, "wrong count" );
1192cdf0e10cSrcweir                                 }
1193cdf0e10cSrcweir 
1194cdf0e10cSrcweir                                 pOldData->SetFunction( xFunc, aObject );
1195cdf0e10cSrcweir                                 pOldData->SetArguments( nVisibleCount, pVisibleArgs );
1196cdf0e10cSrcweir                                 pOldData->SetCallerPos( nCallerPos );
1197cdf0e10cSrcweir 
1198cdf0e10cSrcweir                                 if ( pFunctionList )
1199cdf0e10cSrcweir                                     lcl_UpdateFunctionList( *pFunctionList, *pOldData );
1200cdf0e10cSrcweir 
1201cdf0e10cSrcweir                                 delete[] pVisibleArgs;
1202cdf0e10cSrcweir                             }
1203cdf0e10cSrcweir                         }
1204cdf0e10cSrcweir                     }
1205cdf0e10cSrcweir                 }
1206cdf0e10cSrcweir             }
1207cdf0e10cSrcweir         }
1208cdf0e10cSrcweir     }
1209cdf0e10cSrcweir }
1210cdf0e10cSrcweir 
FindFunction(const String & rUpperName,sal_Bool bLocalFirst)1211cdf0e10cSrcweir String ScUnoAddInCollection::FindFunction( const String& rUpperName, sal_Bool bLocalFirst )
1212cdf0e10cSrcweir {
1213cdf0e10cSrcweir     if (!bInitialized)
1214cdf0e10cSrcweir         Initialize();
1215cdf0e10cSrcweir 
1216cdf0e10cSrcweir     if (nFuncCount == 0)
1217cdf0e10cSrcweir         return EMPTY_STRING;
1218cdf0e10cSrcweir 
1219cdf0e10cSrcweir     if ( bLocalFirst )
1220cdf0e10cSrcweir     {
1221cdf0e10cSrcweir         //  first scan all local names (used for entering formulas)
1222cdf0e10cSrcweir 
1223cdf0e10cSrcweir         ScAddInHashMap::const_iterator iLook( pLocalHashMap->find( rUpperName ) );
1224cdf0e10cSrcweir         if ( iLook != pLocalHashMap->end() )
1225cdf0e10cSrcweir             return iLook->second->GetOriginalName();
1226cdf0e10cSrcweir 
1227cdf0e10cSrcweir #if 0
1228cdf0e10cSrcweir         //  after that, scan international names (really?)
1229cdf0e10cSrcweir 
1230cdf0e10cSrcweir         iLook = pNameHashMap->find( rUpperName );
1231cdf0e10cSrcweir         if ( iLook != pNameHashMap->end() )
1232cdf0e10cSrcweir             return iLook->second->GetOriginalName();
1233cdf0e10cSrcweir #endif
1234cdf0e10cSrcweir     }
1235cdf0e10cSrcweir     else
1236cdf0e10cSrcweir     {
1237cdf0e10cSrcweir         //  first scan international names (used when calling a function)
1238cdf0e10cSrcweir         //! before that, check for exact match???
1239cdf0e10cSrcweir 
1240cdf0e10cSrcweir         ScAddInHashMap::const_iterator iLook( pNameHashMap->find( rUpperName ) );
1241cdf0e10cSrcweir         if ( iLook != pNameHashMap->end() )
1242cdf0e10cSrcweir             return iLook->second->GetOriginalName();
1243cdf0e10cSrcweir 
1244cdf0e10cSrcweir         //  after that, scan all local names (to allow replacing old AddIns with Uno)
1245cdf0e10cSrcweir 
1246cdf0e10cSrcweir         iLook = pLocalHashMap->find( rUpperName );
1247cdf0e10cSrcweir         if ( iLook != pLocalHashMap->end() )
1248cdf0e10cSrcweir             return iLook->second->GetOriginalName();
1249cdf0e10cSrcweir     }
1250cdf0e10cSrcweir 
1251cdf0e10cSrcweir     return EMPTY_STRING;
1252cdf0e10cSrcweir }
1253cdf0e10cSrcweir 
GetFuncData(const String & rName,bool bComplete)1254cdf0e10cSrcweir const ScUnoAddInFuncData* ScUnoAddInCollection::GetFuncData( const String& rName, bool bComplete )
1255cdf0e10cSrcweir {
1256cdf0e10cSrcweir     if (!bInitialized)
1257cdf0e10cSrcweir         Initialize();
1258cdf0e10cSrcweir 
1259cdf0e10cSrcweir     //  rName must be the exact internal name
1260cdf0e10cSrcweir 
1261cdf0e10cSrcweir     ScAddInHashMap::const_iterator iLook( pExactHashMap->find( rName ) );
1262cdf0e10cSrcweir     if ( iLook != pExactHashMap->end() )
1263cdf0e10cSrcweir     {
1264cdf0e10cSrcweir         const ScUnoAddInFuncData* pFuncData = iLook->second;
1265cdf0e10cSrcweir 
1266cdf0e10cSrcweir         if ( bComplete && !pFuncData->GetFunction().is() )           //! extra flag?
1267cdf0e10cSrcweir             LoadComponent( *pFuncData );
1268cdf0e10cSrcweir 
1269cdf0e10cSrcweir         return pFuncData;
1270cdf0e10cSrcweir     }
1271cdf0e10cSrcweir 
1272cdf0e10cSrcweir     return NULL;
1273cdf0e10cSrcweir }
1274cdf0e10cSrcweir 
GetFuncData(long nIndex)1275cdf0e10cSrcweir const ScUnoAddInFuncData* ScUnoAddInCollection::GetFuncData( long nIndex )
1276cdf0e10cSrcweir {
1277cdf0e10cSrcweir     if (!bInitialized)
1278cdf0e10cSrcweir         Initialize();
1279cdf0e10cSrcweir 
1280cdf0e10cSrcweir     if (nIndex < nFuncCount)
1281cdf0e10cSrcweir         return ppFuncData[nIndex];
1282cdf0e10cSrcweir     return NULL;
1283cdf0e10cSrcweir }
1284cdf0e10cSrcweir 
LocalizeString(String & rName)1285cdf0e10cSrcweir void ScUnoAddInCollection::LocalizeString( String& rName )
1286cdf0e10cSrcweir {
1287cdf0e10cSrcweir     if (!bInitialized)
1288cdf0e10cSrcweir         Initialize();
1289cdf0e10cSrcweir 
1290cdf0e10cSrcweir     //  modify rName - input: exact name
1291cdf0e10cSrcweir 
1292cdf0e10cSrcweir     ScAddInHashMap::const_iterator iLook( pExactHashMap->find( rName ) );
1293cdf0e10cSrcweir     if ( iLook != pExactHashMap->end() )
1294cdf0e10cSrcweir         rName = iLook->second->GetUpperLocal();         //! upper?
1295cdf0e10cSrcweir }
1296cdf0e10cSrcweir 
1297cdf0e10cSrcweir 
GetFuncCount()1298cdf0e10cSrcweir long ScUnoAddInCollection::GetFuncCount()
1299cdf0e10cSrcweir {
1300cdf0e10cSrcweir     if (!bInitialized)
1301cdf0e10cSrcweir         Initialize();
1302cdf0e10cSrcweir 
1303cdf0e10cSrcweir     return nFuncCount;
1304cdf0e10cSrcweir }
1305cdf0e10cSrcweir 
FillFunctionDesc(long nFunc,ScFuncDesc & rDesc)1306cdf0e10cSrcweir sal_Bool ScUnoAddInCollection::FillFunctionDesc( long nFunc, ScFuncDesc& rDesc )
1307cdf0e10cSrcweir {
1308cdf0e10cSrcweir     if (!bInitialized)
1309cdf0e10cSrcweir         Initialize();
1310cdf0e10cSrcweir 
1311cdf0e10cSrcweir     if (nFunc >= nFuncCount || !ppFuncData[nFunc])
1312cdf0e10cSrcweir         return sal_False;
1313cdf0e10cSrcweir 
1314cdf0e10cSrcweir     const ScUnoAddInFuncData& rFuncData = *ppFuncData[nFunc];
1315cdf0e10cSrcweir 
1316cdf0e10cSrcweir     return FillFunctionDescFromData( rFuncData, rDesc );
1317cdf0e10cSrcweir }
1318cdf0e10cSrcweir 
1319cdf0e10cSrcweir // static
FillFunctionDescFromData(const ScUnoAddInFuncData & rFuncData,ScFuncDesc & rDesc)1320cdf0e10cSrcweir sal_Bool ScUnoAddInCollection::FillFunctionDescFromData( const ScUnoAddInFuncData& rFuncData, ScFuncDesc& rDesc )
1321cdf0e10cSrcweir {
1322cdf0e10cSrcweir     rDesc.Clear();
1323cdf0e10cSrcweir 
1324cdf0e10cSrcweir     sal_Bool bIncomplete = !rFuncData.GetFunction().is();       //! extra flag?
1325cdf0e10cSrcweir 
1326cdf0e10cSrcweir     long nArgCount = rFuncData.GetArgumentCount();
1327cdf0e10cSrcweir     if ( nArgCount > USHRT_MAX )
1328cdf0e10cSrcweir         return sal_False;
1329cdf0e10cSrcweir 
1330cdf0e10cSrcweir     if ( bIncomplete )
1331cdf0e10cSrcweir         nArgCount = 0;      // if incomplete, fill without argument info (no wrong order)
1332cdf0e10cSrcweir 
1333cdf0e10cSrcweir     // nFIndex is set from outside
1334cdf0e10cSrcweir 
1335cdf0e10cSrcweir     rDesc.pFuncName = new String( rFuncData.GetUpperLocal() );     //! upper?
1336cdf0e10cSrcweir     rDesc.nCategory = rFuncData.GetCategory();
1337cdf0e10cSrcweir     rDesc.sHelpId = rFuncData.GetHelpId();
1338cdf0e10cSrcweir 
1339cdf0e10cSrcweir     String aDesc = rFuncData.GetDescription();
1340cdf0e10cSrcweir     if (!aDesc.Len())
1341cdf0e10cSrcweir         aDesc = rFuncData.GetLocalName();      // use name if no description is available
1342cdf0e10cSrcweir     rDesc.pFuncDesc = new String( aDesc );
1343cdf0e10cSrcweir 
1344cdf0e10cSrcweir     // AddInArgumentType_CALLER is already left out in FuncData
1345cdf0e10cSrcweir 
1346cdf0e10cSrcweir     rDesc.nArgCount = (sal_uInt16)nArgCount;
1347cdf0e10cSrcweir     if ( nArgCount )
1348cdf0e10cSrcweir     {
1349cdf0e10cSrcweir         sal_Bool bMultiple = sal_False;
1350cdf0e10cSrcweir         const ScAddInArgDesc* pArgs = rFuncData.GetArguments();
1351cdf0e10cSrcweir 
1352cdf0e10cSrcweir         rDesc.ppDefArgNames = new String*[nArgCount];
1353cdf0e10cSrcweir         rDesc.ppDefArgDescs = new String*[nArgCount];
1354cdf0e10cSrcweir         rDesc.pDefArgFlags   = new ScFuncDesc::ParameterFlags[nArgCount];
1355cdf0e10cSrcweir         for ( long nArg=0; nArg<nArgCount; nArg++ )
1356cdf0e10cSrcweir         {
1357cdf0e10cSrcweir             rDesc.ppDefArgNames[nArg] = new String( pArgs[nArg].aName );
1358cdf0e10cSrcweir             rDesc.ppDefArgDescs[nArg] = new String( pArgs[nArg].aDescription );
1359cdf0e10cSrcweir             rDesc.pDefArgFlags[nArg].bOptional = pArgs[nArg].bOptional;
1360cdf0e10cSrcweir             rDesc.pDefArgFlags[nArg].bSuppress = false;
1361cdf0e10cSrcweir 
1362cdf0e10cSrcweir             // no empty names...
1363cdf0e10cSrcweir             if ( rDesc.ppDefArgNames[nArg]->Len() == 0 )
1364cdf0e10cSrcweir             {
1365cdf0e10cSrcweir                 String aDefName( RTL_CONSTASCII_USTRINGPARAM("arg") );
1366cdf0e10cSrcweir                 aDefName += String::CreateFromInt32( nArg+1 );
1367cdf0e10cSrcweir                 *rDesc.ppDefArgNames[nArg] = aDefName;
1368cdf0e10cSrcweir             }
1369cdf0e10cSrcweir 
1370cdf0e10cSrcweir             //  last argument repeated?
1371cdf0e10cSrcweir             if ( nArg+1 == nArgCount && ( pArgs[nArg].eType == SC_ADDINARG_VARARGS ) )
1372cdf0e10cSrcweir                 bMultiple = sal_True;
1373cdf0e10cSrcweir         }
1374cdf0e10cSrcweir 
1375cdf0e10cSrcweir         if ( bMultiple )
1376cdf0e10cSrcweir             rDesc.nArgCount += VAR_ARGS - 1;    // VAR_ARGS means just one repeated arg
1377cdf0e10cSrcweir     }
1378cdf0e10cSrcweir 
1379cdf0e10cSrcweir     rDesc.bIncomplete = bIncomplete;
1380cdf0e10cSrcweir 
1381cdf0e10cSrcweir     return sal_True;
1382cdf0e10cSrcweir }
1383cdf0e10cSrcweir 
1384cdf0e10cSrcweir 
1385cdf0e10cSrcweir //------------------------------------------------------------------------
1386cdf0e10cSrcweir 
ScUnoAddInCall(ScUnoAddInCollection & rColl,const String & rName,long nParamCount)1387cdf0e10cSrcweir ScUnoAddInCall::ScUnoAddInCall( ScUnoAddInCollection& rColl, const String& rName,
1388cdf0e10cSrcweir                                 long nParamCount ) :
1389cdf0e10cSrcweir     bValidCount( sal_False ),
1390cdf0e10cSrcweir     nErrCode( errNoCode ),      // before function was called
1391cdf0e10cSrcweir     bHasString( sal_True ),
1392cdf0e10cSrcweir     fValue( 0.0 ),
1393cdf0e10cSrcweir     xMatrix( NULL )
1394cdf0e10cSrcweir {
1395cdf0e10cSrcweir     pFuncData = rColl.GetFuncData( rName, true );           // need fully initialized data
1396cdf0e10cSrcweir     DBG_ASSERT( pFuncData, "Function Data missing" );
1397cdf0e10cSrcweir     if ( pFuncData )
1398cdf0e10cSrcweir     {
1399cdf0e10cSrcweir         long nDescCount = pFuncData->GetArgumentCount();
1400cdf0e10cSrcweir         const ScAddInArgDesc* pArgs = pFuncData->GetArguments();
1401cdf0e10cSrcweir 
1402cdf0e10cSrcweir         //  is aVarArg sequence needed?
1403cdf0e10cSrcweir         if ( nParamCount >= nDescCount && nDescCount > 0 &&
1404cdf0e10cSrcweir              pArgs[nDescCount-1].eType == SC_ADDINARG_VARARGS )
1405cdf0e10cSrcweir         {
1406cdf0e10cSrcweir             long nVarCount = nParamCount - ( nDescCount - 1 );  // size of last argument
1407cdf0e10cSrcweir             aVarArg.realloc( nVarCount );
1408cdf0e10cSrcweir             bValidCount = sal_True;
1409cdf0e10cSrcweir         }
1410cdf0e10cSrcweir         else if ( nParamCount <= nDescCount )
1411cdf0e10cSrcweir         {
1412cdf0e10cSrcweir             //  all args behind nParamCount must be optional
1413cdf0e10cSrcweir             bValidCount = sal_True;
1414cdf0e10cSrcweir             for (long i=nParamCount; i<nDescCount; i++)
1415cdf0e10cSrcweir                 if ( !pArgs[i].bOptional )
1416cdf0e10cSrcweir                     bValidCount = sal_False;
1417cdf0e10cSrcweir         }
1418cdf0e10cSrcweir         // else invalid (too many arguments)
1419cdf0e10cSrcweir 
1420cdf0e10cSrcweir         if ( bValidCount )
1421cdf0e10cSrcweir             aArgs.realloc( nDescCount );    // sequence must always match function signature
1422cdf0e10cSrcweir     }
1423cdf0e10cSrcweir }
1424cdf0e10cSrcweir 
~ScUnoAddInCall()1425cdf0e10cSrcweir ScUnoAddInCall::~ScUnoAddInCall()
1426cdf0e10cSrcweir {
1427cdf0e10cSrcweir     // pFuncData is deleted with ScUnoAddInCollection
1428cdf0e10cSrcweir }
1429cdf0e10cSrcweir 
ValidParamCount()1430cdf0e10cSrcweir sal_Bool ScUnoAddInCall::ValidParamCount()
1431cdf0e10cSrcweir {
1432cdf0e10cSrcweir     return bValidCount;
1433cdf0e10cSrcweir }
1434cdf0e10cSrcweir 
GetArgType(long nPos)1435cdf0e10cSrcweir ScAddInArgumentType ScUnoAddInCall::GetArgType( long nPos )
1436cdf0e10cSrcweir {
1437cdf0e10cSrcweir     if ( pFuncData )
1438cdf0e10cSrcweir     {
1439cdf0e10cSrcweir         long nCount = pFuncData->GetArgumentCount();
1440cdf0e10cSrcweir         const ScAddInArgDesc* pArgs = pFuncData->GetArguments();
1441cdf0e10cSrcweir 
1442cdf0e10cSrcweir         // if last arg is sequence, use "any" type
1443cdf0e10cSrcweir         if ( nCount > 0 && nPos >= nCount-1 && pArgs[nCount-1].eType == SC_ADDINARG_VARARGS )
1444cdf0e10cSrcweir             return SC_ADDINARG_VALUE_OR_ARRAY;
1445cdf0e10cSrcweir 
1446cdf0e10cSrcweir         if ( nPos < nCount )
1447cdf0e10cSrcweir             return pArgs[nPos].eType;
1448cdf0e10cSrcweir     }
1449cdf0e10cSrcweir     return SC_ADDINARG_VALUE_OR_ARRAY;      //! error code !!!!
1450cdf0e10cSrcweir }
1451cdf0e10cSrcweir 
NeedsCaller() const1452cdf0e10cSrcweir sal_Bool ScUnoAddInCall::NeedsCaller() const
1453cdf0e10cSrcweir {
1454cdf0e10cSrcweir     return pFuncData && pFuncData->GetCallerPos() != SC_CALLERPOS_NONE;
1455cdf0e10cSrcweir }
1456cdf0e10cSrcweir 
SetCaller(const uno::Reference<uno::XInterface> & rInterface)1457cdf0e10cSrcweir void ScUnoAddInCall::SetCaller( const uno::Reference<uno::XInterface>& rInterface )
1458cdf0e10cSrcweir {
1459cdf0e10cSrcweir     xCaller = rInterface;
1460cdf0e10cSrcweir }
1461cdf0e10cSrcweir 
SetCallerFromObjectShell(SfxObjectShell * pObjSh)1462cdf0e10cSrcweir void ScUnoAddInCall::SetCallerFromObjectShell( SfxObjectShell* pObjSh )
1463cdf0e10cSrcweir {
1464cdf0e10cSrcweir     if (pObjSh)
1465cdf0e10cSrcweir     {
1466cdf0e10cSrcweir         uno::Reference<uno::XInterface> xInt( pObjSh->GetBaseModel(), uno::UNO_QUERY );
1467cdf0e10cSrcweir         SetCaller( xInt );
1468cdf0e10cSrcweir     }
1469cdf0e10cSrcweir }
1470cdf0e10cSrcweir 
SetParam(long nPos,const uno::Any & rValue)1471cdf0e10cSrcweir void ScUnoAddInCall::SetParam( long nPos, const uno::Any& rValue )
1472cdf0e10cSrcweir {
1473cdf0e10cSrcweir     if ( pFuncData )
1474cdf0e10cSrcweir     {
1475cdf0e10cSrcweir         long nCount = pFuncData->GetArgumentCount();
1476cdf0e10cSrcweir         const ScAddInArgDesc* pArgs = pFuncData->GetArguments();
1477cdf0e10cSrcweir         if ( nCount > 0 && nPos >= nCount-1 && pArgs[nCount-1].eType == SC_ADDINARG_VARARGS )
1478cdf0e10cSrcweir         {
1479cdf0e10cSrcweir             long nVarPos = nPos-(nCount-1);
1480cdf0e10cSrcweir             if ( nVarPos < aVarArg.getLength() )
1481cdf0e10cSrcweir                 aVarArg.getArray()[nVarPos] = rValue;
1482cdf0e10cSrcweir             else
1483cdf0e10cSrcweir             {
1484cdf0e10cSrcweir                 DBG_ERROR("wrong argument number");
1485cdf0e10cSrcweir             }
1486cdf0e10cSrcweir         }
1487cdf0e10cSrcweir         else if ( nPos < aArgs.getLength() )
1488cdf0e10cSrcweir             aArgs.getArray()[nPos] = rValue;
1489cdf0e10cSrcweir         else
1490cdf0e10cSrcweir         {
1491cdf0e10cSrcweir             DBG_ERROR("wrong argument number");
1492cdf0e10cSrcweir         }
1493cdf0e10cSrcweir     }
1494cdf0e10cSrcweir }
1495cdf0e10cSrcweir 
ExecuteCall()1496cdf0e10cSrcweir void ScUnoAddInCall::ExecuteCall()
1497cdf0e10cSrcweir {
1498cdf0e10cSrcweir     if ( !pFuncData )
1499cdf0e10cSrcweir         return;
1500cdf0e10cSrcweir 
1501cdf0e10cSrcweir     long nCount = pFuncData->GetArgumentCount();
1502cdf0e10cSrcweir     const ScAddInArgDesc* pArgs = pFuncData->GetArguments();
1503cdf0e10cSrcweir     if ( nCount > 0 && pArgs[nCount-1].eType == SC_ADDINARG_VARARGS )
1504cdf0e10cSrcweir     {
1505cdf0e10cSrcweir         //  insert aVarArg as last argument
1506cdf0e10cSrcweir         //! after inserting caller (to prevent copying twice)?
1507cdf0e10cSrcweir 
1508cdf0e10cSrcweir         DBG_ASSERT( aArgs.getLength() == nCount, "wrong argument count" );
1509cdf0e10cSrcweir         aArgs.getArray()[nCount-1] <<= aVarArg;
1510cdf0e10cSrcweir     }
1511cdf0e10cSrcweir 
1512cdf0e10cSrcweir     if ( pFuncData->GetCallerPos() != SC_CALLERPOS_NONE )
1513cdf0e10cSrcweir     {
1514cdf0e10cSrcweir         uno::Any aCallerAny;
1515cdf0e10cSrcweir         aCallerAny <<= xCaller;
1516cdf0e10cSrcweir 
1517cdf0e10cSrcweir         long nUserLen = aArgs.getLength();
1518cdf0e10cSrcweir         long nCallPos = pFuncData->GetCallerPos();
1519cdf0e10cSrcweir         if (nCallPos>nUserLen)                          // should not happen
1520cdf0e10cSrcweir         {
1521cdf0e10cSrcweir             DBG_ERROR("wrong CallPos");
1522cdf0e10cSrcweir             nCallPos = nUserLen;
1523cdf0e10cSrcweir         }
1524cdf0e10cSrcweir 
1525cdf0e10cSrcweir         long nDestLen = nUserLen + 1;
1526cdf0e10cSrcweir         uno::Sequence<uno::Any> aRealArgs( nDestLen );
1527cdf0e10cSrcweir         uno::Any* pDest = aRealArgs.getArray();
1528cdf0e10cSrcweir 
1529cdf0e10cSrcweir         const uno::Any* pSource = aArgs.getConstArray();
1530cdf0e10cSrcweir         long nSrcPos = 0;
1531cdf0e10cSrcweir 
1532cdf0e10cSrcweir         for ( long nDestPos = 0; nDestPos < nDestLen; nDestPos++ )
1533cdf0e10cSrcweir         {
1534cdf0e10cSrcweir             if ( nDestPos == nCallPos )
1535cdf0e10cSrcweir                 pDest[nDestPos] = aCallerAny;
1536cdf0e10cSrcweir             else
1537cdf0e10cSrcweir                 pDest[nDestPos] = pSource[nSrcPos++];
1538cdf0e10cSrcweir         }
1539cdf0e10cSrcweir 
1540cdf0e10cSrcweir         ExecuteCallWithArgs( aRealArgs );
1541cdf0e10cSrcweir     }
1542cdf0e10cSrcweir     else
1543cdf0e10cSrcweir         ExecuteCallWithArgs( aArgs );
1544cdf0e10cSrcweir }
1545cdf0e10cSrcweir 
ExecuteCallWithArgs(uno::Sequence<uno::Any> & rCallArgs)1546cdf0e10cSrcweir void ScUnoAddInCall::ExecuteCallWithArgs(uno::Sequence<uno::Any>& rCallArgs)
1547cdf0e10cSrcweir {
1548cdf0e10cSrcweir     //  rCallArgs may not match argument descriptions (because of caller)
1549cdf0e10cSrcweir 
1550cdf0e10cSrcweir     uno::Reference<reflection::XIdlMethod> xFunction;
1551cdf0e10cSrcweir     uno::Any aObject;
1552cdf0e10cSrcweir     if ( pFuncData )
1553cdf0e10cSrcweir     {
1554cdf0e10cSrcweir         xFunction = pFuncData->GetFunction();
1555cdf0e10cSrcweir         aObject = pFuncData->GetObject();
1556cdf0e10cSrcweir     }
1557cdf0e10cSrcweir 
1558cdf0e10cSrcweir     if ( xFunction.is() )
1559cdf0e10cSrcweir     {
1560cdf0e10cSrcweir         uno::Any aAny;
1561cdf0e10cSrcweir         nErrCode = 0;
1562cdf0e10cSrcweir 
1563cdf0e10cSrcweir         try
1564cdf0e10cSrcweir         {
1565cdf0e10cSrcweir             aAny = xFunction->invoke( aObject, rCallArgs );
1566cdf0e10cSrcweir         }
1567cdf0e10cSrcweir         catch(lang::IllegalArgumentException&)
1568cdf0e10cSrcweir         {
1569cdf0e10cSrcweir             nErrCode = errIllegalArgument;
1570cdf0e10cSrcweir         }
1571cdf0e10cSrcweir #if 0
1572cdf0e10cSrcweir         catch(FloatingPointException&)
1573cdf0e10cSrcweir         {
1574cdf0e10cSrcweir             nErrCode = errIllegalFPOperation;
1575cdf0e10cSrcweir         }
1576cdf0e10cSrcweir #endif
1577cdf0e10cSrcweir 		catch(reflection::InvocationTargetException& rWrapped)
1578cdf0e10cSrcweir 		{
1579cdf0e10cSrcweir 			if ( rWrapped.TargetException.getValueType().equals(
1580cdf0e10cSrcweir 					getCppuType( (lang::IllegalArgumentException*)0 ) ) )
1581cdf0e10cSrcweir 				nErrCode = errIllegalArgument;
1582cdf0e10cSrcweir             else if ( rWrapped.TargetException.getValueType().equals(
1583cdf0e10cSrcweir                     getCppuType( (sheet::NoConvergenceException*)0 ) ) )
1584cdf0e10cSrcweir                 nErrCode = errNoConvergence;
1585cdf0e10cSrcweir 			else
1586cdf0e10cSrcweir 	            nErrCode = errNoValue;
1587cdf0e10cSrcweir 		}
1588cdf0e10cSrcweir 
1589cdf0e10cSrcweir         catch(uno::Exception&)
1590cdf0e10cSrcweir         {
1591cdf0e10cSrcweir             nErrCode = errNoValue;
1592cdf0e10cSrcweir         }
1593cdf0e10cSrcweir 
1594cdf0e10cSrcweir         if (!nErrCode)
1595cdf0e10cSrcweir             SetResult( aAny );      // convert result to Calc types
1596cdf0e10cSrcweir     }
1597cdf0e10cSrcweir }
1598cdf0e10cSrcweir 
SetResult(const uno::Any & rNewRes)1599cdf0e10cSrcweir void ScUnoAddInCall::SetResult( const uno::Any& rNewRes )
1600cdf0e10cSrcweir {
1601cdf0e10cSrcweir     nErrCode = 0;
1602cdf0e10cSrcweir     xVarRes = NULL;
1603cdf0e10cSrcweir 
1604cdf0e10cSrcweir     // Reflection* pRefl = rNewRes.getReflection();
1605cdf0e10cSrcweir 
1606cdf0e10cSrcweir     uno::TypeClass eClass = rNewRes.getValueTypeClass();
1607cdf0e10cSrcweir     uno::Type aType = rNewRes.getValueType();
1608cdf0e10cSrcweir     switch (eClass)
1609cdf0e10cSrcweir     {
1610cdf0e10cSrcweir         case uno::TypeClass_VOID:
1611cdf0e10cSrcweir             nErrCode = NOTAVAILABLE;         // #NA
1612cdf0e10cSrcweir             break;
1613cdf0e10cSrcweir 
1614cdf0e10cSrcweir         case uno::TypeClass_ENUM:
1615cdf0e10cSrcweir         case uno::TypeClass_BOOLEAN:
1616cdf0e10cSrcweir         case uno::TypeClass_CHAR:
1617cdf0e10cSrcweir         case uno::TypeClass_BYTE:
1618cdf0e10cSrcweir         case uno::TypeClass_SHORT:
1619cdf0e10cSrcweir         case uno::TypeClass_UNSIGNED_SHORT:
1620cdf0e10cSrcweir         case uno::TypeClass_LONG:
1621cdf0e10cSrcweir         case uno::TypeClass_UNSIGNED_LONG:
1622cdf0e10cSrcweir         case uno::TypeClass_FLOAT:
1623cdf0e10cSrcweir         case uno::TypeClass_DOUBLE:
1624cdf0e10cSrcweir             {
1625cdf0e10cSrcweir                 uno::TypeClass eMyClass;
1626cdf0e10cSrcweir                 ScApiTypeConversion::ConvertAnyToDouble( fValue, eMyClass, rNewRes);
1627cdf0e10cSrcweir                 bHasString = sal_False;
1628cdf0e10cSrcweir             }
1629cdf0e10cSrcweir             break;
1630cdf0e10cSrcweir 
1631cdf0e10cSrcweir         case uno::TypeClass_STRING:
1632cdf0e10cSrcweir             {
1633cdf0e10cSrcweir                 rtl::OUString aUStr;
1634cdf0e10cSrcweir                 rNewRes >>= aUStr;
1635cdf0e10cSrcweir                 aString = String( aUStr );
1636cdf0e10cSrcweir                 bHasString = sal_True;
1637cdf0e10cSrcweir             }
1638cdf0e10cSrcweir             break;
1639cdf0e10cSrcweir 
1640cdf0e10cSrcweir         case uno::TypeClass_INTERFACE:
1641cdf0e10cSrcweir             {
1642cdf0e10cSrcweir                 //! directly extract XVolatileResult from any?
1643cdf0e10cSrcweir                 uno::Reference<uno::XInterface> xInterface;
1644cdf0e10cSrcweir                 rNewRes >>= xInterface;
1645cdf0e10cSrcweir                 if ( xInterface.is() )
1646cdf0e10cSrcweir                     xVarRes = uno::Reference<sheet::XVolatileResult>( xInterface, uno::UNO_QUERY );
1647cdf0e10cSrcweir 
1648cdf0e10cSrcweir                 if (!xVarRes.is())
1649cdf0e10cSrcweir                     nErrCode = errNoValue;          // unknown interface
1650cdf0e10cSrcweir             }
1651cdf0e10cSrcweir             break;
1652cdf0e10cSrcweir 
1653cdf0e10cSrcweir         default:
1654cdf0e10cSrcweir             if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<sal_Int32> > *)0 ) ) )
1655cdf0e10cSrcweir             {
1656cdf0e10cSrcweir                 const uno::Sequence< uno::Sequence<sal_Int32> >* pRowSeq = NULL;
1657cdf0e10cSrcweir 
1658cdf0e10cSrcweir                 //! use pointer from any!
1659cdf0e10cSrcweir                 uno::Sequence< uno::Sequence<sal_Int32> > aSequence;
1660cdf0e10cSrcweir                 if ( rNewRes >>= aSequence )
1661cdf0e10cSrcweir                     pRowSeq = &aSequence;
1662cdf0e10cSrcweir 
1663cdf0e10cSrcweir                 if ( pRowSeq )
1664cdf0e10cSrcweir                 {
1665cdf0e10cSrcweir                     long nRowCount = pRowSeq->getLength();
1666cdf0e10cSrcweir                     const uno::Sequence<sal_Int32>* pRowArr = pRowSeq->getConstArray();
1667cdf0e10cSrcweir                     long nMaxColCount = 0;
1668cdf0e10cSrcweir                     long nCol, nRow;
1669cdf0e10cSrcweir                     for (nRow=0; nRow<nRowCount; nRow++)
1670cdf0e10cSrcweir                     {
1671cdf0e10cSrcweir                         long nTmp = pRowArr[nRow].getLength();
1672cdf0e10cSrcweir                         if ( nTmp > nMaxColCount )
1673cdf0e10cSrcweir                             nMaxColCount = nTmp;
1674cdf0e10cSrcweir                     }
1675cdf0e10cSrcweir                     if ( nMaxColCount && nRowCount )
1676cdf0e10cSrcweir                     {
1677cdf0e10cSrcweir                         xMatrix = new ScMatrix(
1678cdf0e10cSrcweir                                 static_cast<SCSIZE>(nMaxColCount),
1679cdf0e10cSrcweir                                 static_cast<SCSIZE>(nRowCount) );
1680cdf0e10cSrcweir                         ScMatrix* pMatrix = xMatrix;
1681cdf0e10cSrcweir                         for (nRow=0; nRow<nRowCount; nRow++)
1682cdf0e10cSrcweir                         {
1683cdf0e10cSrcweir                             long nColCount = pRowArr[nRow].getLength();
1684cdf0e10cSrcweir                             const sal_Int32* pColArr = pRowArr[nRow].getConstArray();
1685cdf0e10cSrcweir                             for (nCol=0; nCol<nColCount; nCol++)
1686cdf0e10cSrcweir                                 pMatrix->PutDouble( pColArr[nCol],
1687cdf0e10cSrcweir                                         static_cast<SCSIZE>(nCol),
1688cdf0e10cSrcweir                                         static_cast<SCSIZE>(nRow) );
1689cdf0e10cSrcweir                             for (nCol=nColCount; nCol<nMaxColCount; nCol++)
1690cdf0e10cSrcweir                                 pMatrix->PutDouble( 0.0,
1691cdf0e10cSrcweir                                         static_cast<SCSIZE>(nCol),
1692cdf0e10cSrcweir                                         static_cast<SCSIZE>(nRow) );
1693cdf0e10cSrcweir                         }
1694cdf0e10cSrcweir                     }
1695cdf0e10cSrcweir                 }
1696cdf0e10cSrcweir             }
1697cdf0e10cSrcweir             else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<double> > *)0 ) ) )
1698cdf0e10cSrcweir             {
1699cdf0e10cSrcweir                 const uno::Sequence< uno::Sequence<double> >* pRowSeq = NULL;
1700cdf0e10cSrcweir 
1701cdf0e10cSrcweir                 //! use pointer from any!
1702cdf0e10cSrcweir                 uno::Sequence< uno::Sequence<double> > aSequence;
1703cdf0e10cSrcweir                 if ( rNewRes >>= aSequence )
1704cdf0e10cSrcweir                     pRowSeq = &aSequence;
1705cdf0e10cSrcweir 
1706cdf0e10cSrcweir                 if ( pRowSeq )
1707cdf0e10cSrcweir                 {
1708cdf0e10cSrcweir                     long nRowCount = pRowSeq->getLength();
1709cdf0e10cSrcweir                     const uno::Sequence<double>* pRowArr = pRowSeq->getConstArray();
1710cdf0e10cSrcweir                     long nMaxColCount = 0;
1711cdf0e10cSrcweir                     long nCol, nRow;
1712cdf0e10cSrcweir                     for (nRow=0; nRow<nRowCount; nRow++)
1713cdf0e10cSrcweir                     {
1714cdf0e10cSrcweir                         long nTmp = pRowArr[nRow].getLength();
1715cdf0e10cSrcweir                         if ( nTmp > nMaxColCount )
1716cdf0e10cSrcweir                             nMaxColCount = nTmp;
1717cdf0e10cSrcweir                     }
1718cdf0e10cSrcweir                     if ( nMaxColCount && nRowCount )
1719cdf0e10cSrcweir                     {
1720cdf0e10cSrcweir                         xMatrix = new ScMatrix(
1721cdf0e10cSrcweir                                 static_cast<SCSIZE>(nMaxColCount),
1722cdf0e10cSrcweir                                 static_cast<SCSIZE>(nRowCount) );
1723cdf0e10cSrcweir                         ScMatrix* pMatrix = xMatrix;
1724cdf0e10cSrcweir                         for (nRow=0; nRow<nRowCount; nRow++)
1725cdf0e10cSrcweir                         {
1726cdf0e10cSrcweir                             long nColCount = pRowArr[nRow].getLength();
1727cdf0e10cSrcweir                             const double* pColArr = pRowArr[nRow].getConstArray();
1728cdf0e10cSrcweir                             for (nCol=0; nCol<nColCount; nCol++)
1729cdf0e10cSrcweir                                 pMatrix->PutDouble( pColArr[nCol],
1730cdf0e10cSrcweir                                         static_cast<SCSIZE>(nCol),
1731cdf0e10cSrcweir                                         static_cast<SCSIZE>(nRow) );
1732cdf0e10cSrcweir                             for (nCol=nColCount; nCol<nMaxColCount; nCol++)
1733cdf0e10cSrcweir                                 pMatrix->PutDouble( 0.0,
1734cdf0e10cSrcweir                                         static_cast<SCSIZE>(nCol),
1735cdf0e10cSrcweir                                         static_cast<SCSIZE>(nRow) );
1736cdf0e10cSrcweir                         }
1737cdf0e10cSrcweir                     }
1738cdf0e10cSrcweir                 }
1739cdf0e10cSrcweir             }
1740cdf0e10cSrcweir             else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<rtl::OUString> > *)0 ) ) )
1741cdf0e10cSrcweir             {
1742cdf0e10cSrcweir                 const uno::Sequence< uno::Sequence<rtl::OUString> >* pRowSeq = NULL;
1743cdf0e10cSrcweir 
1744cdf0e10cSrcweir                 //! use pointer from any!
1745cdf0e10cSrcweir                 uno::Sequence< uno::Sequence<rtl::OUString> > aSequence;
1746cdf0e10cSrcweir                 if ( rNewRes >>= aSequence )
1747cdf0e10cSrcweir                     pRowSeq = &aSequence;
1748cdf0e10cSrcweir 
1749cdf0e10cSrcweir                 if ( pRowSeq )
1750cdf0e10cSrcweir                 {
1751cdf0e10cSrcweir                     long nRowCount = pRowSeq->getLength();
1752cdf0e10cSrcweir                     const uno::Sequence<rtl::OUString>* pRowArr = pRowSeq->getConstArray();
1753cdf0e10cSrcweir                     long nMaxColCount = 0;
1754cdf0e10cSrcweir                     long nCol, nRow;
1755cdf0e10cSrcweir                     for (nRow=0; nRow<nRowCount; nRow++)
1756cdf0e10cSrcweir                     {
1757cdf0e10cSrcweir                         long nTmp = pRowArr[nRow].getLength();
1758cdf0e10cSrcweir                         if ( nTmp > nMaxColCount )
1759cdf0e10cSrcweir                             nMaxColCount = nTmp;
1760cdf0e10cSrcweir                     }
1761cdf0e10cSrcweir                     if ( nMaxColCount && nRowCount )
1762cdf0e10cSrcweir                     {
1763cdf0e10cSrcweir                         xMatrix = new ScMatrix(
1764cdf0e10cSrcweir                                 static_cast<SCSIZE>(nMaxColCount),
1765cdf0e10cSrcweir                                 static_cast<SCSIZE>(nRowCount) );
1766cdf0e10cSrcweir                         ScMatrix* pMatrix = xMatrix;
1767cdf0e10cSrcweir                         for (nRow=0; nRow<nRowCount; nRow++)
1768cdf0e10cSrcweir                         {
1769cdf0e10cSrcweir                             long nColCount = pRowArr[nRow].getLength();
1770cdf0e10cSrcweir                             const rtl::OUString* pColArr = pRowArr[nRow].getConstArray();
1771cdf0e10cSrcweir                             for (nCol=0; nCol<nColCount; nCol++)
1772cdf0e10cSrcweir                                 pMatrix->PutString( String( pColArr[nCol] ),
1773cdf0e10cSrcweir                                     static_cast<SCSIZE>(nCol),
1774cdf0e10cSrcweir                                     static_cast<SCSIZE>(nRow) );
1775cdf0e10cSrcweir                             for (nCol=nColCount; nCol<nMaxColCount; nCol++)
1776cdf0e10cSrcweir                                 pMatrix->PutString( EMPTY_STRING,
1777cdf0e10cSrcweir                                         static_cast<SCSIZE>(nCol),
1778cdf0e10cSrcweir                                         static_cast<SCSIZE>(nRow) );
1779cdf0e10cSrcweir                         }
1780cdf0e10cSrcweir                     }
1781cdf0e10cSrcweir                 }
1782cdf0e10cSrcweir             }
1783cdf0e10cSrcweir             else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<uno::Any> > *)0 ) ) )
1784cdf0e10cSrcweir             {
1785cdf0e10cSrcweir                 xMatrix = ScSequenceToMatrix::CreateMixedMatrix( rNewRes );
1786cdf0e10cSrcweir             }
1787cdf0e10cSrcweir 
1788cdf0e10cSrcweir             if (!xMatrix)                       // no array found
1789cdf0e10cSrcweir                 nErrCode = errNoValue;          //! code for error in return type???
1790cdf0e10cSrcweir     }
1791cdf0e10cSrcweir }
1792cdf0e10cSrcweir 
1793cdf0e10cSrcweir 
1794cdf0e10cSrcweir 
1795cdf0e10cSrcweir //------------------------------------------------------------------------
1796cdf0e10cSrcweir 
1797cdf0e10cSrcweir 
1798cdf0e10cSrcweir 
1799