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 }
756cdf0e10cSrcweir
lcl_GetArgType(const uno::Reference<reflection::XIdlClass> & xClass)757cdf0e10cSrcweir ScAddInArgumentType lcl_GetArgType( const uno::Reference<reflection::XIdlClass>& xClass )
758cdf0e10cSrcweir {
759cdf0e10cSrcweir if (!xClass.is())
760cdf0e10cSrcweir return SC_ADDINARG_NONE;
761cdf0e10cSrcweir
762cdf0e10cSrcweir uno::TypeClass eType = xClass->getTypeClass();
763cdf0e10cSrcweir
764cdf0e10cSrcweir if ( eType == uno::TypeClass_LONG ) //! other integer types?
765cdf0e10cSrcweir return SC_ADDINARG_INTEGER;
766cdf0e10cSrcweir
767cdf0e10cSrcweir if ( eType == uno::TypeClass_DOUBLE )
768cdf0e10cSrcweir return SC_ADDINARG_DOUBLE;
769cdf0e10cSrcweir
770cdf0e10cSrcweir if ( eType == uno::TypeClass_STRING )
771cdf0e10cSrcweir return SC_ADDINARG_STRING;
772cdf0e10cSrcweir
773cdf0e10cSrcweir //! XIdlClass needs getType() method!
774cdf0e10cSrcweir rtl::OUString sName = xClass->getName();
775cdf0e10cSrcweir
776cdf0e10cSrcweir if (IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<sal_Int32> >*)0) ))
777cdf0e10cSrcweir return SC_ADDINARG_INTEGER_ARRAY;
778cdf0e10cSrcweir
779cdf0e10cSrcweir if (IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<double> >*)0) ))
780cdf0e10cSrcweir return SC_ADDINARG_DOUBLE_ARRAY;
781cdf0e10cSrcweir
782cdf0e10cSrcweir if (IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<rtl::OUString> >*)0) ))
783cdf0e10cSrcweir return SC_ADDINARG_STRING_ARRAY;
784cdf0e10cSrcweir
785cdf0e10cSrcweir if (IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<uno::Any> >*)0) ))
786cdf0e10cSrcweir return SC_ADDINARG_MIXED_ARRAY;
787cdf0e10cSrcweir
788cdf0e10cSrcweir if (IsTypeName( sName, getCppuType((uno::Any*)0) ))
789cdf0e10cSrcweir return SC_ADDINARG_VALUE_OR_ARRAY;
790cdf0e10cSrcweir
791cdf0e10cSrcweir if (IsTypeName( sName, getCppuType((uno::Reference<table::XCellRange>*)0) ))
792cdf0e10cSrcweir return SC_ADDINARG_CELLRANGE;
793cdf0e10cSrcweir
794cdf0e10cSrcweir if (IsTypeName( sName, getCppuType((uno::Reference<beans::XPropertySet>*)0) ))
795cdf0e10cSrcweir return SC_ADDINARG_CALLER;
796cdf0e10cSrcweir
797cdf0e10cSrcweir if (IsTypeName( sName, getCppuType((uno::Sequence<uno::Any>*)0) ))
798cdf0e10cSrcweir return SC_ADDINARG_VARARGS;
799cdf0e10cSrcweir
800cdf0e10cSrcweir return SC_ADDINARG_NONE;
801cdf0e10cSrcweir }
802cdf0e10cSrcweir
ReadFromAddIn(const uno::Reference<uno::XInterface> & xInterface)803cdf0e10cSrcweir void ScUnoAddInCollection::ReadFromAddIn( const uno::Reference<uno::XInterface>& xInterface )
804cdf0e10cSrcweir {
805cdf0e10cSrcweir uno::Reference<sheet::XAddIn> xAddIn( xInterface, uno::UNO_QUERY );
806cdf0e10cSrcweir uno::Reference<lang::XServiceName> xName( xInterface, uno::UNO_QUERY );
807cdf0e10cSrcweir if ( xAddIn.is() && xName.is() )
808cdf0e10cSrcweir {
809cdf0e10cSrcweir // AddIns must use the language for which the office is installed
810cdf0e10cSrcweir LanguageType eOfficeLang = Application::GetSettings().GetUILanguage();
811cdf0e10cSrcweir
812cdf0e10cSrcweir lang::Locale aLocale( MsLangId::convertLanguageToLocale( eOfficeLang ));
813cdf0e10cSrcweir xAddIn->setLocale( aLocale );
814cdf0e10cSrcweir
815cdf0e10cSrcweir String aServiceName = String( xName->getServiceName() );
816cdf0e10cSrcweir ScUnoAddInHelpIdGenerator aHelpIdGenerator( xName->getServiceName() );
817cdf0e10cSrcweir
818cdf0e10cSrcweir //! pass XIntrospection to ReadFromAddIn
819cdf0e10cSrcweir
820cdf0e10cSrcweir uno::Reference<lang::XMultiServiceFactory> xManager = comphelper::getProcessServiceFactory();
821cdf0e10cSrcweir if ( xManager.is() )
822cdf0e10cSrcweir {
823cdf0e10cSrcweir uno::Reference<beans::XIntrospection> xIntro(
824cdf0e10cSrcweir xManager->createInstance(rtl::OUString::createFromAscii(
825cdf0e10cSrcweir "com.sun.star.beans.Introspection" )),
826cdf0e10cSrcweir uno::UNO_QUERY );
827cdf0e10cSrcweir if ( xIntro.is() )
828cdf0e10cSrcweir {
829cdf0e10cSrcweir uno::Any aObject;
830cdf0e10cSrcweir aObject <<= xAddIn;
831cdf0e10cSrcweir uno::Reference<beans::XIntrospectionAccess> xAcc = xIntro->inspect(aObject);
832cdf0e10cSrcweir if (xAcc.is())
833cdf0e10cSrcweir {
834cdf0e10cSrcweir uno::Sequence< uno::Reference<reflection::XIdlMethod> > aMethods =
835cdf0e10cSrcweir xAcc->getMethods( beans::MethodConcept::ALL );
836cdf0e10cSrcweir long nNewCount = aMethods.getLength();
837cdf0e10cSrcweir if ( nNewCount )
838cdf0e10cSrcweir {
839cdf0e10cSrcweir long nOld = nFuncCount;
840cdf0e10cSrcweir nFuncCount = nNewCount+nOld;
841cdf0e10cSrcweir if ( nOld )
842cdf0e10cSrcweir {
843cdf0e10cSrcweir ScUnoAddInFuncData** ppNew = new ScUnoAddInFuncData*[nFuncCount];
844cdf0e10cSrcweir for (long i=0; i<nOld; i++)
845cdf0e10cSrcweir ppNew[i] = ppFuncData[i];
846cdf0e10cSrcweir delete[] ppFuncData;
847cdf0e10cSrcweir ppFuncData = ppNew;
848cdf0e10cSrcweir }
849cdf0e10cSrcweir else
850cdf0e10cSrcweir ppFuncData = new ScUnoAddInFuncData*[nFuncCount];
851cdf0e10cSrcweir
852cdf0e10cSrcweir //! TODO: adjust bucket count?
853cdf0e10cSrcweir if ( !pExactHashMap )
854cdf0e10cSrcweir pExactHashMap = new ScAddInHashMap;
855cdf0e10cSrcweir if ( !pNameHashMap )
856cdf0e10cSrcweir pNameHashMap = new ScAddInHashMap;
857cdf0e10cSrcweir if ( !pLocalHashMap )
858cdf0e10cSrcweir pLocalHashMap = new ScAddInHashMap;
859cdf0e10cSrcweir
860cdf0e10cSrcweir const uno::Reference<reflection::XIdlMethod>* pArray = aMethods.getConstArray();
861cdf0e10cSrcweir for (long nFuncPos=0; nFuncPos<nNewCount; nFuncPos++)
862cdf0e10cSrcweir {
863cdf0e10cSrcweir ppFuncData[nFuncPos+nOld] = NULL;
864cdf0e10cSrcweir
865cdf0e10cSrcweir uno::Reference<reflection::XIdlMethod> xFunc = pArray[nFuncPos];
866cdf0e10cSrcweir if (xFunc.is())
867cdf0e10cSrcweir {
868cdf0e10cSrcweir // leave out internal functions
869cdf0e10cSrcweir uno::Reference<reflection::XIdlClass> xClass =
870cdf0e10cSrcweir xFunc->getDeclaringClass();
871cdf0e10cSrcweir sal_Bool bSkip = sal_True;
872cdf0e10cSrcweir if ( xClass.is() )
873cdf0e10cSrcweir {
874cdf0e10cSrcweir //! XIdlClass needs getType() method!
875cdf0e10cSrcweir rtl::OUString sName = xClass->getName();
876cdf0e10cSrcweir bSkip = (
877cdf0e10cSrcweir IsTypeName( sName,
878cdf0e10cSrcweir getCppuType((uno::Reference<uno::XInterface>*)0) ) ||
879cdf0e10cSrcweir IsTypeName( sName,
880cdf0e10cSrcweir getCppuType((uno::Reference<reflection::XIdlClassProvider>*)0) ) ||
881cdf0e10cSrcweir IsTypeName( sName,
882cdf0e10cSrcweir getCppuType((uno::Reference<lang::XServiceName>*)0) ) ||
883cdf0e10cSrcweir IsTypeName( sName,
884cdf0e10cSrcweir getCppuType((uno::Reference<lang::XServiceInfo>*)0) ) ||
885cdf0e10cSrcweir IsTypeName( sName,
886cdf0e10cSrcweir getCppuType((uno::Reference<sheet::XAddIn>*)0) ) );
887cdf0e10cSrcweir }
888cdf0e10cSrcweir if (!bSkip)
889cdf0e10cSrcweir {
890cdf0e10cSrcweir uno::Reference<reflection::XIdlClass> xReturn =
891cdf0e10cSrcweir xFunc->getReturnType();
892cdf0e10cSrcweir if ( !lcl_ValidReturnType( xReturn ) )
893cdf0e10cSrcweir bSkip = sal_True;
894cdf0e10cSrcweir }
895cdf0e10cSrcweir if (!bSkip)
896cdf0e10cSrcweir {
897cdf0e10cSrcweir rtl::OUString aFuncU = xFunc->getName();
898cdf0e10cSrcweir
899cdf0e10cSrcweir // stored function name: (service name).(function)
900cdf0e10cSrcweir String aFuncName = aServiceName;
901cdf0e10cSrcweir aFuncName += '.';
902cdf0e10cSrcweir aFuncName += String( aFuncU );
903cdf0e10cSrcweir
904cdf0e10cSrcweir sal_Bool bValid = sal_True;
905cdf0e10cSrcweir long nVisibleCount = 0;
906cdf0e10cSrcweir long nCallerPos = SC_CALLERPOS_NONE;
907cdf0e10cSrcweir
908cdf0e10cSrcweir uno::Sequence<reflection::ParamInfo> aParams =
909cdf0e10cSrcweir xFunc->getParameterInfos();
910cdf0e10cSrcweir long nParamCount = aParams.getLength();
911cdf0e10cSrcweir const reflection::ParamInfo* pParArr = aParams.getConstArray();
912cdf0e10cSrcweir long nParamPos;
913cdf0e10cSrcweir for (nParamPos=0; nParamPos<nParamCount; nParamPos++)
914cdf0e10cSrcweir {
915cdf0e10cSrcweir if ( pParArr[nParamPos].aMode != reflection::ParamMode_IN )
916cdf0e10cSrcweir bValid = sal_False;
917cdf0e10cSrcweir uno::Reference<reflection::XIdlClass> xParClass =
918cdf0e10cSrcweir pParArr[nParamPos].aType;
919cdf0e10cSrcweir ScAddInArgumentType eArgType = lcl_GetArgType( xParClass );
920cdf0e10cSrcweir if ( eArgType == SC_ADDINARG_NONE )
921cdf0e10cSrcweir bValid = sal_False;
922cdf0e10cSrcweir else if ( eArgType == SC_ADDINARG_CALLER )
923cdf0e10cSrcweir nCallerPos = nParamPos;
924cdf0e10cSrcweir else
925cdf0e10cSrcweir ++nVisibleCount;
926cdf0e10cSrcweir }
927cdf0e10cSrcweir if (bValid)
928cdf0e10cSrcweir {
929cdf0e10cSrcweir sal_uInt16 nCategory = lcl_GetCategory(
930cdf0e10cSrcweir String(
931cdf0e10cSrcweir xAddIn->getProgrammaticCategoryName(
932cdf0e10cSrcweir aFuncU ) ) );
933cdf0e10cSrcweir
934cdf0e10cSrcweir rtl::OString sHelpId = aHelpIdGenerator.GetHelpId( aFuncU );
935cdf0e10cSrcweir
936cdf0e10cSrcweir rtl::OUString aLocalU;
937cdf0e10cSrcweir try
938cdf0e10cSrcweir {
939cdf0e10cSrcweir aLocalU = xAddIn->
940cdf0e10cSrcweir getDisplayFunctionName( aFuncU );
941cdf0e10cSrcweir }
942cdf0e10cSrcweir catch(uno::Exception&)
943cdf0e10cSrcweir {
944cdf0e10cSrcweir aLocalU = rtl::OUString::createFromAscii( "###" );
945cdf0e10cSrcweir }
946cdf0e10cSrcweir String aLocalName = String( aLocalU );
947cdf0e10cSrcweir
948cdf0e10cSrcweir rtl::OUString aDescU;
949cdf0e10cSrcweir try
950cdf0e10cSrcweir {
951cdf0e10cSrcweir aDescU = xAddIn->
952cdf0e10cSrcweir getFunctionDescription( aFuncU );
953cdf0e10cSrcweir }
954cdf0e10cSrcweir catch(uno::Exception&)
955cdf0e10cSrcweir {
956cdf0e10cSrcweir aDescU = rtl::OUString::createFromAscii( "###" );
957cdf0e10cSrcweir }
958cdf0e10cSrcweir String aDescription = String( aDescU );
959cdf0e10cSrcweir
960cdf0e10cSrcweir ScAddInArgDesc* pVisibleArgs = NULL;
961cdf0e10cSrcweir if ( nVisibleCount > 0 )
962cdf0e10cSrcweir {
963cdf0e10cSrcweir ScAddInArgDesc aDesc;
964cdf0e10cSrcweir pVisibleArgs = new ScAddInArgDesc[nVisibleCount];
965cdf0e10cSrcweir long nDestPos = 0;
966cdf0e10cSrcweir for (nParamPos=0; nParamPos<nParamCount; nParamPos++)
967cdf0e10cSrcweir {
968cdf0e10cSrcweir uno::Reference<reflection::XIdlClass> xParClass =
969cdf0e10cSrcweir pParArr[nParamPos].aType;
970cdf0e10cSrcweir ScAddInArgumentType eArgType = lcl_GetArgType( xParClass );
971cdf0e10cSrcweir if ( eArgType != SC_ADDINARG_CALLER )
972cdf0e10cSrcweir {
973cdf0e10cSrcweir rtl::OUString aArgName;
974cdf0e10cSrcweir try
975cdf0e10cSrcweir {
976cdf0e10cSrcweir aArgName = xAddIn->
977cdf0e10cSrcweir getDisplayArgumentName( aFuncU, nParamPos );
978cdf0e10cSrcweir }
979cdf0e10cSrcweir catch(uno::Exception&)
980cdf0e10cSrcweir {
981cdf0e10cSrcweir aArgName = rtl::OUString::createFromAscii( "###" );
982cdf0e10cSrcweir }
983cdf0e10cSrcweir rtl::OUString aArgDesc;
984cdf0e10cSrcweir try
985cdf0e10cSrcweir {
986cdf0e10cSrcweir aArgDesc = xAddIn->
987cdf0e10cSrcweir getArgumentDescription( aFuncU, nParamPos );
988cdf0e10cSrcweir }
989cdf0e10cSrcweir catch(uno::Exception&)
990cdf0e10cSrcweir {
991cdf0e10cSrcweir aArgName = rtl::OUString::createFromAscii( "###" );
992cdf0e10cSrcweir }
993cdf0e10cSrcweir
994cdf0e10cSrcweir sal_Bool bOptional =
995cdf0e10cSrcweir ( eArgType == SC_ADDINARG_VALUE_OR_ARRAY ||
996cdf0e10cSrcweir eArgType == SC_ADDINARG_VARARGS );
997cdf0e10cSrcweir
998cdf0e10cSrcweir aDesc.eType = eArgType;
999cdf0e10cSrcweir aDesc.aName = String( aArgName );
1000cdf0e10cSrcweir aDesc.aDescription = String( aArgDesc );
1001cdf0e10cSrcweir aDesc.bOptional = bOptional;
1002cdf0e10cSrcweir //! initialize aInternalName only from config?
1003cdf0e10cSrcweir aDesc.aInternalName = pParArr[nParamPos].aName;
1004cdf0e10cSrcweir
1005cdf0e10cSrcweir pVisibleArgs[nDestPos++] = aDesc;
1006cdf0e10cSrcweir }
1007cdf0e10cSrcweir }
1008cdf0e10cSrcweir DBG_ASSERT( nDestPos==nVisibleCount, "wrong count" );
1009cdf0e10cSrcweir }
1010cdf0e10cSrcweir
1011cdf0e10cSrcweir ppFuncData[nFuncPos+nOld] = new ScUnoAddInFuncData(
1012cdf0e10cSrcweir aFuncName, aLocalName, aDescription,
1013cdf0e10cSrcweir nCategory, sHelpId,
1014cdf0e10cSrcweir xFunc, aObject,
1015cdf0e10cSrcweir nVisibleCount, pVisibleArgs, nCallerPos );
1016cdf0e10cSrcweir
1017cdf0e10cSrcweir const ScUnoAddInFuncData* pData =
1018cdf0e10cSrcweir ppFuncData[nFuncPos+nOld];
1019cdf0e10cSrcweir pExactHashMap->insert(
1020cdf0e10cSrcweir ScAddInHashMap::value_type(
1021cdf0e10cSrcweir pData->GetOriginalName(),
1022cdf0e10cSrcweir pData ) );
1023cdf0e10cSrcweir pNameHashMap->insert(
1024cdf0e10cSrcweir ScAddInHashMap::value_type(
1025cdf0e10cSrcweir pData->GetUpperName(),
1026cdf0e10cSrcweir pData ) );
1027cdf0e10cSrcweir pLocalHashMap->insert(
1028cdf0e10cSrcweir ScAddInHashMap::value_type(
1029cdf0e10cSrcweir pData->GetUpperLocal(),
1030cdf0e10cSrcweir pData ) );
1031cdf0e10cSrcweir
1032cdf0e10cSrcweir delete[] pVisibleArgs;
1033cdf0e10cSrcweir }
1034cdf0e10cSrcweir }
1035cdf0e10cSrcweir }
1036cdf0e10cSrcweir }
1037cdf0e10cSrcweir }
1038cdf0e10cSrcweir }
1039cdf0e10cSrcweir }
1040cdf0e10cSrcweir }
1041cdf0e10cSrcweir }
1042cdf0e10cSrcweir }
1043cdf0e10cSrcweir
lcl_UpdateFunctionList(ScFunctionList & rFunctionList,const ScUnoAddInFuncData & rFuncData)1044cdf0e10cSrcweir void lcl_UpdateFunctionList( ScFunctionList& rFunctionList, const ScUnoAddInFuncData& rFuncData )
1045cdf0e10cSrcweir {
1046cdf0e10cSrcweir String aCompare = rFuncData.GetUpperLocal(); // as used in FillFunctionDescFromData
1047cdf0e10cSrcweir
1048cdf0e10cSrcweir sal_uLong nCount = rFunctionList.GetCount();
1049cdf0e10cSrcweir for (sal_uLong nPos=0; nPos<nCount; nPos++)
1050cdf0e10cSrcweir {
1051cdf0e10cSrcweir const ScFuncDesc* pDesc = rFunctionList.GetFunction( nPos );
1052cdf0e10cSrcweir if ( pDesc && pDesc->pFuncName && *pDesc->pFuncName == aCompare )
1053cdf0e10cSrcweir {
1054cdf0e10cSrcweir ScUnoAddInCollection::FillFunctionDescFromData( rFuncData, *const_cast<ScFuncDesc*>(pDesc) );
1055cdf0e10cSrcweir break;
1056cdf0e10cSrcweir }
1057cdf0e10cSrcweir }
1058cdf0e10cSrcweir }
1059cdf0e10cSrcweir
lcl_FindArgDesc(const ScUnoAddInFuncData & rFuncData,const String & rArgIntName)1060cdf0e10cSrcweir const ScAddInArgDesc* lcl_FindArgDesc( const ScUnoAddInFuncData& rFuncData, const String& rArgIntName )
1061cdf0e10cSrcweir {
1062cdf0e10cSrcweir long nArgCount = rFuncData.GetArgumentCount();
1063cdf0e10cSrcweir const ScAddInArgDesc* pArguments = rFuncData.GetArguments();
1064cdf0e10cSrcweir for (long nPos=0; nPos<nArgCount; nPos++)
1065cdf0e10cSrcweir {
1066cdf0e10cSrcweir if ( pArguments[nPos].aInternalName == rArgIntName )
1067cdf0e10cSrcweir return &pArguments[nPos];
1068cdf0e10cSrcweir }
1069cdf0e10cSrcweir return NULL;
1070cdf0e10cSrcweir }
1071cdf0e10cSrcweir
UpdateFromAddIn(const uno::Reference<uno::XInterface> & xInterface,const String & rServiceName)1072cdf0e10cSrcweir void ScUnoAddInCollection::UpdateFromAddIn( const uno::Reference<uno::XInterface>& xInterface,
1073cdf0e10cSrcweir const String& rServiceName )
1074cdf0e10cSrcweir {
1075cdf0e10cSrcweir uno::Reference<lang::XLocalizable> xLoc( xInterface, uno::UNO_QUERY );
1076cdf0e10cSrcweir if ( xLoc.is() ) // optional in new add-ins
1077cdf0e10cSrcweir {
1078cdf0e10cSrcweir LanguageType eOfficeLang = Application::GetSettings().GetUILanguage();
1079cdf0e10cSrcweir lang::Locale aLocale( MsLangId::convertLanguageToLocale( eOfficeLang ));
1080cdf0e10cSrcweir xLoc->setLocale( aLocale );
1081cdf0e10cSrcweir }
1082cdf0e10cSrcweir
1083cdf0e10cSrcweir // if function list was already initialized, it must be updated
1084cdf0e10cSrcweir
1085cdf0e10cSrcweir ScFunctionList* pFunctionList = NULL;
1086cdf0e10cSrcweir if ( ScGlobal::HasStarCalcFunctionList() )
1087cdf0e10cSrcweir pFunctionList = ScGlobal::GetStarCalcFunctionList();
1088cdf0e10cSrcweir
1089cdf0e10cSrcweir // only get the function information from Introspection
1090cdf0e10cSrcweir
1091cdf0e10cSrcweir uno::Reference<lang::XMultiServiceFactory> xManager = comphelper::getProcessServiceFactory();
1092cdf0e10cSrcweir if ( xManager.is() )
1093cdf0e10cSrcweir {
1094cdf0e10cSrcweir uno::Reference<beans::XIntrospection> xIntro(
1095cdf0e10cSrcweir xManager->createInstance(rtl::OUString::createFromAscii(
1096cdf0e10cSrcweir "com.sun.star.beans.Introspection" )),
1097cdf0e10cSrcweir uno::UNO_QUERY );
1098cdf0e10cSrcweir if ( xIntro.is() )
1099cdf0e10cSrcweir {
1100cdf0e10cSrcweir uno::Any aObject;
1101cdf0e10cSrcweir aObject <<= xInterface;
1102cdf0e10cSrcweir uno::Reference<beans::XIntrospectionAccess> xAcc = xIntro->inspect(aObject);
1103cdf0e10cSrcweir if (xAcc.is())
1104cdf0e10cSrcweir {
1105cdf0e10cSrcweir uno::Sequence< uno::Reference<reflection::XIdlMethod> > aMethods =
1106cdf0e10cSrcweir xAcc->getMethods( beans::MethodConcept::ALL );
1107cdf0e10cSrcweir long nMethodCount = aMethods.getLength();
1108cdf0e10cSrcweir const uno::Reference<reflection::XIdlMethod>* pArray = aMethods.getConstArray();
1109cdf0e10cSrcweir for (long nFuncPos=0; nFuncPos<nMethodCount; nFuncPos++)
1110cdf0e10cSrcweir {
1111cdf0e10cSrcweir uno::Reference<reflection::XIdlMethod> xFunc = pArray[nFuncPos];
1112cdf0e10cSrcweir if (xFunc.is())
1113cdf0e10cSrcweir {
1114cdf0e10cSrcweir rtl::OUString aFuncU = xFunc->getName();
1115cdf0e10cSrcweir
1116cdf0e10cSrcweir // stored function name: (service name).(function)
1117cdf0e10cSrcweir String aFuncName = rServiceName;
1118cdf0e10cSrcweir aFuncName += '.';
1119cdf0e10cSrcweir aFuncName += String( aFuncU );
1120cdf0e10cSrcweir
1121cdf0e10cSrcweir // internal names are skipped because no FuncData exists
1122cdf0e10cSrcweir ScUnoAddInFuncData* pOldData = const_cast<ScUnoAddInFuncData*>( GetFuncData( aFuncName ) );
1123cdf0e10cSrcweir if ( pOldData )
1124cdf0e10cSrcweir {
1125cdf0e10cSrcweir // Create new (complete) argument info.
1126cdf0e10cSrcweir // As in ReadFromAddIn, the reflection information is authoritative.
1127cdf0e10cSrcweir // Local names and descriptions from pOldData are looked up using the
1128cdf0e10cSrcweir // internal argument name.
1129cdf0e10cSrcweir
1130cdf0e10cSrcweir sal_Bool bValid = sal_True;
1131cdf0e10cSrcweir long nVisibleCount = 0;
1132cdf0e10cSrcweir long nCallerPos = SC_CALLERPOS_NONE;
1133cdf0e10cSrcweir
1134cdf0e10cSrcweir uno::Sequence<reflection::ParamInfo> aParams =
1135cdf0e10cSrcweir xFunc->getParameterInfos();
1136cdf0e10cSrcweir long nParamCount = aParams.getLength();
1137cdf0e10cSrcweir const reflection::ParamInfo* pParArr = aParams.getConstArray();
1138cdf0e10cSrcweir long nParamPos;
1139cdf0e10cSrcweir for (nParamPos=0; nParamPos<nParamCount; nParamPos++)
1140cdf0e10cSrcweir {
1141cdf0e10cSrcweir if ( pParArr[nParamPos].aMode != reflection::ParamMode_IN )
1142cdf0e10cSrcweir bValid = sal_False;
1143cdf0e10cSrcweir uno::Reference<reflection::XIdlClass> xParClass =
1144cdf0e10cSrcweir pParArr[nParamPos].aType;
1145cdf0e10cSrcweir ScAddInArgumentType eArgType = lcl_GetArgType( xParClass );
1146cdf0e10cSrcweir if ( eArgType == SC_ADDINARG_NONE )
1147cdf0e10cSrcweir bValid = sal_False;
1148cdf0e10cSrcweir else if ( eArgType == SC_ADDINARG_CALLER )
1149cdf0e10cSrcweir nCallerPos = nParamPos;
1150cdf0e10cSrcweir else
1151cdf0e10cSrcweir ++nVisibleCount;
1152cdf0e10cSrcweir }
1153cdf0e10cSrcweir if (bValid)
1154cdf0e10cSrcweir {
1155cdf0e10cSrcweir ScAddInArgDesc* pVisibleArgs = NULL;
1156cdf0e10cSrcweir if ( nVisibleCount > 0 )
1157cdf0e10cSrcweir {
1158cdf0e10cSrcweir ScAddInArgDesc aDesc;
1159cdf0e10cSrcweir pVisibleArgs = new ScAddInArgDesc[nVisibleCount];
1160cdf0e10cSrcweir long nDestPos = 0;
1161cdf0e10cSrcweir for (nParamPos=0; nParamPos<nParamCount; nParamPos++)
1162cdf0e10cSrcweir {
1163cdf0e10cSrcweir uno::Reference<reflection::XIdlClass> xParClass =
1164cdf0e10cSrcweir pParArr[nParamPos].aType;
1165cdf0e10cSrcweir ScAddInArgumentType eArgType = lcl_GetArgType( xParClass );
1166cdf0e10cSrcweir if ( eArgType != SC_ADDINARG_CALLER )
1167cdf0e10cSrcweir {
1168cdf0e10cSrcweir const ScAddInArgDesc* pOldArgDesc =
1169cdf0e10cSrcweir lcl_FindArgDesc( *pOldData, pParArr[nParamPos].aName );
1170cdf0e10cSrcweir if ( pOldArgDesc )
1171cdf0e10cSrcweir {
1172cdf0e10cSrcweir aDesc.aName = pOldArgDesc->aName;
1173cdf0e10cSrcweir aDesc.aDescription = pOldArgDesc->aDescription;
1174cdf0e10cSrcweir }
1175cdf0e10cSrcweir else
1176cdf0e10cSrcweir aDesc.aName = aDesc.aDescription = String::CreateFromAscii( "###" );
1177cdf0e10cSrcweir
1178cdf0e10cSrcweir sal_Bool bOptional =
1179cdf0e10cSrcweir ( eArgType == SC_ADDINARG_VALUE_OR_ARRAY ||
1180cdf0e10cSrcweir eArgType == SC_ADDINARG_VARARGS );
1181cdf0e10cSrcweir
1182cdf0e10cSrcweir aDesc.eType = eArgType;
1183cdf0e10cSrcweir aDesc.bOptional = bOptional;
1184cdf0e10cSrcweir //! initialize aInternalName only from config?
1185cdf0e10cSrcweir aDesc.aInternalName = pParArr[nParamPos].aName;
1186cdf0e10cSrcweir
1187cdf0e10cSrcweir pVisibleArgs[nDestPos++] = aDesc;
1188cdf0e10cSrcweir }
1189cdf0e10cSrcweir }
1190cdf0e10cSrcweir DBG_ASSERT( nDestPos==nVisibleCount, "wrong count" );
1191cdf0e10cSrcweir }
1192cdf0e10cSrcweir
1193cdf0e10cSrcweir pOldData->SetFunction( xFunc, aObject );
1194cdf0e10cSrcweir pOldData->SetArguments( nVisibleCount, pVisibleArgs );
1195cdf0e10cSrcweir pOldData->SetCallerPos( nCallerPos );
1196cdf0e10cSrcweir
1197cdf0e10cSrcweir if ( pFunctionList )
1198cdf0e10cSrcweir lcl_UpdateFunctionList( *pFunctionList, *pOldData );
1199cdf0e10cSrcweir
1200cdf0e10cSrcweir delete[] pVisibleArgs;
1201cdf0e10cSrcweir }
1202cdf0e10cSrcweir }
1203cdf0e10cSrcweir }
1204cdf0e10cSrcweir }
1205cdf0e10cSrcweir }
1206cdf0e10cSrcweir }
1207cdf0e10cSrcweir }
1208cdf0e10cSrcweir }
1209cdf0e10cSrcweir
FindFunction(const String & rUpperName,sal_Bool bLocalFirst)1210cdf0e10cSrcweir String ScUnoAddInCollection::FindFunction( const String& rUpperName, sal_Bool bLocalFirst )
1211cdf0e10cSrcweir {
1212cdf0e10cSrcweir if (!bInitialized)
1213cdf0e10cSrcweir Initialize();
1214cdf0e10cSrcweir
1215cdf0e10cSrcweir if (nFuncCount == 0)
1216cdf0e10cSrcweir return EMPTY_STRING;
1217cdf0e10cSrcweir
1218cdf0e10cSrcweir if ( bLocalFirst )
1219cdf0e10cSrcweir {
1220cdf0e10cSrcweir // first scan all local names (used for entering formulas)
1221cdf0e10cSrcweir
1222cdf0e10cSrcweir ScAddInHashMap::const_iterator iLook( pLocalHashMap->find( rUpperName ) );
1223cdf0e10cSrcweir if ( iLook != pLocalHashMap->end() )
1224cdf0e10cSrcweir return iLook->second->GetOriginalName();
1225cdf0e10cSrcweir
1226cdf0e10cSrcweir #if 0
1227cdf0e10cSrcweir // after that, scan international names (really?)
1228cdf0e10cSrcweir
1229cdf0e10cSrcweir iLook = pNameHashMap->find( rUpperName );
1230cdf0e10cSrcweir if ( iLook != pNameHashMap->end() )
1231cdf0e10cSrcweir return iLook->second->GetOriginalName();
1232cdf0e10cSrcweir #endif
1233cdf0e10cSrcweir }
1234cdf0e10cSrcweir else
1235cdf0e10cSrcweir {
1236cdf0e10cSrcweir // first scan international names (used when calling a function)
1237cdf0e10cSrcweir //! before that, check for exact match???
1238cdf0e10cSrcweir
1239cdf0e10cSrcweir ScAddInHashMap::const_iterator iLook( pNameHashMap->find( rUpperName ) );
1240cdf0e10cSrcweir if ( iLook != pNameHashMap->end() )
1241cdf0e10cSrcweir return iLook->second->GetOriginalName();
1242cdf0e10cSrcweir
1243cdf0e10cSrcweir // after that, scan all local names (to allow replacing old AddIns with Uno)
1244cdf0e10cSrcweir
1245cdf0e10cSrcweir iLook = pLocalHashMap->find( rUpperName );
1246cdf0e10cSrcweir if ( iLook != pLocalHashMap->end() )
1247cdf0e10cSrcweir return iLook->second->GetOriginalName();
1248cdf0e10cSrcweir }
1249cdf0e10cSrcweir
1250cdf0e10cSrcweir return EMPTY_STRING;
1251cdf0e10cSrcweir }
1252cdf0e10cSrcweir
GetFuncData(const String & rName,bool bComplete)1253cdf0e10cSrcweir const ScUnoAddInFuncData* ScUnoAddInCollection::GetFuncData( const String& rName, bool bComplete )
1254cdf0e10cSrcweir {
1255cdf0e10cSrcweir if (!bInitialized)
1256cdf0e10cSrcweir Initialize();
1257cdf0e10cSrcweir
1258cdf0e10cSrcweir // rName must be the exact internal name
1259cdf0e10cSrcweir
1260cdf0e10cSrcweir ScAddInHashMap::const_iterator iLook( pExactHashMap->find( rName ) );
1261cdf0e10cSrcweir if ( iLook != pExactHashMap->end() )
1262cdf0e10cSrcweir {
1263cdf0e10cSrcweir const ScUnoAddInFuncData* pFuncData = iLook->second;
1264cdf0e10cSrcweir
1265cdf0e10cSrcweir if ( bComplete && !pFuncData->GetFunction().is() ) //! extra flag?
1266cdf0e10cSrcweir LoadComponent( *pFuncData );
1267cdf0e10cSrcweir
1268cdf0e10cSrcweir return pFuncData;
1269cdf0e10cSrcweir }
1270cdf0e10cSrcweir
1271cdf0e10cSrcweir return NULL;
1272cdf0e10cSrcweir }
1273cdf0e10cSrcweir
GetFuncData(long nIndex)1274cdf0e10cSrcweir const ScUnoAddInFuncData* ScUnoAddInCollection::GetFuncData( long nIndex )
1275cdf0e10cSrcweir {
1276cdf0e10cSrcweir if (!bInitialized)
1277cdf0e10cSrcweir Initialize();
1278cdf0e10cSrcweir
1279cdf0e10cSrcweir if (nIndex < nFuncCount)
1280cdf0e10cSrcweir return ppFuncData[nIndex];
1281cdf0e10cSrcweir return NULL;
1282cdf0e10cSrcweir }
1283cdf0e10cSrcweir
LocalizeString(String & rName)1284cdf0e10cSrcweir void ScUnoAddInCollection::LocalizeString( String& rName )
1285cdf0e10cSrcweir {
1286cdf0e10cSrcweir if (!bInitialized)
1287cdf0e10cSrcweir Initialize();
1288cdf0e10cSrcweir
1289cdf0e10cSrcweir // modify rName - input: exact name
1290cdf0e10cSrcweir
1291cdf0e10cSrcweir ScAddInHashMap::const_iterator iLook( pExactHashMap->find( rName ) );
1292cdf0e10cSrcweir if ( iLook != pExactHashMap->end() )
1293cdf0e10cSrcweir rName = iLook->second->GetUpperLocal(); //! upper?
1294cdf0e10cSrcweir }
1295cdf0e10cSrcweir
1296cdf0e10cSrcweir
GetFuncCount()1297cdf0e10cSrcweir long ScUnoAddInCollection::GetFuncCount()
1298cdf0e10cSrcweir {
1299cdf0e10cSrcweir if (!bInitialized)
1300cdf0e10cSrcweir Initialize();
1301cdf0e10cSrcweir
1302cdf0e10cSrcweir return nFuncCount;
1303cdf0e10cSrcweir }
1304cdf0e10cSrcweir
FillFunctionDesc(long nFunc,ScFuncDesc & rDesc)1305cdf0e10cSrcweir sal_Bool ScUnoAddInCollection::FillFunctionDesc( long nFunc, ScFuncDesc& rDesc )
1306cdf0e10cSrcweir {
1307cdf0e10cSrcweir if (!bInitialized)
1308cdf0e10cSrcweir Initialize();
1309cdf0e10cSrcweir
1310cdf0e10cSrcweir if (nFunc >= nFuncCount || !ppFuncData[nFunc])
1311cdf0e10cSrcweir return sal_False;
1312cdf0e10cSrcweir
1313cdf0e10cSrcweir const ScUnoAddInFuncData& rFuncData = *ppFuncData[nFunc];
1314cdf0e10cSrcweir
1315cdf0e10cSrcweir return FillFunctionDescFromData( rFuncData, rDesc );
1316cdf0e10cSrcweir }
1317cdf0e10cSrcweir
1318cdf0e10cSrcweir // static
FillFunctionDescFromData(const ScUnoAddInFuncData & rFuncData,ScFuncDesc & rDesc)1319cdf0e10cSrcweir sal_Bool ScUnoAddInCollection::FillFunctionDescFromData( const ScUnoAddInFuncData& rFuncData, ScFuncDesc& rDesc )
1320cdf0e10cSrcweir {
1321cdf0e10cSrcweir rDesc.Clear();
1322cdf0e10cSrcweir
1323cdf0e10cSrcweir sal_Bool bIncomplete = !rFuncData.GetFunction().is(); //! extra flag?
1324cdf0e10cSrcweir
1325cdf0e10cSrcweir long nArgCount = rFuncData.GetArgumentCount();
1326cdf0e10cSrcweir if ( nArgCount > USHRT_MAX )
1327cdf0e10cSrcweir return sal_False;
1328cdf0e10cSrcweir
1329cdf0e10cSrcweir if ( bIncomplete )
1330cdf0e10cSrcweir nArgCount = 0; // if incomplete, fill without argument info (no wrong order)
1331cdf0e10cSrcweir
1332cdf0e10cSrcweir // nFIndex is set from outside
1333cdf0e10cSrcweir
1334cdf0e10cSrcweir rDesc.pFuncName = new String( rFuncData.GetUpperLocal() ); //! upper?
1335cdf0e10cSrcweir rDesc.nCategory = rFuncData.GetCategory();
1336cdf0e10cSrcweir rDesc.sHelpId = rFuncData.GetHelpId();
1337cdf0e10cSrcweir
1338cdf0e10cSrcweir String aDesc = rFuncData.GetDescription();
1339cdf0e10cSrcweir if (!aDesc.Len())
1340cdf0e10cSrcweir aDesc = rFuncData.GetLocalName(); // use name if no description is available
1341cdf0e10cSrcweir rDesc.pFuncDesc = new String( aDesc );
1342cdf0e10cSrcweir
1343cdf0e10cSrcweir // AddInArgumentType_CALLER is already left out in FuncData
1344cdf0e10cSrcweir
1345cdf0e10cSrcweir rDesc.nArgCount = (sal_uInt16)nArgCount;
1346cdf0e10cSrcweir if ( nArgCount )
1347cdf0e10cSrcweir {
1348cdf0e10cSrcweir sal_Bool bMultiple = sal_False;
1349cdf0e10cSrcweir const ScAddInArgDesc* pArgs = rFuncData.GetArguments();
1350cdf0e10cSrcweir
1351cdf0e10cSrcweir rDesc.ppDefArgNames = new String*[nArgCount];
1352cdf0e10cSrcweir rDesc.ppDefArgDescs = new String*[nArgCount];
1353cdf0e10cSrcweir rDesc.pDefArgFlags = new ScFuncDesc::ParameterFlags[nArgCount];
1354cdf0e10cSrcweir for ( long nArg=0; nArg<nArgCount; nArg++ )
1355cdf0e10cSrcweir {
1356cdf0e10cSrcweir rDesc.ppDefArgNames[nArg] = new String( pArgs[nArg].aName );
1357cdf0e10cSrcweir rDesc.ppDefArgDescs[nArg] = new String( pArgs[nArg].aDescription );
1358cdf0e10cSrcweir rDesc.pDefArgFlags[nArg].bOptional = pArgs[nArg].bOptional;
1359cdf0e10cSrcweir rDesc.pDefArgFlags[nArg].bSuppress = false;
1360cdf0e10cSrcweir
1361cdf0e10cSrcweir // no empty names...
1362cdf0e10cSrcweir if ( rDesc.ppDefArgNames[nArg]->Len() == 0 )
1363cdf0e10cSrcweir {
1364cdf0e10cSrcweir String aDefName( RTL_CONSTASCII_USTRINGPARAM("arg") );
1365cdf0e10cSrcweir aDefName += String::CreateFromInt32( nArg+1 );
1366cdf0e10cSrcweir *rDesc.ppDefArgNames[nArg] = aDefName;
1367cdf0e10cSrcweir }
1368cdf0e10cSrcweir
1369cdf0e10cSrcweir // last argument repeated?
1370cdf0e10cSrcweir if ( nArg+1 == nArgCount && ( pArgs[nArg].eType == SC_ADDINARG_VARARGS ) )
1371cdf0e10cSrcweir bMultiple = sal_True;
1372cdf0e10cSrcweir }
1373cdf0e10cSrcweir
1374cdf0e10cSrcweir if ( bMultiple )
1375cdf0e10cSrcweir rDesc.nArgCount += VAR_ARGS - 1; // VAR_ARGS means just one repeated arg
1376cdf0e10cSrcweir }
1377cdf0e10cSrcweir
1378cdf0e10cSrcweir rDesc.bIncomplete = bIncomplete;
1379cdf0e10cSrcweir
1380cdf0e10cSrcweir return sal_True;
1381cdf0e10cSrcweir }
1382cdf0e10cSrcweir
1383cdf0e10cSrcweir
1384cdf0e10cSrcweir //------------------------------------------------------------------------
1385cdf0e10cSrcweir
ScUnoAddInCall(ScUnoAddInCollection & rColl,const String & rName,long nParamCount)1386cdf0e10cSrcweir ScUnoAddInCall::ScUnoAddInCall( ScUnoAddInCollection& rColl, const String& rName,
1387cdf0e10cSrcweir long nParamCount ) :
1388cdf0e10cSrcweir bValidCount( sal_False ),
1389cdf0e10cSrcweir nErrCode( errNoCode ), // before function was called
1390cdf0e10cSrcweir bHasString( sal_True ),
1391cdf0e10cSrcweir fValue( 0.0 ),
1392cdf0e10cSrcweir xMatrix( NULL )
1393cdf0e10cSrcweir {
1394cdf0e10cSrcweir pFuncData = rColl.GetFuncData( rName, true ); // need fully initialized data
1395cdf0e10cSrcweir DBG_ASSERT( pFuncData, "Function Data missing" );
1396cdf0e10cSrcweir if ( pFuncData )
1397cdf0e10cSrcweir {
1398cdf0e10cSrcweir long nDescCount = pFuncData->GetArgumentCount();
1399cdf0e10cSrcweir const ScAddInArgDesc* pArgs = pFuncData->GetArguments();
1400cdf0e10cSrcweir
1401cdf0e10cSrcweir // is aVarArg sequence needed?
1402cdf0e10cSrcweir if ( nParamCount >= nDescCount && nDescCount > 0 &&
1403cdf0e10cSrcweir pArgs[nDescCount-1].eType == SC_ADDINARG_VARARGS )
1404cdf0e10cSrcweir {
1405cdf0e10cSrcweir long nVarCount = nParamCount - ( nDescCount - 1 ); // size of last argument
1406cdf0e10cSrcweir aVarArg.realloc( nVarCount );
1407cdf0e10cSrcweir bValidCount = sal_True;
1408cdf0e10cSrcweir }
1409cdf0e10cSrcweir else if ( nParamCount <= nDescCount )
1410cdf0e10cSrcweir {
1411cdf0e10cSrcweir // all args behind nParamCount must be optional
1412cdf0e10cSrcweir bValidCount = sal_True;
1413cdf0e10cSrcweir for (long i=nParamCount; i<nDescCount; i++)
1414cdf0e10cSrcweir if ( !pArgs[i].bOptional )
1415cdf0e10cSrcweir bValidCount = sal_False;
1416cdf0e10cSrcweir }
1417cdf0e10cSrcweir // else invalid (too many arguments)
1418cdf0e10cSrcweir
1419cdf0e10cSrcweir if ( bValidCount )
1420cdf0e10cSrcweir aArgs.realloc( nDescCount ); // sequence must always match function signature
1421cdf0e10cSrcweir }
1422cdf0e10cSrcweir }
1423cdf0e10cSrcweir
~ScUnoAddInCall()1424cdf0e10cSrcweir ScUnoAddInCall::~ScUnoAddInCall()
1425cdf0e10cSrcweir {
1426cdf0e10cSrcweir // pFuncData is deleted with ScUnoAddInCollection
1427cdf0e10cSrcweir }
1428cdf0e10cSrcweir
ValidParamCount()1429cdf0e10cSrcweir sal_Bool ScUnoAddInCall::ValidParamCount()
1430cdf0e10cSrcweir {
1431cdf0e10cSrcweir return bValidCount;
1432cdf0e10cSrcweir }
1433cdf0e10cSrcweir
GetArgType(long nPos)1434cdf0e10cSrcweir ScAddInArgumentType ScUnoAddInCall::GetArgType( long nPos )
1435cdf0e10cSrcweir {
1436cdf0e10cSrcweir if ( pFuncData )
1437cdf0e10cSrcweir {
1438cdf0e10cSrcweir long nCount = pFuncData->GetArgumentCount();
1439cdf0e10cSrcweir const ScAddInArgDesc* pArgs = pFuncData->GetArguments();
1440cdf0e10cSrcweir
1441cdf0e10cSrcweir // if last arg is sequence, use "any" type
1442cdf0e10cSrcweir if ( nCount > 0 && nPos >= nCount-1 && pArgs[nCount-1].eType == SC_ADDINARG_VARARGS )
1443cdf0e10cSrcweir return SC_ADDINARG_VALUE_OR_ARRAY;
1444cdf0e10cSrcweir
1445cdf0e10cSrcweir if ( nPos < nCount )
1446cdf0e10cSrcweir return pArgs[nPos].eType;
1447cdf0e10cSrcweir }
1448cdf0e10cSrcweir return SC_ADDINARG_VALUE_OR_ARRAY; //! error code !!!!
1449cdf0e10cSrcweir }
1450cdf0e10cSrcweir
NeedsCaller() const1451cdf0e10cSrcweir sal_Bool ScUnoAddInCall::NeedsCaller() const
1452cdf0e10cSrcweir {
1453cdf0e10cSrcweir return pFuncData && pFuncData->GetCallerPos() != SC_CALLERPOS_NONE;
1454cdf0e10cSrcweir }
1455cdf0e10cSrcweir
SetCaller(const uno::Reference<uno::XInterface> & rInterface)1456cdf0e10cSrcweir void ScUnoAddInCall::SetCaller( const uno::Reference<uno::XInterface>& rInterface )
1457cdf0e10cSrcweir {
1458cdf0e10cSrcweir xCaller = rInterface;
1459cdf0e10cSrcweir }
1460cdf0e10cSrcweir
SetCallerFromObjectShell(SfxObjectShell * pObjSh)1461cdf0e10cSrcweir void ScUnoAddInCall::SetCallerFromObjectShell( SfxObjectShell* pObjSh )
1462cdf0e10cSrcweir {
1463cdf0e10cSrcweir if (pObjSh)
1464cdf0e10cSrcweir {
1465cdf0e10cSrcweir uno::Reference<uno::XInterface> xInt( pObjSh->GetBaseModel(), uno::UNO_QUERY );
1466cdf0e10cSrcweir SetCaller( xInt );
1467cdf0e10cSrcweir }
1468cdf0e10cSrcweir }
1469cdf0e10cSrcweir
SetParam(long nPos,const uno::Any & rValue)1470cdf0e10cSrcweir void ScUnoAddInCall::SetParam( long nPos, const uno::Any& rValue )
1471cdf0e10cSrcweir {
1472cdf0e10cSrcweir if ( pFuncData )
1473cdf0e10cSrcweir {
1474cdf0e10cSrcweir long nCount = pFuncData->GetArgumentCount();
1475cdf0e10cSrcweir const ScAddInArgDesc* pArgs = pFuncData->GetArguments();
1476cdf0e10cSrcweir if ( nCount > 0 && nPos >= nCount-1 && pArgs[nCount-1].eType == SC_ADDINARG_VARARGS )
1477cdf0e10cSrcweir {
1478cdf0e10cSrcweir long nVarPos = nPos-(nCount-1);
1479cdf0e10cSrcweir if ( nVarPos < aVarArg.getLength() )
1480cdf0e10cSrcweir aVarArg.getArray()[nVarPos] = rValue;
1481cdf0e10cSrcweir else
1482cdf0e10cSrcweir {
1483cdf0e10cSrcweir DBG_ERROR("wrong argument number");
1484cdf0e10cSrcweir }
1485cdf0e10cSrcweir }
1486cdf0e10cSrcweir else if ( nPos < aArgs.getLength() )
1487cdf0e10cSrcweir aArgs.getArray()[nPos] = rValue;
1488cdf0e10cSrcweir else
1489cdf0e10cSrcweir {
1490cdf0e10cSrcweir DBG_ERROR("wrong argument number");
1491cdf0e10cSrcweir }
1492cdf0e10cSrcweir }
1493cdf0e10cSrcweir }
1494cdf0e10cSrcweir
ExecuteCall()1495cdf0e10cSrcweir void ScUnoAddInCall::ExecuteCall()
1496cdf0e10cSrcweir {
1497cdf0e10cSrcweir if ( !pFuncData )
1498cdf0e10cSrcweir return;
1499cdf0e10cSrcweir
1500cdf0e10cSrcweir long nCount = pFuncData->GetArgumentCount();
1501cdf0e10cSrcweir const ScAddInArgDesc* pArgs = pFuncData->GetArguments();
1502cdf0e10cSrcweir if ( nCount > 0 && pArgs[nCount-1].eType == SC_ADDINARG_VARARGS )
1503cdf0e10cSrcweir {
1504cdf0e10cSrcweir // insert aVarArg as last argument
1505cdf0e10cSrcweir //! after inserting caller (to prevent copying twice)?
1506cdf0e10cSrcweir
1507cdf0e10cSrcweir DBG_ASSERT( aArgs.getLength() == nCount, "wrong argument count" );
1508cdf0e10cSrcweir aArgs.getArray()[nCount-1] <<= aVarArg;
1509cdf0e10cSrcweir }
1510cdf0e10cSrcweir
1511cdf0e10cSrcweir if ( pFuncData->GetCallerPos() != SC_CALLERPOS_NONE )
1512cdf0e10cSrcweir {
1513cdf0e10cSrcweir uno::Any aCallerAny;
1514cdf0e10cSrcweir aCallerAny <<= xCaller;
1515cdf0e10cSrcweir
1516cdf0e10cSrcweir long nUserLen = aArgs.getLength();
1517cdf0e10cSrcweir long nCallPos = pFuncData->GetCallerPos();
1518cdf0e10cSrcweir if (nCallPos>nUserLen) // should not happen
1519cdf0e10cSrcweir {
1520cdf0e10cSrcweir DBG_ERROR("wrong CallPos");
1521cdf0e10cSrcweir nCallPos = nUserLen;
1522cdf0e10cSrcweir }
1523cdf0e10cSrcweir
1524cdf0e10cSrcweir long nDestLen = nUserLen + 1;
1525cdf0e10cSrcweir uno::Sequence<uno::Any> aRealArgs( nDestLen );
1526cdf0e10cSrcweir uno::Any* pDest = aRealArgs.getArray();
1527cdf0e10cSrcweir
1528cdf0e10cSrcweir const uno::Any* pSource = aArgs.getConstArray();
1529cdf0e10cSrcweir long nSrcPos = 0;
1530cdf0e10cSrcweir
1531cdf0e10cSrcweir for ( long nDestPos = 0; nDestPos < nDestLen; nDestPos++ )
1532cdf0e10cSrcweir {
1533cdf0e10cSrcweir if ( nDestPos == nCallPos )
1534cdf0e10cSrcweir pDest[nDestPos] = aCallerAny;
1535cdf0e10cSrcweir else
1536cdf0e10cSrcweir pDest[nDestPos] = pSource[nSrcPos++];
1537cdf0e10cSrcweir }
1538cdf0e10cSrcweir
1539cdf0e10cSrcweir ExecuteCallWithArgs( aRealArgs );
1540cdf0e10cSrcweir }
1541cdf0e10cSrcweir else
1542cdf0e10cSrcweir ExecuteCallWithArgs( aArgs );
1543cdf0e10cSrcweir }
1544cdf0e10cSrcweir
ExecuteCallWithArgs(uno::Sequence<uno::Any> & rCallArgs)1545cdf0e10cSrcweir void ScUnoAddInCall::ExecuteCallWithArgs(uno::Sequence<uno::Any>& rCallArgs)
1546cdf0e10cSrcweir {
1547cdf0e10cSrcweir // rCallArgs may not match argument descriptions (because of caller)
1548cdf0e10cSrcweir
1549cdf0e10cSrcweir uno::Reference<reflection::XIdlMethod> xFunction;
1550cdf0e10cSrcweir uno::Any aObject;
1551cdf0e10cSrcweir if ( pFuncData )
1552cdf0e10cSrcweir {
1553cdf0e10cSrcweir xFunction = pFuncData->GetFunction();
1554cdf0e10cSrcweir aObject = pFuncData->GetObject();
1555cdf0e10cSrcweir }
1556cdf0e10cSrcweir
1557cdf0e10cSrcweir if ( xFunction.is() )
1558cdf0e10cSrcweir {
1559cdf0e10cSrcweir uno::Any aAny;
1560cdf0e10cSrcweir nErrCode = 0;
1561cdf0e10cSrcweir
1562cdf0e10cSrcweir try
1563cdf0e10cSrcweir {
1564cdf0e10cSrcweir aAny = xFunction->invoke( aObject, rCallArgs );
1565cdf0e10cSrcweir }
1566cdf0e10cSrcweir catch(lang::IllegalArgumentException&)
1567cdf0e10cSrcweir {
1568cdf0e10cSrcweir nErrCode = errIllegalArgument;
1569cdf0e10cSrcweir }
1570cdf0e10cSrcweir #if 0
1571cdf0e10cSrcweir catch(FloatingPointException&)
1572cdf0e10cSrcweir {
1573cdf0e10cSrcweir nErrCode = errIllegalFPOperation;
1574cdf0e10cSrcweir }
1575cdf0e10cSrcweir #endif
1576cdf0e10cSrcweir catch(reflection::InvocationTargetException& rWrapped)
1577cdf0e10cSrcweir {
1578cdf0e10cSrcweir if ( rWrapped.TargetException.getValueType().equals(
1579cdf0e10cSrcweir getCppuType( (lang::IllegalArgumentException*)0 ) ) )
1580cdf0e10cSrcweir nErrCode = errIllegalArgument;
1581cdf0e10cSrcweir else if ( rWrapped.TargetException.getValueType().equals(
1582cdf0e10cSrcweir getCppuType( (sheet::NoConvergenceException*)0 ) ) )
1583cdf0e10cSrcweir nErrCode = errNoConvergence;
1584cdf0e10cSrcweir else
1585cdf0e10cSrcweir nErrCode = errNoValue;
1586cdf0e10cSrcweir }
1587cdf0e10cSrcweir
1588cdf0e10cSrcweir catch(uno::Exception&)
1589cdf0e10cSrcweir {
1590cdf0e10cSrcweir nErrCode = errNoValue;
1591cdf0e10cSrcweir }
1592cdf0e10cSrcweir
1593cdf0e10cSrcweir if (!nErrCode)
1594cdf0e10cSrcweir SetResult( aAny ); // convert result to Calc types
1595cdf0e10cSrcweir }
1596cdf0e10cSrcweir }
1597cdf0e10cSrcweir
SetResult(const uno::Any & rNewRes)1598cdf0e10cSrcweir void ScUnoAddInCall::SetResult( const uno::Any& rNewRes )
1599cdf0e10cSrcweir {
1600cdf0e10cSrcweir nErrCode = 0;
1601cdf0e10cSrcweir xVarRes = NULL;
1602cdf0e10cSrcweir
1603cdf0e10cSrcweir // Reflection* pRefl = rNewRes.getReflection();
1604cdf0e10cSrcweir
1605cdf0e10cSrcweir uno::TypeClass eClass = rNewRes.getValueTypeClass();
1606cdf0e10cSrcweir uno::Type aType = rNewRes.getValueType();
1607cdf0e10cSrcweir switch (eClass)
1608cdf0e10cSrcweir {
1609cdf0e10cSrcweir case uno::TypeClass_VOID:
1610cdf0e10cSrcweir nErrCode = NOTAVAILABLE; // #NA
1611cdf0e10cSrcweir break;
1612cdf0e10cSrcweir
1613cdf0e10cSrcweir case uno::TypeClass_ENUM:
1614cdf0e10cSrcweir case uno::TypeClass_BOOLEAN:
1615cdf0e10cSrcweir case uno::TypeClass_CHAR:
1616cdf0e10cSrcweir case uno::TypeClass_BYTE:
1617cdf0e10cSrcweir case uno::TypeClass_SHORT:
1618cdf0e10cSrcweir case uno::TypeClass_UNSIGNED_SHORT:
1619cdf0e10cSrcweir case uno::TypeClass_LONG:
1620cdf0e10cSrcweir case uno::TypeClass_UNSIGNED_LONG:
1621cdf0e10cSrcweir case uno::TypeClass_FLOAT:
1622cdf0e10cSrcweir case uno::TypeClass_DOUBLE:
1623cdf0e10cSrcweir {
1624cdf0e10cSrcweir uno::TypeClass eMyClass;
1625cdf0e10cSrcweir ScApiTypeConversion::ConvertAnyToDouble( fValue, eMyClass, rNewRes);
1626cdf0e10cSrcweir bHasString = sal_False;
1627cdf0e10cSrcweir }
1628cdf0e10cSrcweir break;
1629cdf0e10cSrcweir
1630cdf0e10cSrcweir case uno::TypeClass_STRING:
1631cdf0e10cSrcweir {
1632cdf0e10cSrcweir rtl::OUString aUStr;
1633cdf0e10cSrcweir rNewRes >>= aUStr;
1634cdf0e10cSrcweir aString = String( aUStr );
1635cdf0e10cSrcweir bHasString = sal_True;
1636cdf0e10cSrcweir }
1637cdf0e10cSrcweir break;
1638cdf0e10cSrcweir
1639cdf0e10cSrcweir case uno::TypeClass_INTERFACE:
1640cdf0e10cSrcweir {
1641cdf0e10cSrcweir //! directly extract XVolatileResult from any?
1642cdf0e10cSrcweir uno::Reference<uno::XInterface> xInterface;
1643cdf0e10cSrcweir rNewRes >>= xInterface;
1644cdf0e10cSrcweir if ( xInterface.is() )
1645cdf0e10cSrcweir xVarRes = uno::Reference<sheet::XVolatileResult>( xInterface, uno::UNO_QUERY );
1646cdf0e10cSrcweir
1647cdf0e10cSrcweir if (!xVarRes.is())
1648cdf0e10cSrcweir nErrCode = errNoValue; // unknown interface
1649cdf0e10cSrcweir }
1650cdf0e10cSrcweir break;
1651cdf0e10cSrcweir
1652cdf0e10cSrcweir default:
1653cdf0e10cSrcweir if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<sal_Int32> > *)0 ) ) )
1654cdf0e10cSrcweir {
1655cdf0e10cSrcweir const uno::Sequence< uno::Sequence<sal_Int32> >* pRowSeq = NULL;
1656cdf0e10cSrcweir
1657cdf0e10cSrcweir //! use pointer from any!
1658cdf0e10cSrcweir uno::Sequence< uno::Sequence<sal_Int32> > aSequence;
1659cdf0e10cSrcweir if ( rNewRes >>= aSequence )
1660cdf0e10cSrcweir pRowSeq = &aSequence;
1661cdf0e10cSrcweir
1662cdf0e10cSrcweir if ( pRowSeq )
1663cdf0e10cSrcweir {
1664cdf0e10cSrcweir long nRowCount = pRowSeq->getLength();
1665cdf0e10cSrcweir const uno::Sequence<sal_Int32>* pRowArr = pRowSeq->getConstArray();
1666cdf0e10cSrcweir long nMaxColCount = 0;
1667cdf0e10cSrcweir long nCol, nRow;
1668cdf0e10cSrcweir for (nRow=0; nRow<nRowCount; nRow++)
1669cdf0e10cSrcweir {
1670cdf0e10cSrcweir long nTmp = pRowArr[nRow].getLength();
1671cdf0e10cSrcweir if ( nTmp > nMaxColCount )
1672cdf0e10cSrcweir nMaxColCount = nTmp;
1673cdf0e10cSrcweir }
1674cdf0e10cSrcweir if ( nMaxColCount && nRowCount )
1675cdf0e10cSrcweir {
1676cdf0e10cSrcweir xMatrix = new ScMatrix(
1677cdf0e10cSrcweir static_cast<SCSIZE>(nMaxColCount),
1678cdf0e10cSrcweir static_cast<SCSIZE>(nRowCount) );
1679cdf0e10cSrcweir ScMatrix* pMatrix = xMatrix;
1680cdf0e10cSrcweir for (nRow=0; nRow<nRowCount; nRow++)
1681cdf0e10cSrcweir {
1682cdf0e10cSrcweir long nColCount = pRowArr[nRow].getLength();
1683cdf0e10cSrcweir const sal_Int32* pColArr = pRowArr[nRow].getConstArray();
1684cdf0e10cSrcweir for (nCol=0; nCol<nColCount; nCol++)
1685cdf0e10cSrcweir pMatrix->PutDouble( pColArr[nCol],
1686cdf0e10cSrcweir static_cast<SCSIZE>(nCol),
1687cdf0e10cSrcweir static_cast<SCSIZE>(nRow) );
1688cdf0e10cSrcweir for (nCol=nColCount; nCol<nMaxColCount; nCol++)
1689cdf0e10cSrcweir pMatrix->PutDouble( 0.0,
1690cdf0e10cSrcweir static_cast<SCSIZE>(nCol),
1691cdf0e10cSrcweir static_cast<SCSIZE>(nRow) );
1692cdf0e10cSrcweir }
1693cdf0e10cSrcweir }
1694cdf0e10cSrcweir }
1695cdf0e10cSrcweir }
1696cdf0e10cSrcweir else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<double> > *)0 ) ) )
1697cdf0e10cSrcweir {
1698cdf0e10cSrcweir const uno::Sequence< uno::Sequence<double> >* pRowSeq = NULL;
1699cdf0e10cSrcweir
1700cdf0e10cSrcweir //! use pointer from any!
1701cdf0e10cSrcweir uno::Sequence< uno::Sequence<double> > aSequence;
1702cdf0e10cSrcweir if ( rNewRes >>= aSequence )
1703cdf0e10cSrcweir pRowSeq = &aSequence;
1704cdf0e10cSrcweir
1705cdf0e10cSrcweir if ( pRowSeq )
1706cdf0e10cSrcweir {
1707cdf0e10cSrcweir long nRowCount = pRowSeq->getLength();
1708cdf0e10cSrcweir const uno::Sequence<double>* pRowArr = pRowSeq->getConstArray();
1709cdf0e10cSrcweir long nMaxColCount = 0;
1710cdf0e10cSrcweir long nCol, nRow;
1711cdf0e10cSrcweir for (nRow=0; nRow<nRowCount; nRow++)
1712cdf0e10cSrcweir {
1713cdf0e10cSrcweir long nTmp = pRowArr[nRow].getLength();
1714cdf0e10cSrcweir if ( nTmp > nMaxColCount )
1715cdf0e10cSrcweir nMaxColCount = nTmp;
1716cdf0e10cSrcweir }
1717cdf0e10cSrcweir if ( nMaxColCount && nRowCount )
1718cdf0e10cSrcweir {
1719cdf0e10cSrcweir xMatrix = new ScMatrix(
1720cdf0e10cSrcweir static_cast<SCSIZE>(nMaxColCount),
1721cdf0e10cSrcweir static_cast<SCSIZE>(nRowCount) );
1722cdf0e10cSrcweir ScMatrix* pMatrix = xMatrix;
1723cdf0e10cSrcweir for (nRow=0; nRow<nRowCount; nRow++)
1724cdf0e10cSrcweir {
1725cdf0e10cSrcweir long nColCount = pRowArr[nRow].getLength();
1726cdf0e10cSrcweir const double* pColArr = pRowArr[nRow].getConstArray();
1727cdf0e10cSrcweir for (nCol=0; nCol<nColCount; nCol++)
1728cdf0e10cSrcweir pMatrix->PutDouble( pColArr[nCol],
1729cdf0e10cSrcweir static_cast<SCSIZE>(nCol),
1730cdf0e10cSrcweir static_cast<SCSIZE>(nRow) );
1731cdf0e10cSrcweir for (nCol=nColCount; nCol<nMaxColCount; nCol++)
1732cdf0e10cSrcweir pMatrix->PutDouble( 0.0,
1733cdf0e10cSrcweir static_cast<SCSIZE>(nCol),
1734cdf0e10cSrcweir static_cast<SCSIZE>(nRow) );
1735cdf0e10cSrcweir }
1736cdf0e10cSrcweir }
1737cdf0e10cSrcweir }
1738cdf0e10cSrcweir }
1739cdf0e10cSrcweir else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<rtl::OUString> > *)0 ) ) )
1740cdf0e10cSrcweir {
1741cdf0e10cSrcweir const uno::Sequence< uno::Sequence<rtl::OUString> >* pRowSeq = NULL;
1742cdf0e10cSrcweir
1743cdf0e10cSrcweir //! use pointer from any!
1744cdf0e10cSrcweir uno::Sequence< uno::Sequence<rtl::OUString> > aSequence;
1745cdf0e10cSrcweir if ( rNewRes >>= aSequence )
1746cdf0e10cSrcweir pRowSeq = &aSequence;
1747cdf0e10cSrcweir
1748cdf0e10cSrcweir if ( pRowSeq )
1749cdf0e10cSrcweir {
1750cdf0e10cSrcweir long nRowCount = pRowSeq->getLength();
1751cdf0e10cSrcweir const uno::Sequence<rtl::OUString>* pRowArr = pRowSeq->getConstArray();
1752cdf0e10cSrcweir long nMaxColCount = 0;
1753cdf0e10cSrcweir long nCol, nRow;
1754cdf0e10cSrcweir for (nRow=0; nRow<nRowCount; nRow++)
1755cdf0e10cSrcweir {
1756cdf0e10cSrcweir long nTmp = pRowArr[nRow].getLength();
1757cdf0e10cSrcweir if ( nTmp > nMaxColCount )
1758cdf0e10cSrcweir nMaxColCount = nTmp;
1759cdf0e10cSrcweir }
1760cdf0e10cSrcweir if ( nMaxColCount && nRowCount )
1761cdf0e10cSrcweir {
1762cdf0e10cSrcweir xMatrix = new ScMatrix(
1763cdf0e10cSrcweir static_cast<SCSIZE>(nMaxColCount),
1764cdf0e10cSrcweir static_cast<SCSIZE>(nRowCount) );
1765cdf0e10cSrcweir ScMatrix* pMatrix = xMatrix;
1766cdf0e10cSrcweir for (nRow=0; nRow<nRowCount; nRow++)
1767cdf0e10cSrcweir {
1768cdf0e10cSrcweir long nColCount = pRowArr[nRow].getLength();
1769cdf0e10cSrcweir const rtl::OUString* pColArr = pRowArr[nRow].getConstArray();
1770cdf0e10cSrcweir for (nCol=0; nCol<nColCount; nCol++)
1771cdf0e10cSrcweir pMatrix->PutString( String( pColArr[nCol] ),
1772cdf0e10cSrcweir static_cast<SCSIZE>(nCol),
1773cdf0e10cSrcweir static_cast<SCSIZE>(nRow) );
1774cdf0e10cSrcweir for (nCol=nColCount; nCol<nMaxColCount; nCol++)
1775cdf0e10cSrcweir pMatrix->PutString( EMPTY_STRING,
1776cdf0e10cSrcweir static_cast<SCSIZE>(nCol),
1777cdf0e10cSrcweir static_cast<SCSIZE>(nRow) );
1778cdf0e10cSrcweir }
1779cdf0e10cSrcweir }
1780cdf0e10cSrcweir }
1781cdf0e10cSrcweir }
1782cdf0e10cSrcweir else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<uno::Any> > *)0 ) ) )
1783cdf0e10cSrcweir {
1784cdf0e10cSrcweir xMatrix = ScSequenceToMatrix::CreateMixedMatrix( rNewRes );
1785cdf0e10cSrcweir }
1786cdf0e10cSrcweir
1787cdf0e10cSrcweir if (!xMatrix) // no array found
1788cdf0e10cSrcweir nErrCode = errNoValue; //! code for error in return type???
1789cdf0e10cSrcweir }
1790cdf0e10cSrcweir }
1791cdf0e10cSrcweir
1792cdf0e10cSrcweir
1793cdf0e10cSrcweir
1794cdf0e10cSrcweir //------------------------------------------------------------------------
1795