LibreOffice Module sc (master)  1
addincol.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
22 #include <vcl/svapp.hxx>
23 #include <vcl/settings.hxx>
24 #include <sfx2/objsh.hxx>
25 #include <unotools/charclass.hxx>
26 #include <sal/log.hxx>
27 #include <o3tl/string_view.hxx>
28 #include <osl/diagnose.h>
29 
30 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
31 #include <com/sun/star/frame/XModel.hpp>
32 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
33 #include <com/sun/star/lang/XServiceInfo.hpp>
34 #include <com/sun/star/lang/XServiceName.hpp>
35 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
36 #include <com/sun/star/lang/XSingleComponentFactory.hpp>
37 #include <com/sun/star/reflection/XIdlClass.hpp>
38 #include <com/sun/star/beans/XIntrospectionAccess.hpp>
39 #include <com/sun/star/beans/theIntrospection.hpp>
40 #include <com/sun/star/beans/MethodConcept.hpp>
41 #include <com/sun/star/beans/XPropertySet.hpp>
42 #include <com/sun/star/beans/PropertyValue.hpp>
43 #include <com/sun/star/table/XCellRange.hpp>
44 #include <com/sun/star/lang/Locale.hpp>
45 #include <com/sun/star/sheet/XCompatibilityNames.hpp>
46 #include <com/sun/star/sheet/NoConvergenceException.hpp>
47 #include <com/sun/star/sheet/XAddIn.hpp>
48 #include <com/sun/star/sheet/XVolatileResult.hpp>
49 
50 #include <addincol.hxx>
51 #include <addinhelpid.hxx>
52 #include <scmatrix.hxx>
53 #include <formula/errorcodes.hxx>
54 #include <formula/funcvarargs.h>
55 #include <optutil.hxx>
56 #include <addincfg.hxx>
57 #include <scmod.hxx>
58 #include <rangeseq.hxx>
59 #include <funcdesc.hxx>
60 #include <svl/sharedstring.hxx>
61 #include <formulaopt.hxx>
62 #include <memory>
63 
64 using namespace com::sun::star;
65 
66 #define SC_CALLERPOS_NONE (-1)
67 
68 ScUnoAddInFuncData::ScUnoAddInFuncData( const OUString& rNam, const OUString& rLoc,
69  const OUString& rDesc,
70  sal_uInt16 nCat, const OString& sHelp,
71  const uno::Reference<reflection::XIdlMethod>& rFunc,
72  const uno::Any& rO,
73  tools::Long nAC, const ScAddInArgDesc* pAD,
74  tools::Long nCP ) :
75  aOriginalName( rNam ),
76  aLocalName( rLoc ),
77  aUpperName( rNam ),
78  aUpperLocal( rLoc ),
79  aDescription( rDesc ),
80  xFunction( rFunc ),
81  aObject( rO ),
82  nArgCount( nAC ),
83  nCallerPos( nCP ),
84  nCategory( nCat ),
85  sHelpId( sHelp ),
86  bCompInitialized( false )
87 {
88  if ( nArgCount )
89  {
90  pArgDescs.reset( new ScAddInArgDesc[nArgCount] );
91  for (tools::Long i=0; i<nArgCount; i++)
92  pArgDescs[i] = pAD[i];
93  }
94 
97 }
98 
100 {
101 }
102 
103 const ::std::vector<ScUnoAddInFuncData::LocalizedName>& ScUnoAddInFuncData::GetCompNames() const
104 {
105  if ( !bCompInitialized )
106  {
107  // read sequence of compatibility names on demand
108 
109  uno::Reference<sheet::XAddIn> xAddIn;
110  if ( aObject >>= xAddIn )
111  {
112  uno::Reference<sheet::XCompatibilityNames> xComp( xAddIn, uno::UNO_QUERY );
113  if ( xComp.is() && xFunction.is() )
114  {
115  OUString aMethodName = xFunction->getName();
116  const uno::Sequence< sheet::LocalizedName> aCompNames( xComp->getCompatibilityNames( aMethodName ));
117  maCompNames.clear();
118  for (const sheet::LocalizedName& rCompName : aCompNames)
119  {
120  maCompNames.emplace_back(
121  LanguageTag::convertToBcp47( rCompName.Locale, false),
122  rCompName.Name);
123  }
124  }
125  }
126 
127  bCompInitialized = true; // also if not successful
128  }
129  return maCompNames;
130 }
131 
132 void ScUnoAddInFuncData::SetCompNames( ::std::vector< ScUnoAddInFuncData::LocalizedName >&& rNew )
133 {
134  OSL_ENSURE( !bCompInitialized, "SetCompNames after initializing" );
135 
136  maCompNames = std::move(rNew);
137 
138  bCompInitialized = true;
139 }
140 
141 bool ScUnoAddInFuncData::GetExcelName( LanguageType eDestLang, OUString& rRetExcelName ) const
142 {
143  const ::std::vector<LocalizedName>& rCompNames = GetCompNames();
144  if ( !rCompNames.empty() )
145  {
146  LanguageTag aLanguageTag( eDestLang);
147  const OUString& aSearch( aLanguageTag.getBcp47());
148 
149  // First, check exact match without fallback overhead.
150  ::std::vector<LocalizedName>::const_iterator itNames = std::find_if(rCompNames.begin(), rCompNames.end(),
151  [&aSearch](const LocalizedName& rName) { return rName.maLocale == aSearch; });
152  if (itNames != rCompNames.end())
153  {
154  rRetExcelName = (*itNames).maName;
155  return true;
156  }
157 
158  // Second, try match of fallback search with fallback locales,
159  // appending also 'en-US' and 'en' to search if not queried.
160  ::std::vector< OUString > aFallbackSearch( aLanguageTag.getFallbackStrings( true));
161  if (aSearch != "en-US")
162  {
163  aFallbackSearch.emplace_back("en-US");
164  if (aSearch != "en")
165  {
166  aFallbackSearch.emplace_back("en");
167  }
168  }
169  for (const auto& rSearch : aFallbackSearch)
170  {
171  for (const auto& rCompName : rCompNames)
172  {
173  // We checked already the full tag, start with second.
174  ::std::vector< OUString > aFallbackLocales( LanguageTag( rCompName.maLocale).getFallbackStrings( false));
175  if (std::find(aFallbackLocales.begin(), aFallbackLocales.end(), rSearch) != aFallbackLocales.end())
176  {
177  rRetExcelName = rCompName.maName;
178  return true;
179  }
180  }
181  }
182 
183  // Third, last resort, use first (default) entry.
184  rRetExcelName = rCompNames[0].maName;
185  return true;
186  }
187  return false;
188 }
189 
190 void ScUnoAddInFuncData::SetFunction( const uno::Reference< reflection::XIdlMethod>& rNewFunc, const uno::Any& rNewObj )
191 {
192  xFunction = rNewFunc;
193  aObject = rNewObj;
194 }
195 
197 {
198  nArgCount = nNewCount;
199  if ( nArgCount )
200  {
201  pArgDescs.reset( new ScAddInArgDesc[nArgCount] );
202  for (tools::Long i=0; i<nArgCount; i++)
203  pArgDescs[i] = pNewDescs[i];
204  }
205  else
206  pArgDescs.reset();
207 }
208 
210 {
211  nCallerPos = nNewPos;
212 }
213 
215  nFuncCount( 0 ),
216  bInitialized( false )
217 {
218 }
219 
221 {
222 }
223 
225 {
226  pExactHashMap.reset();
227  pNameHashMap.reset();
228  pLocalHashMap.reset();
229  ppFuncData.reset();
230  nFuncCount = 0;
231 
232  bInitialized = false;
233 }
234 
236 {
237  OSL_ENSURE( !bInitialized, "Initialize twice?" );
238 
239  uno::Reference<lang::XMultiServiceFactory> xManager = comphelper::getProcessServiceFactory();
240  uno::Reference<container::XContentEnumerationAccess> xEnAc( xManager, uno::UNO_QUERY );
241  if ( xEnAc.is() )
242  {
243  uno::Reference<container::XEnumeration> xEnum =
244  xEnAc->createContentEnumeration( "com.sun.star.sheet.AddIn" );
245  if ( xEnum.is() )
246  {
247  // loop through all AddIns
248  while ( xEnum->hasMoreElements() )
249  {
250  uno::Any aAddInAny = xEnum->nextElement();
251 
252  try
253  {
254  uno::Reference<uno::XInterface> xIntFac;
255  aAddInAny >>= xIntFac;
256  if ( xIntFac.is() )
257  {
258  // #i59984# try XSingleComponentFactory in addition to (old) XSingleServiceFactory,
259  // passing the context to the component
260 
261  uno::Reference<uno::XInterface> xInterface;
262  uno::Reference<uno::XComponentContext> xCtx(
264  uno::Reference<lang::XSingleComponentFactory> xCFac( xIntFac, uno::UNO_QUERY );
265  if (xCFac.is())
266  {
267  xInterface = xCFac->createInstanceWithContext(xCtx);
268  if (xInterface.is())
269  ReadFromAddIn( xInterface );
270  }
271 
272  if (!xInterface.is())
273  {
274  uno::Reference<lang::XSingleServiceFactory> xFac( xIntFac, uno::UNO_QUERY );
275  if ( xFac.is() )
276  {
277  xInterface = xFac->createInstance();
278  if (xInterface.is())
279  ReadFromAddIn( xInterface );
280  }
281  }
282  }
283  } catch ( const uno::Exception& ) {
284  SAL_WARN ( "sc", "Failed to initialize create instance of sheet.AddIn" );
285  }
286  }
287  }
288  }
289 
290  // ReadConfiguration is called after looking at the AddIn implementations.
291  // Duplicated are skipped (by using the service information, they don't have to be updated again
292  // when argument information is needed).
294 
295  bInitialized = true; // with or without functions
296 }
297 
298 static sal_uInt16 lcl_GetCategory( std::u16string_view rName )
299 {
300  static const char* aFuncNames[SC_FUNCGROUP_COUNT] =
301  {
302  // array index = ID - 1 (ID starts at 1)
303  // all upper case
304  "Database", // ID_FUNCTION_GRP_DATABASE
305  "Date&Time", // ID_FUNCTION_GRP_DATETIME
306  "Financial", // ID_FUNCTION_GRP_FINANCIAL
307  "Information", // ID_FUNCTION_GRP_INFO
308  "Logical", // ID_FUNCTION_GRP_LOGIC
309  "Mathematical", // ID_FUNCTION_GRP_MATH
310  "Matrix", // ID_FUNCTION_GRP_MATRIX
311  "Statistical", // ID_FUNCTION_GRP_STATISTIC
312  "Spreadsheet", // ID_FUNCTION_GRP_TABLE
313  "Text", // ID_FUNCTION_GRP_TEXT
314  "Add-In" // ID_FUNCTION_GRP_ADDINS
315  };
316  for (sal_uInt16 i=0; i<SC_FUNCGROUP_COUNT; i++)
317  if ( o3tl::equalsAscii( rName, aFuncNames[i] ) )
318  return i+1; // IDs start at 1
319 
320  return ID_FUNCTION_GRP_ADDINS; // if not found, use Add-In group
321 }
322 
323 constexpr OUStringLiteral CFGPATH_ADDINS = u"Office.CalcAddIns/AddInInfo";
324 constexpr OUStringLiteral CFGSTR_ADDINFUNCTIONS = u"AddInFunctions";
325 
326 #define CFG_FUNCPROP_DISPLAYNAME 0
327 #define CFG_FUNCPROP_DESCRIPTION 1
328 #define CFG_FUNCPROP_CATEGORY 2
329 #define CFG_FUNCPROP_COUNT 3
330 constexpr OUStringLiteral CFGSTR_DISPLAYNAME = u"DisplayName";
331 constexpr OUStringLiteral CFGSTR_DESCRIPTION = u"Description";
332 constexpr OUStringLiteral CFGSTR_CATEGORY = u"Category";
333 // CategoryDisplayName is ignored for now
334 
335 constexpr OUStringLiteral CFGSTR_COMPATIBILITYNAME = u"CompatibilityName";
336 constexpr OUStringLiteral CFGSTR_PARAMETERS = u"Parameters";
337 
339 {
340  // called only from Initialize
341 
342  ScAddInCfg& rAddInConfig = SC_MOD()->GetAddInCfg();
343 
344  // additional, temporary config item for the compatibility names
345  ScLinkConfigItem aAllLocalesConfig( CFGPATH_ADDINS, ConfigItemMode::AllLocales );
346  // CommitLink is not used (only reading values)
347 
348  const OUString sSlash('/');
349 
350  // get the list of add-ins (services)
351  const uno::Sequence<OUString> aServiceNames = rAddInConfig.GetNodeNames( "" );
352 
353  for ( const OUString& aServiceName : aServiceNames )
354  {
355  ScUnoAddInHelpIdGenerator aHelpIdGenerator( aServiceName );
356 
357  OUString aFunctionsPath(aServiceName + sSlash + CFGSTR_ADDINFUNCTIONS);
358 
359  uno::Sequence<OUString> aFunctionNames = rAddInConfig.GetNodeNames( aFunctionsPath );
360  sal_Int32 nNewCount = aFunctionNames.getLength();
361 
362  // allocate pointers
363 
364  tools::Long nOld = nFuncCount;
365  nFuncCount = nNewCount+nOld;
366  if ( nOld )
367  {
368  std::unique_ptr<std::unique_ptr<ScUnoAddInFuncData>[]> ppNew(new std::unique_ptr<ScUnoAddInFuncData>[nFuncCount]);
369  for (tools::Long i=0; i<nOld; i++)
370  ppNew[i] = std::move(ppFuncData[i]);
371  ppFuncData = std::move(ppNew);
372  }
373  else
374  ppFuncData.reset( new std::unique_ptr<ScUnoAddInFuncData>[nFuncCount] );
375 
376  //TODO: adjust bucket count?
377  if ( !pExactHashMap )
378  pExactHashMap.reset( new ScAddInHashMap );
379  if ( !pNameHashMap )
380  pNameHashMap.reset( new ScAddInHashMap );
381  if ( !pLocalHashMap )
382  pLocalHashMap.reset( new ScAddInHashMap );
383 
384  //TODO: get the function information in a single call for all functions?
385 
386  const OUString* pFuncNameArray = aFunctionNames.getConstArray();
387  for ( sal_Int32 nFuncPos = 0; nFuncPos < nNewCount; nFuncPos++ )
388  {
389  ppFuncData[nFuncPos+nOld] = nullptr;
390 
391  // stored function name: (service name).(function)
392  OUString aFuncName = aServiceName + "." + pFuncNameArray[nFuncPos];
393 
394  // skip the function if already known (read from old AddIn service)
395 
396  if ( pExactHashMap->find( aFuncName ) == pExactHashMap->end() )
397  {
398  OUString aLocalName;
399  OUString aDescription;
400  sal_uInt16 nCategory = ID_FUNCTION_GRP_ADDINS;
401 
402  // get direct information on the function
403 
404  OUString aFuncPropPath = aFunctionsPath + sSlash + pFuncNameArray[nFuncPos] + sSlash;
405 
406  uno::Sequence<OUString> aFuncPropNames{
407  (aFuncPropPath + CFGSTR_DISPLAYNAME), // CFG_FUNCPROP_DISPLAYNAME
408  (aFuncPropPath + CFGSTR_DESCRIPTION), // CFG_FUNCPROP_DESCRIPTION
409  (aFuncPropPath + CFGSTR_CATEGORY)}; // CFG_FUNCPROP_CATEGORY
410 
411  uno::Sequence<uno::Any> aFuncProperties = rAddInConfig.GetProperties( aFuncPropNames );
412  if ( aFuncProperties.getLength() == CFG_FUNCPROP_COUNT )
413  {
414  aFuncProperties[CFG_FUNCPROP_DISPLAYNAME] >>= aLocalName;
415  aFuncProperties[CFG_FUNCPROP_DESCRIPTION] >>= aDescription;
416 
417  OUString aCategoryName;
418  aFuncProperties[CFG_FUNCPROP_CATEGORY] >>= aCategoryName;
419  nCategory = lcl_GetCategory( aCategoryName );
420  }
421 
422  // get compatibility names
423 
424  ::std::vector<ScUnoAddInFuncData::LocalizedName> aCompNames;
425 
426  OUString aCompPath(aFuncPropPath + CFGSTR_COMPATIBILITYNAME);
427  uno::Sequence<OUString> aCompPropNames( &aCompPath, 1 );
428 
429  uno::Sequence<uno::Any> aCompProperties = aAllLocalesConfig.GetProperties( aCompPropNames );
430  if ( aCompProperties.getLength() == 1 )
431  {
432  uno::Sequence<beans::PropertyValue> aLocalEntries;
433  if ( aCompProperties[0] >>= aLocalEntries )
434  {
435  for ( const beans::PropertyValue& rConfig : std::as_const(aLocalEntries) )
436  {
437  // PropertyValue name is the locale ("convert" from
438  // string to canonicalize)
439  OUString aLocale( LanguageTag( rConfig.Name, true).getBcp47( false));
440  // PropertyValue value is the localized value (string in this case)
441  OUString aName;
442  rConfig.Value >>= aName;
443  aCompNames.emplace_back( aLocale, aName);
444  }
445  }
446  }
447 
448  // get argument info
449 
450  std::unique_ptr<ScAddInArgDesc[]> pVisibleArgs;
451  tools::Long nVisibleCount = 0;
452 
453  OUString aArgumentsPath(aFuncPropPath + CFGSTR_PARAMETERS);
454 
455  const uno::Sequence<OUString> aArgumentNames = rAddInConfig.GetNodeNames( aArgumentsPath );
456  sal_Int32 nArgumentCount = aArgumentNames.getLength();
457  if ( nArgumentCount )
458  {
459  // get DisplayName and Description for each argument
460  uno::Sequence<OUString> aArgPropNames( nArgumentCount * 2 );
461  OUString* pPropNameArray = aArgPropNames.getArray();
462 
463  sal_Int32 nIndex = 0;
464  for ( const OUString& rArgName : aArgumentNames )
465  {
466  OUString aOneArgPath = aArgumentsPath + sSlash + rArgName + sSlash;
467 
468  pPropNameArray[nIndex++] = aOneArgPath
470  pPropNameArray[nIndex++] = aOneArgPath
472  }
473 
474  uno::Sequence<uno::Any> aArgProperties = rAddInConfig.GetProperties( aArgPropNames );
475  if ( aArgProperties.getLength() == aArgPropNames.getLength() )
476  {
477  const OUString* pArgNameArray = aArgumentNames.getConstArray();
478  const uno::Any* pPropArray = aArgProperties.getConstArray();
479  OUString sDisplayName;
480  OUString sDescription;
481 
482  ScAddInArgDesc aDesc;
483  aDesc.eType = SC_ADDINARG_NONE; // arg type is not in configuration
484  aDesc.bOptional = false;
485 
486  nVisibleCount = nArgumentCount;
487  pVisibleArgs.reset(new ScAddInArgDesc[nVisibleCount]);
488 
489  nIndex = 0;
490  for ( sal_Int32 nArgument = 0; nArgument < nArgumentCount; nArgument++ )
491  {
492  pPropArray[nIndex++] >>= sDisplayName;
493  pPropArray[nIndex++] >>= sDescription;
494 
495  aDesc.aInternalName = pArgNameArray[nArgument];
496  aDesc.aName = sDisplayName;
497  aDesc.aDescription = sDescription;
498 
499  pVisibleArgs[nArgument] = aDesc;
500  }
501  }
502  }
503 
504  OString sHelpId = aHelpIdGenerator.GetHelpId( pFuncNameArray[nFuncPos] );
505 
506  uno::Reference<reflection::XIdlMethod> xFunc; // remains empty
507  uno::Any aObject; // also empty
508 
509  // create and insert into the array
510 
512  aFuncName, aLocalName, aDescription,
513  nCategory, sHelpId,
514  xFunc, aObject,
515  nVisibleCount, pVisibleArgs.get(), SC_CALLERPOS_NONE );
516 
517  pData->SetCompNames( std::move(aCompNames) );
518 
519  ppFuncData[nFuncPos+nOld].reset(pData);
520 
521  pExactHashMap->emplace(
522  pData->GetOriginalName(),
523  pData );
524  pNameHashMap->emplace(
525  pData->GetUpperName(),
526  pData );
527  pLocalHashMap->emplace(
528  pData->GetUpperLocal(),
529  pData );
530  }
531  }
532  }
533 }
534 
536 {
537  const OUString& aFullName = rFuncData.GetOriginalName();
538  sal_Int32 nPos = aFullName.lastIndexOf( '.' );
539  if ( nPos <= 0 )
540  return;
541 
542  OUString aServiceName = aFullName.copy( 0, nPos );
543 
544  try
545  {
546  uno::Reference<lang::XMultiServiceFactory> xServiceFactory = comphelper::getProcessServiceFactory();
547  uno::Reference<uno::XInterface> xInterface( xServiceFactory->createInstance( aServiceName ) );
548 
549  if (xInterface.is())
550  UpdateFromAddIn( xInterface, aServiceName );
551  }
552  catch (const uno::Exception &)
553  {
554  SAL_WARN ("sc", "Failed to create addin component '"
555  << aServiceName << "'");
556  }
557 }
558 
559 bool ScUnoAddInCollection::GetExcelName( const OUString& rCalcName,
560  LanguageType eDestLang, OUString& rRetExcelName )
561 {
562  const ScUnoAddInFuncData* pFuncData = GetFuncData( rCalcName );
563  if ( pFuncData )
564  return pFuncData->GetExcelName( eDestLang, rRetExcelName);
565  return false;
566 }
567 
568 bool ScUnoAddInCollection::GetCalcName( const OUString& rExcelName, OUString& rRetCalcName )
569 {
570  if (!bInitialized)
571  Initialize();
572 
573  OUString aUpperCmp = ScGlobal::getCharClass().uppercase(rExcelName);
574 
575  for (tools::Long i=0; i<nFuncCount; i++)
576  {
577  ScUnoAddInFuncData* pFuncData = ppFuncData[i].get();
578  if ( pFuncData )
579  {
580  const ::std::vector<ScUnoAddInFuncData::LocalizedName>& rNames = pFuncData->GetCompNames();
581  auto bFound = std::any_of(rNames.begin(), rNames.end(),
582  [&aUpperCmp](const ScUnoAddInFuncData::LocalizedName& rName) {
583  return ScGlobal::getCharClass().uppercase( rName.maName ) == aUpperCmp; });
584  if (bFound)
585  {
586  //TODO: store upper case for comparing?
587 
588  // use the first function that has this name for any language
589  rRetCalcName = pFuncData->GetOriginalName();
590  return true;
591  }
592  }
593  }
594  return false;
595 }
596 
597 static bool IsTypeName( std::u16string_view rName, const uno::Type& rType )
598 {
599  return rName == rType.getTypeName();
600 }
601 
602 static bool lcl_ValidReturnType( const uno::Reference<reflection::XIdlClass>& xClass )
603 {
604  // this must match with ScUnoAddInCall::SetResult
605 
606  if ( !xClass.is() ) return false;
607 
608  switch (xClass->getTypeClass())
609  {
610  case uno::TypeClass_ANY: // variable type
611  case uno::TypeClass_ENUM: //TODO: ???
612  case uno::TypeClass_BOOLEAN:
613  case uno::TypeClass_CHAR:
614  case uno::TypeClass_BYTE:
615  case uno::TypeClass_SHORT:
616  case uno::TypeClass_UNSIGNED_SHORT:
617  case uno::TypeClass_LONG:
618  case uno::TypeClass_UNSIGNED_LONG:
619  case uno::TypeClass_FLOAT:
620  case uno::TypeClass_DOUBLE:
621  case uno::TypeClass_STRING:
622  return true; // values or string
623 
624  case uno::TypeClass_INTERFACE:
625  {
626  // return type XInterface may contain a XVolatileResult
627  //TODO: XIdlClass needs getType() method!
628 
629  OUString sName = xClass->getName();
630  return (
633  }
634 
635  default:
636  {
637  // nested sequences for arrays
638  //TODO: XIdlClass needs getType() method!
639 
640  OUString sName = xClass->getName();
641  return (
642  IsTypeName( sName, cppu::UnoType<uno::Sequence< uno::Sequence<sal_Int32> >>::get() ) ||
643  IsTypeName( sName, cppu::UnoType<uno::Sequence< uno::Sequence<double> >>::get() ) ||
644  IsTypeName( sName, cppu::UnoType<uno::Sequence< uno::Sequence<OUString> >>::get() ) ||
645  IsTypeName( sName, cppu::UnoType<uno::Sequence< uno::Sequence<uno::Any> >>::get() ) );
646  }
647  }
648 }
649 
650 static ScAddInArgumentType lcl_GetArgType( const uno::Reference<reflection::XIdlClass>& xClass )
651 {
652  if (!xClass.is())
653  return SC_ADDINARG_NONE;
654 
655  uno::TypeClass eType = xClass->getTypeClass();
656 
657  if ( eType == uno::TypeClass_LONG ) //TODO: other integer types?
658  return SC_ADDINARG_INTEGER;
659 
660  if ( eType == uno::TypeClass_DOUBLE )
661  return SC_ADDINARG_DOUBLE;
662 
663  if ( eType == uno::TypeClass_STRING )
664  return SC_ADDINARG_STRING;
665 
666  //TODO: XIdlClass needs getType() method!
667  OUString sName = xClass->getName();
668 
669  if (IsTypeName( sName, cppu::UnoType<uno::Sequence< uno::Sequence<sal_Int32> >>::get() ))
671 
672  if (IsTypeName( sName, cppu::UnoType<uno::Sequence< uno::Sequence<double> >>::get() ))
674 
675  if (IsTypeName( sName, cppu::UnoType<uno::Sequence< uno::Sequence<OUString> >>::get() ))
677 
678  if (IsTypeName( sName, cppu::UnoType<uno::Sequence< uno::Sequence<uno::Any> >>::get() ))
680 
683 
685  return SC_ADDINARG_CELLRANGE;
686 
688  return SC_ADDINARG_CALLER;
689 
690  if (IsTypeName( sName, cppu::UnoType<uno::Sequence<uno::Any>>::get() ))
691  return SC_ADDINARG_VARARGS;
692 
693  return SC_ADDINARG_NONE;
694 }
695 
696 void ScUnoAddInCollection::ReadFromAddIn( const uno::Reference<uno::XInterface>& xInterface )
697 {
698  uno::Reference<sheet::XAddIn> xAddIn( xInterface, uno::UNO_QUERY );
699  uno::Reference<lang::XServiceName> xName( xInterface, uno::UNO_QUERY );
700  if ( !(xAddIn.is() && xName.is()) )
701  return;
702 
703  // fdo50118 when GetUseEnglishFunctionName() returns true, set the
704  // locale to en-US to get English function names
705  if ( SC_MOD()->GetFormulaOptions().GetUseEnglishFuncName() )
706  xAddIn->setLocale( lang::Locale( "en", "US", ""));
707  else
708  xAddIn->setLocale( Application::GetSettings().GetUILanguageTag().getLocale());
709 
710  OUString aServiceName( xName->getServiceName() );
711  ScUnoAddInHelpIdGenerator aHelpIdGenerator( aServiceName );
712 
713  //TODO: pass XIntrospection to ReadFromAddIn
714 
715  uno::Reference<uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
716 
717  uno::Reference<beans::XIntrospection> xIntro = beans::theIntrospection::get( xContext );
718  uno::Any aObject;
719  aObject <<= xAddIn;
720  uno::Reference<beans::XIntrospectionAccess> xAcc = xIntro->inspect(aObject);
721  if (!xAcc.is())
722  return;
723 
724  uno::Sequence< uno::Reference<reflection::XIdlMethod> > aMethods =
725  xAcc->getMethods( beans::MethodConcept::ALL );
726  tools::Long nNewCount = aMethods.getLength();
727  if ( !nNewCount )
728  return;
729 
730  tools::Long nOld = nFuncCount;
731  nFuncCount = nNewCount+nOld;
732  if ( nOld )
733  {
734  std::unique_ptr<std::unique_ptr<ScUnoAddInFuncData>[]> ppNew(new std::unique_ptr<ScUnoAddInFuncData>[nFuncCount]);
735  for (tools::Long i=0; i<nOld; i++)
736  ppNew[i] = std::move(ppFuncData[i]);
737  ppFuncData = std::move(ppNew);
738  }
739  else
740  ppFuncData.reset(new std::unique_ptr<ScUnoAddInFuncData>[nFuncCount]);
741 
742  //TODO: adjust bucket count?
743  if ( !pExactHashMap )
744  pExactHashMap.reset( new ScAddInHashMap );
745  if ( !pNameHashMap )
746  pNameHashMap.reset( new ScAddInHashMap );
747  if ( !pLocalHashMap )
748  pLocalHashMap.reset( new ScAddInHashMap );
749 
750  const uno::Reference<reflection::XIdlMethod>* pArray = aMethods.getConstArray();
751  for (tools::Long nFuncPos=0; nFuncPos<nNewCount; nFuncPos++)
752  {
753  ppFuncData[nFuncPos+nOld] = nullptr;
754 
755  uno::Reference<reflection::XIdlMethod> xFunc = pArray[nFuncPos];
756  if (xFunc.is())
757  {
758  // leave out internal functions
759  uno::Reference<reflection::XIdlClass> xClass =
760  xFunc->getDeclaringClass();
761  bool bSkip = true;
762  if ( xClass.is() )
763  {
764  //TODO: XIdlClass needs getType() method!
765  OUString sName = xClass->getName();
766  bSkip = (
767  IsTypeName( sName,
769  IsTypeName( sName,
771  IsTypeName( sName,
773  IsTypeName( sName,
775  }
776  if (!bSkip)
777  {
778  uno::Reference<reflection::XIdlClass> xReturn =
779  xFunc->getReturnType();
780  if ( !lcl_ValidReturnType( xReturn ) )
781  bSkip = true;
782  }
783  if (!bSkip)
784  {
785  OUString aFuncU = xFunc->getName();
786 
787  // stored function name: (service name).(function)
788  OUString aFuncName = aServiceName + "." + aFuncU;
789 
790  bool bValid = true;
791  tools::Long nVisibleCount = 0;
792  tools::Long nCallerPos = SC_CALLERPOS_NONE;
793 
794  uno::Sequence<reflection::ParamInfo> aParams =
795  xFunc->getParameterInfos();
796  tools::Long nParamCount = aParams.getLength();
797  const reflection::ParamInfo* pParArr = aParams.getConstArray();
798  tools::Long nParamPos;
799  for (nParamPos=0; nParamPos<nParamCount; nParamPos++)
800  {
801  if ( pParArr[nParamPos].aMode != reflection::ParamMode_IN )
802  bValid = false;
803  uno::Reference<reflection::XIdlClass> xParClass =
804  pParArr[nParamPos].aType;
805  ScAddInArgumentType eArgType = lcl_GetArgType( xParClass );
806  if ( eArgType == SC_ADDINARG_NONE )
807  bValid = false;
808  else if ( eArgType == SC_ADDINARG_CALLER )
809  nCallerPos = nParamPos;
810  else
811  ++nVisibleCount;
812  }
813  if (bValid)
814  {
815  sal_uInt16 nCategory = lcl_GetCategory(
816  xAddIn->getProgrammaticCategoryName( aFuncU ) );
817 
818  OString sHelpId = aHelpIdGenerator.GetHelpId( aFuncU );
819 
820  OUString aLocalName;
821  try
822  {
823  aLocalName = xAddIn->
824  getDisplayFunctionName( aFuncU );
825  }
826  catch(uno::Exception&)
827  {
828  aLocalName = "###";
829  }
830 
831  OUString aDescription;
832  try
833  {
834  aDescription = xAddIn->
835  getFunctionDescription( aFuncU );
836  }
837  catch(uno::Exception&)
838  {
839  aDescription = "###";
840  }
841 
842  std::unique_ptr<ScAddInArgDesc[]> pVisibleArgs;
843  if ( nVisibleCount > 0 )
844  {
845  ScAddInArgDesc aDesc;
846  pVisibleArgs.reset(new ScAddInArgDesc[nVisibleCount]);
847  tools::Long nDestPos = 0;
848  for (nParamPos=0; nParamPos<nParamCount; nParamPos++)
849  {
850  uno::Reference<reflection::XIdlClass> xParClass =
851  pParArr[nParamPos].aType;
852  ScAddInArgumentType eArgType = lcl_GetArgType( xParClass );
853  if ( eArgType != SC_ADDINARG_CALLER )
854  {
855  OUString aArgName;
856  try
857  {
858  aArgName = xAddIn->
859  getDisplayArgumentName( aFuncU, nParamPos );
860  }
861  catch(uno::Exception&)
862  {
863  aArgName = "###";
864  }
865  OUString aArgDesc;
866  try
867  {
868  aArgDesc = xAddIn->
869  getArgumentDescription( aFuncU, nParamPos );
870  }
871  catch(uno::Exception&)
872  {
873  aArgDesc = "###";
874  }
875 
876  bool bOptional =
877  ( eArgType == SC_ADDINARG_VALUE_OR_ARRAY ||
878  eArgType == SC_ADDINARG_VARARGS );
879 
880  aDesc.eType = eArgType;
881  aDesc.aName = aArgName;
882  aDesc.aDescription = aArgDesc;
883  aDesc.bOptional = bOptional;
884  //TODO: initialize aInternalName only from config?
885  aDesc.aInternalName = pParArr[nParamPos].aName;
886 
887  pVisibleArgs[nDestPos++] = aDesc;
888  }
889  }
890  OSL_ENSURE( nDestPos==nVisibleCount, "wrong count" );
891  }
892 
893  ppFuncData[nFuncPos+nOld].reset( new ScUnoAddInFuncData(
894  aFuncName, aLocalName, aDescription,
895  nCategory, sHelpId,
896  xFunc, aObject,
897  nVisibleCount, pVisibleArgs.get(), nCallerPos ) );
898 
899  const ScUnoAddInFuncData* pData =
900  ppFuncData[nFuncPos+nOld].get();
901  pExactHashMap->emplace(
902  pData->GetOriginalName(),
903  pData );
904  pNameHashMap->emplace(
905  pData->GetUpperName(),
906  pData );
907  pLocalHashMap->emplace(
908  pData->GetUpperLocal(),
909  pData );
910  }
911  }
912  }
913  }
914 }
915 
916 static void lcl_UpdateFunctionList( const ScFunctionList& rFunctionList, const ScUnoAddInFuncData& rFuncData )
917 {
918  const OUString& aCompare = rFuncData.GetUpperLocal(); // as used in FillFunctionDescFromData
919 
920  sal_uLong nCount = rFunctionList.GetCount();
921  for (sal_uLong nPos=0; nPos<nCount; nPos++)
922  {
923  const ScFuncDesc* pDesc = rFunctionList.GetFunction( nPos );
924  if ( pDesc && pDesc->mxFuncName && *pDesc->mxFuncName == aCompare )
925  {
926  ScUnoAddInCollection::FillFunctionDescFromData( rFuncData, *const_cast<ScFuncDesc*>(pDesc) );
927  break;
928  }
929  }
930 }
931 
932 static const ScAddInArgDesc* lcl_FindArgDesc( const ScUnoAddInFuncData& rFuncData, std::u16string_view rArgIntName )
933 {
934  tools::Long nArgCount = rFuncData.GetArgumentCount();
935  const ScAddInArgDesc* pArguments = rFuncData.GetArguments();
936  for (tools::Long nPos=0; nPos<nArgCount; nPos++)
937  {
938  if ( pArguments[nPos].aInternalName == rArgIntName )
939  return &pArguments[nPos];
940  }
941  return nullptr;
942 }
943 
944 void ScUnoAddInCollection::UpdateFromAddIn( const uno::Reference<uno::XInterface>& xInterface,
945  std::u16string_view rServiceName )
946 {
947  uno::Reference<lang::XLocalizable> xLoc( xInterface, uno::UNO_QUERY );
948  if ( xLoc.is() ) // optional in new add-ins
949  {
950  // fdo50118 when GetUseEnglishFunctionName() returns true, set the
951  // locale to en-US to get English function names
952  if ( SC_MOD()->GetFormulaOptions().GetUseEnglishFuncName() )
953  xLoc->setLocale( lang::Locale( "en", "US", ""));
954  else
955  xLoc->setLocale( Application::GetSettings().GetUILanguageTag().getLocale());
956  }
957 
958  // if function list was already initialized, it must be updated
959 
960  ScFunctionList* pFunctionList = nullptr;
962  pFunctionList = ScGlobal::GetStarCalcFunctionList();
963 
964  // only get the function information from Introspection
965 
966  uno::Reference<uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
967 
968  uno::Reference<beans::XIntrospection> xIntro = beans::theIntrospection::get(xContext);
969  uno::Any aObject;
970  aObject <<= xInterface;
971  uno::Reference<beans::XIntrospectionAccess> xAcc = xIntro->inspect(aObject);
972  if (!xAcc.is())
973  return;
974 
975  const uno::Sequence< uno::Reference<reflection::XIdlMethod> > aMethods =
976  xAcc->getMethods( beans::MethodConcept::ALL );
977  for (const uno::Reference<reflection::XIdlMethod>& xFunc : aMethods)
978  {
979  if (xFunc.is())
980  {
981  OUString aFuncU = xFunc->getName();
982 
983  // stored function name: (service name).(function)
984  OUString aFuncName = OUString::Concat(rServiceName) + "." + aFuncU;
985 
986  // internal names are skipped because no FuncData exists
987  ScUnoAddInFuncData* pOldData = const_cast<ScUnoAddInFuncData*>( GetFuncData( aFuncName ) );
988  if ( pOldData )
989  {
990  // Create new (complete) argument info.
991  // As in ReadFromAddIn, the reflection information is authoritative.
992  // Local names and descriptions from pOldData are looked up using the
993  // internal argument name.
994 
995  bool bValid = true;
996  tools::Long nVisibleCount = 0;
997  tools::Long nCallerPos = SC_CALLERPOS_NONE;
998 
999  const uno::Sequence<reflection::ParamInfo> aParams =
1000  xFunc->getParameterInfos();
1001  tools::Long nParamCount = aParams.getLength();
1002  const reflection::ParamInfo* pParArr = aParams.getConstArray();
1003  for (tools::Long nParamPos=0; nParamPos<nParamCount; nParamPos++)
1004  {
1005  if ( pParArr[nParamPos].aMode != reflection::ParamMode_IN )
1006  bValid = false;
1007  uno::Reference<reflection::XIdlClass> xParClass =
1008  pParArr[nParamPos].aType;
1009  ScAddInArgumentType eArgType = lcl_GetArgType( xParClass );
1010  if ( eArgType == SC_ADDINARG_NONE )
1011  bValid = false;
1012  else if ( eArgType == SC_ADDINARG_CALLER )
1013  nCallerPos = nParamPos;
1014  else
1015  ++nVisibleCount;
1016  }
1017  if (bValid)
1018  {
1019  std::unique_ptr<ScAddInArgDesc[]> pVisibleArgs;
1020  if ( nVisibleCount > 0 )
1021  {
1022  ScAddInArgDesc aDesc;
1023  pVisibleArgs.reset(new ScAddInArgDesc[nVisibleCount]);
1024  tools::Long nDestPos = 0;
1025  for (const auto& rParam : aParams)
1026  {
1027  uno::Reference<reflection::XIdlClass> xParClass =
1028  rParam.aType;
1029  ScAddInArgumentType eArgType = lcl_GetArgType( xParClass );
1030  if ( eArgType != SC_ADDINARG_CALLER )
1031  {
1032  const ScAddInArgDesc* pOldArgDesc =
1033  lcl_FindArgDesc( *pOldData, rParam.aName );
1034  if ( pOldArgDesc )
1035  {
1036  aDesc.aName = pOldArgDesc->aName;
1037  aDesc.aDescription = pOldArgDesc->aDescription;
1038  }
1039  else
1040  aDesc.aName = aDesc.aDescription = "###";
1041 
1042  bool bOptional =
1043  ( eArgType == SC_ADDINARG_VALUE_OR_ARRAY ||
1044  eArgType == SC_ADDINARG_VARARGS );
1045 
1046  aDesc.eType = eArgType;
1047  aDesc.bOptional = bOptional;
1048  //TODO: initialize aInternalName only from config?
1049  aDesc.aInternalName = rParam.aName;
1050 
1051  pVisibleArgs[nDestPos++] = aDesc;
1052  }
1053  }
1054  OSL_ENSURE( nDestPos==nVisibleCount, "wrong count" );
1055  }
1056 
1057  pOldData->SetFunction( xFunc, aObject );
1058  pOldData->SetArguments( nVisibleCount, pVisibleArgs.get() );
1059  pOldData->SetCallerPos( nCallerPos );
1060 
1061  if ( pFunctionList )
1062  lcl_UpdateFunctionList( *pFunctionList, *pOldData );
1063  }
1064  }
1065  }
1066  }
1067 }
1068 
1069 OUString ScUnoAddInCollection::FindFunction( const OUString& rUpperName, bool bLocalFirst )
1070 {
1071  if (!bInitialized)
1072  Initialize();
1073 
1074  if (nFuncCount == 0)
1075  return OUString();
1076 
1077  if ( bLocalFirst )
1078  {
1079  // first scan all local names (used for entering formulas)
1080 
1081  ScAddInHashMap::const_iterator iLook( pLocalHashMap->find( rUpperName ) );
1082  if ( iLook != pLocalHashMap->end() )
1083  return iLook->second->GetOriginalName();
1084  }
1085  else
1086  {
1087  // first scan international names (used when calling a function)
1088  //TODO: before that, check for exact match???
1089 
1090  ScAddInHashMap::const_iterator iLook( pNameHashMap->find( rUpperName ) );
1091  if ( iLook != pNameHashMap->end() )
1092  return iLook->second->GetOriginalName();
1093 
1094  // after that, scan all local names (to allow replacing old AddIns with Uno)
1095 
1096  iLook = pLocalHashMap->find( rUpperName );
1097  if ( iLook != pLocalHashMap->end() )
1098  return iLook->second->GetOriginalName();
1099  }
1100 
1101  return OUString();
1102 }
1103 
1104 const ScUnoAddInFuncData* ScUnoAddInCollection::GetFuncData( const OUString& rName, bool bComplete )
1105 {
1106  if (!bInitialized)
1107  Initialize();
1108 
1109  // rName must be the exact internal name
1110 
1111  ScAddInHashMap::const_iterator iLook( pExactHashMap->find( rName ) );
1112  if ( iLook != pExactHashMap->end() )
1113  {
1114  const ScUnoAddInFuncData* pFuncData = iLook->second;
1115 
1116  if ( bComplete && !pFuncData->GetFunction().is() ) //TODO: extra flag?
1117  LoadComponent( *pFuncData );
1118 
1119  return pFuncData;
1120  }
1121 
1122  return nullptr;
1123 }
1124 
1126 {
1127  if (!bInitialized)
1128  Initialize();
1129 
1130  if (nIndex < nFuncCount)
1131  return ppFuncData[nIndex].get();
1132  return nullptr;
1133 }
1134 
1136 {
1137  if (!bInitialized)
1138  Initialize();
1139 
1140  // modify rName - input: exact name
1141 
1142  ScAddInHashMap::const_iterator iLook( pExactHashMap->find( rName ) );
1143  if ( iLook != pExactHashMap->end() )
1144  rName = iLook->second->GetUpperLocal(); //TODO: upper?
1145 }
1146 
1148 {
1149  if (!bInitialized)
1150  Initialize();
1151 
1152  return nFuncCount;
1153 }
1154 
1156 {
1157  if (!bInitialized)
1158  Initialize();
1159 
1160  if (nFunc >= nFuncCount || !ppFuncData[nFunc])
1161  return false;
1162 
1163  const ScUnoAddInFuncData& rFuncData = *ppFuncData[nFunc];
1164 
1165  return FillFunctionDescFromData( rFuncData, rDesc );
1166 }
1167 
1169 {
1170  rDesc.Clear();
1171 
1172  bool bIncomplete = !rFuncData.GetFunction().is(); //TODO: extra flag?
1173 
1174  tools::Long nArgCount = rFuncData.GetArgumentCount();
1175  if ( nArgCount > SAL_MAX_UINT16 )
1176  return false;
1177 
1178  if ( bIncomplete )
1179  nArgCount = 0; // if incomplete, fill without argument info (no wrong order)
1180 
1181  // nFIndex is set from outside
1182 
1183  rDesc.mxFuncName = rFuncData.GetUpperLocal(); //TODO: upper?
1184  rDesc.nCategory = rFuncData.GetCategory();
1185  rDesc.sHelpId = rFuncData.GetHelpId();
1186 
1187  OUString aDesc = rFuncData.GetDescription();
1188  if (aDesc.isEmpty())
1189  aDesc = rFuncData.GetLocalName(); // use name if no description is available
1190  rDesc.mxFuncDesc = aDesc ;
1191 
1192  // AddInArgumentType_CALLER is already left out in FuncData
1193 
1194  rDesc.nArgCount = static_cast<sal_uInt16>(nArgCount);
1195  if ( nArgCount )
1196  {
1197  bool bMultiple = false;
1198  const ScAddInArgDesc* pArgs = rFuncData.GetArguments();
1199 
1200  rDesc.maDefArgNames.clear();
1201  rDesc.maDefArgNames.resize(nArgCount);
1202  rDesc.maDefArgDescs.clear();
1203  rDesc.maDefArgDescs.resize(nArgCount);
1204  rDesc.pDefArgFlags = new ScFuncDesc::ParameterFlags[nArgCount];
1205  for ( tools::Long nArg=0; nArg<nArgCount; nArg++ )
1206  {
1207  rDesc.maDefArgNames[nArg] = pArgs[nArg].aName;
1208  rDesc.maDefArgDescs[nArg] = pArgs[nArg].aDescription;
1209  rDesc.pDefArgFlags[nArg].bOptional = pArgs[nArg].bOptional;
1210 
1211  // no empty names...
1212  if ( rDesc.maDefArgNames[nArg].isEmpty() )
1213  {
1214  OUString aDefName = "arg" + OUString::number( nArg+1 );
1215  rDesc.maDefArgNames[nArg] = aDefName;
1216  }
1217 
1218  // last argument repeated?
1219  if ( nArg+1 == nArgCount && ( pArgs[nArg].eType == SC_ADDINARG_VARARGS ) )
1220  bMultiple = true;
1221  }
1222 
1223  if ( bMultiple )
1224  rDesc.nArgCount += VAR_ARGS - 1; // VAR_ARGS means just one repeated arg
1225  }
1226 
1227  rDesc.bIncomplete = bIncomplete;
1228 
1229  return true;
1230 }
1231 
1234  bValidCount( false ),
1235  nErrCode( FormulaError::NoCode ), // before function was called
1236  bHasString( true ),
1237  fValue( 0.0 ),
1238  xMatrix( nullptr )
1239 {
1240  pFuncData = rColl.GetFuncData( rName, true ); // need fully initialized data
1241  OSL_ENSURE( pFuncData, "Function Data missing" );
1242  if ( !pFuncData )
1243  return;
1244 
1245  tools::Long nDescCount = pFuncData->GetArgumentCount();
1246  const ScAddInArgDesc* pArgs = pFuncData->GetArguments();
1247 
1248  // is aVarArg sequence needed?
1249  if ( nParamCount >= nDescCount && nDescCount > 0 &&
1250  pArgs[nDescCount-1].eType == SC_ADDINARG_VARARGS )
1251  {
1252  tools::Long nVarCount = nParamCount - ( nDescCount - 1 ); // size of last argument
1253  aVarArg.realloc( nVarCount );
1254  bValidCount = true;
1255  }
1256  else if ( nParamCount <= nDescCount )
1257  {
1258  // all args behind nParamCount must be optional
1259  bValidCount = true;
1260  for (tools::Long i=nParamCount; i<nDescCount; i++)
1261  if ( !pArgs[i].bOptional )
1262  bValidCount = false;
1263  }
1264  // else invalid (too many arguments)
1265 
1266  if ( bValidCount )
1267  aArgs.realloc( nDescCount ); // sequence must always match function signature
1268 }
1269 
1271 {
1272  // pFuncData is deleted with ScUnoAddInCollection
1273 }
1274 
1276 {
1277  if ( pFuncData )
1278  {
1280  const ScAddInArgDesc* pArgs = pFuncData->GetArguments();
1281 
1282  // if last arg is sequence, use "any" type
1283  if ( nCount > 0 && nPos >= nCount-1 && pArgs[nCount-1].eType == SC_ADDINARG_VARARGS )
1285 
1286  if ( nPos < nCount )
1287  return pArgs[nPos].eType;
1288  }
1289  return SC_ADDINARG_VALUE_OR_ARRAY; //TODO: error code !!!!
1290 }
1291 
1293 {
1295 }
1296 
1297 void ScUnoAddInCall::SetCaller( const uno::Reference<uno::XInterface>& rInterface )
1298 {
1299  xCaller = rInterface;
1300 }
1301 
1303 {
1304  if (pObjSh)
1305  {
1306  uno::Reference<uno::XInterface> xInt( pObjSh->GetBaseModel(), uno::UNO_QUERY );
1307  SetCaller( xInt );
1308  }
1309 }
1310 
1311 void ScUnoAddInCall::SetParam( tools::Long nPos, const uno::Any& rValue )
1312 {
1313  if ( !pFuncData )
1314  return;
1315 
1317  const ScAddInArgDesc* pArgs = pFuncData->GetArguments();
1318  if ( nCount > 0 && nPos >= nCount-1 && pArgs[nCount-1].eType == SC_ADDINARG_VARARGS )
1319  {
1320  tools::Long nVarPos = nPos-(nCount-1);
1321  if ( nVarPos < aVarArg.getLength() )
1322  aVarArg.getArray()[nVarPos] = rValue;
1323  else
1324  {
1325  OSL_FAIL("wrong argument number");
1326  }
1327  }
1328  else if ( nPos < aArgs.getLength() )
1329  aArgs.getArray()[nPos] = rValue;
1330  else
1331  {
1332  OSL_FAIL("wrong argument number");
1333  }
1334 }
1335 
1337 {
1338  if ( !pFuncData )
1339  return;
1340 
1342  const ScAddInArgDesc* pArgs = pFuncData->GetArguments();
1343  if ( nCount > 0 && pArgs[nCount-1].eType == SC_ADDINARG_VARARGS )
1344  {
1345  // insert aVarArg as last argument
1346  //TODO: after inserting caller (to prevent copying twice)?
1347 
1348  OSL_ENSURE( aArgs.getLength() == nCount, "wrong argument count" );
1349  aArgs.getArray()[nCount-1] <<= aVarArg;
1350  }
1351 
1353  {
1354  uno::Any aCallerAny;
1355  aCallerAny <<= xCaller;
1356 
1357  tools::Long nUserLen = aArgs.getLength();
1358  tools::Long nCallPos = pFuncData->GetCallerPos();
1359  if (nCallPos>nUserLen) // should not happen
1360  {
1361  OSL_FAIL("wrong CallPos");
1362  nCallPos = nUserLen;
1363  }
1364 
1365  tools::Long nDestLen = nUserLen + 1;
1366  uno::Sequence<uno::Any> aRealArgs( nDestLen );
1367  uno::Any* pDest = aRealArgs.getArray();
1368 
1369  pDest = std::copy_n(std::cbegin(aArgs), nCallPos, pDest);
1370  *pDest = aCallerAny;
1371  std::copy(std::next(std::cbegin(aArgs), nCallPos), std::cend(aArgs), std::next(pDest));
1372 
1373  ExecuteCallWithArgs( aRealArgs );
1374  }
1375  else
1377 }
1378 
1379 void ScUnoAddInCall::ExecuteCallWithArgs(uno::Sequence<uno::Any>& rCallArgs)
1380 {
1381  // rCallArgs may not match argument descriptions (because of caller)
1382 
1383  uno::Reference<reflection::XIdlMethod> xFunction;
1384  uno::Any aObject;
1385  if ( pFuncData )
1386  {
1387  xFunction = pFuncData->GetFunction();
1388  aObject = pFuncData->GetObject();
1389  }
1390 
1391  if ( !xFunction.is() )
1392  return;
1393 
1394  uno::Any aAny;
1395  nErrCode = FormulaError::NONE;
1396 
1397  try
1398  {
1399  aAny = xFunction->invoke( aObject, rCallArgs );
1400  }
1401  catch(lang::IllegalArgumentException&)
1402  {
1403  nErrCode = FormulaError::IllegalArgument;
1404  }
1405  catch(const reflection::InvocationTargetException& rWrapped)
1406  {
1407  if ( rWrapped.TargetException.getValueType().equals(
1409  nErrCode = FormulaError::IllegalArgument;
1410  else if ( rWrapped.TargetException.getValueType().equals(
1412  nErrCode = FormulaError::NoConvergence;
1413  else
1414  nErrCode = FormulaError::NoValue;
1415  }
1416  catch(uno::Exception&)
1417  {
1418  nErrCode = FormulaError::NoValue;
1419  }
1420 
1421  if (nErrCode == FormulaError::NONE)
1422  SetResult( aAny ); // convert result to Calc types
1423 }
1424 
1425 template <typename T>
1426 static sal_Int32 lcl_GetMaxColCount(const uno::Sequence< uno::Sequence<T> >* pRowSeq)
1427 {
1428  if (!pRowSeq->hasElements())
1429  return 0;
1430 
1431  auto pRow = std::max_element(pRowSeq->begin(), pRowSeq->end(),
1432  [](const uno::Sequence<T>& a, const uno::Sequence<T>& b) {
1433  return a.getLength() < b.getLength(); });
1434  return pRow->getLength();
1435 }
1436 
1437 void ScUnoAddInCall::SetResult( const uno::Any& rNewRes )
1438 {
1439  nErrCode = FormulaError::NONE;
1440  xVarRes = nullptr;
1441 
1442  // Reflection* pRefl = rNewRes.getReflection();
1443 
1444  uno::TypeClass eClass = rNewRes.getValueTypeClass();
1445  const uno::Type& aType = rNewRes.getValueType();
1446  switch (eClass)
1447  {
1448  case uno::TypeClass_VOID:
1449  nErrCode = FormulaError::NotAvailable; // #NA
1450  break;
1451 
1452  case uno::TypeClass_ENUM:
1453  case uno::TypeClass_BOOLEAN:
1454  case uno::TypeClass_CHAR:
1455  case uno::TypeClass_BYTE:
1456  case uno::TypeClass_SHORT:
1457  case uno::TypeClass_UNSIGNED_SHORT:
1458  case uno::TypeClass_LONG:
1459  case uno::TypeClass_UNSIGNED_LONG:
1460  case uno::TypeClass_FLOAT:
1461  case uno::TypeClass_DOUBLE:
1462  {
1463  uno::TypeClass eMyClass;
1464  ScApiTypeConversion::ConvertAnyToDouble( fValue, eMyClass, rNewRes);
1465  bHasString = false;
1466  }
1467  break;
1468 
1469  case uno::TypeClass_STRING:
1470  {
1471  rNewRes >>= aString;
1472  bHasString = true;
1473  }
1474  break;
1475 
1476  case uno::TypeClass_INTERFACE:
1477  {
1478  //TODO: directly extract XVolatileResult from any?
1479  uno::Reference<uno::XInterface> xInterface;
1480  rNewRes >>= xInterface;
1481  if ( xInterface.is() )
1482  xVarRes.set( xInterface, uno::UNO_QUERY );
1483 
1484  if (!xVarRes.is())
1485  nErrCode = FormulaError::NoValue; // unknown interface
1486  }
1487  break;
1488 
1489  default:
1490  if ( aType.equals( cppu::UnoType<uno::Sequence< uno::Sequence<sal_Int32> >>::get() ) )
1491  {
1492  const uno::Sequence< uno::Sequence<sal_Int32> >* pRowSeq = nullptr;
1493 
1494  //TODO: use pointer from any!
1495  uno::Sequence< uno::Sequence<sal_Int32> > aSequence;
1496  if ( rNewRes >>= aSequence )
1497  pRowSeq = &aSequence;
1498 
1499  if ( pRowSeq )
1500  {
1501  sal_Int32 nRowCount = pRowSeq->getLength();
1502  sal_Int32 nMaxColCount = lcl_GetMaxColCount(pRowSeq);
1503  if ( nMaxColCount && nRowCount )
1504  {
1505  const uno::Sequence<sal_Int32>* pRowArr = pRowSeq->getConstArray();
1506  xMatrix = new ScMatrix(
1507  static_cast<SCSIZE>(nMaxColCount),
1508  static_cast<SCSIZE>(nRowCount), 0.0);
1509  for (sal_Int32 nRow=0; nRow<nRowCount; nRow++)
1510  {
1511  sal_Int32 nColCount = pRowArr[nRow].getLength();
1512  const sal_Int32* pColArr = pRowArr[nRow].getConstArray();
1513  for (sal_Int32 nCol=0; nCol<nColCount; nCol++)
1514  xMatrix->PutDouble( pColArr[nCol],
1515  static_cast<SCSIZE>(nCol),
1516  static_cast<SCSIZE>(nRow) );
1517  for (sal_Int32 nCol=nColCount; nCol<nMaxColCount; nCol++)
1518  xMatrix->PutDouble( 0.0,
1519  static_cast<SCSIZE>(nCol),
1520  static_cast<SCSIZE>(nRow) );
1521  }
1522  }
1523  }
1524  }
1525  else if ( aType.equals( cppu::UnoType<uno::Sequence< uno::Sequence<double> >>::get() ) )
1526  {
1527  const uno::Sequence< uno::Sequence<double> >* pRowSeq = nullptr;
1528 
1529  //TODO: use pointer from any!
1530  uno::Sequence< uno::Sequence<double> > aSequence;
1531  if ( rNewRes >>= aSequence )
1532  pRowSeq = &aSequence;
1533 
1534  if ( pRowSeq )
1535  {
1536  sal_Int32 nRowCount = pRowSeq->getLength();
1537  sal_Int32 nMaxColCount = lcl_GetMaxColCount(pRowSeq);
1538  if ( nMaxColCount && nRowCount )
1539  {
1540  const uno::Sequence<double>* pRowArr = pRowSeq->getConstArray();
1541  xMatrix = new ScMatrix(
1542  static_cast<SCSIZE>(nMaxColCount),
1543  static_cast<SCSIZE>(nRowCount), 0.0);
1544  for (sal_Int32 nRow=0; nRow<nRowCount; nRow++)
1545  {
1546  sal_Int32 nColCount = pRowArr[nRow].getLength();
1547  const double* pColArr = pRowArr[nRow].getConstArray();
1548  for (sal_Int32 nCol=0; nCol<nColCount; nCol++)
1549  xMatrix->PutDouble( pColArr[nCol],
1550  static_cast<SCSIZE>(nCol),
1551  static_cast<SCSIZE>(nRow) );
1552  for (sal_Int32 nCol=nColCount; nCol<nMaxColCount; nCol++)
1553  xMatrix->PutDouble( 0.0,
1554  static_cast<SCSIZE>(nCol),
1555  static_cast<SCSIZE>(nRow) );
1556  }
1557  }
1558  }
1559  }
1560  else if ( aType.equals( cppu::UnoType<uno::Sequence< uno::Sequence<OUString> >>::get() ) )
1561  {
1562  const uno::Sequence< uno::Sequence<OUString> >* pRowSeq = nullptr;
1563 
1564  //TODO: use pointer from any!
1565  uno::Sequence< uno::Sequence<OUString> > aSequence;
1566  if ( rNewRes >>= aSequence )
1567  pRowSeq = &aSequence;
1568 
1569  if ( pRowSeq )
1570  {
1571  sal_Int32 nRowCount = pRowSeq->getLength();
1572  sal_Int32 nMaxColCount = lcl_GetMaxColCount(pRowSeq);
1573  if ( nMaxColCount && nRowCount )
1574  {
1575  const uno::Sequence<OUString>* pRowArr = pRowSeq->getConstArray();
1576  xMatrix = new ScMatrix(
1577  static_cast<SCSIZE>(nMaxColCount),
1578  static_cast<SCSIZE>(nRowCount), 0.0);
1579  for (sal_Int32 nRow=0; nRow<nRowCount; nRow++)
1580  {
1581  sal_Int32 nColCount = pRowArr[nRow].getLength();
1582  const OUString* pColArr = pRowArr[nRow].getConstArray();
1583  for (sal_Int32 nCol=0; nCol<nColCount; nCol++)
1584  {
1585  xMatrix->PutString(
1586  svl::SharedString(pColArr[nCol]),
1587  static_cast<SCSIZE>(nCol), static_cast<SCSIZE>(nRow));
1588  }
1589  for (sal_Int32 nCol=nColCount; nCol<nMaxColCount; nCol++)
1590  {
1591  xMatrix->PutString(
1592  svl::SharedString(OUString()),
1593  static_cast<SCSIZE>(nCol), static_cast<SCSIZE>(nRow));
1594  }
1595  }
1596  }
1597  }
1598  }
1599  else if ( aType.equals( cppu::UnoType<uno::Sequence< uno::Sequence<uno::Any> >>::get() ) )
1600  {
1602  }
1603 
1604  if (!xMatrix) // no array found
1605  nErrCode = FormulaError::NoValue; //TODO: code for error in return type???
1606  }
1607 }
1608 
1609 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Matrix data type that can store values of mixed types.
Definition: scmatrix.hxx:112
constexpr Method aMethods[]
#define ID_FUNCTION_GRP_ADDINS
Definition: scfuncs.hxx:31
List of spreadsheet functions.
Definition: funcdesc.hxx:241
OUString aName
Definition: addincol.hxx:67
sal_Int32 nIndex
bool NeedsCaller() const
Definition: addincol.cxx:1292
const ::std::vector< LocalizedName > & GetCompNames() const
Definition: addincol.cxx:103
static css::uno::Sequence< OUString > GetNodeNames(css::uno::Reference< css::container::XHierarchicalNameAccess > const &xHierarchyAccess, const OUString &rNode, ConfigNameFormat eFormat)
constexpr OUStringLiteral CFGSTR_CATEGORY
Definition: addincol.cxx:332
bool bOptional
Parameter is optional.
Definition: funcdesc.hxx:211
static bool IsTypeName(std::u16string_view rName, const uno::Type &rType)
Definition: addincol.cxx:597
ScMatrixRef xMatrix
Definition: addincol.hxx:197
const ScUnoAddInFuncData * GetFuncData(const OUString &rName, bool bComplete=false)
Only if bComplete is set, the function reference and argument types are initialized (component may ha...
Definition: addincol.cxx:1104
std::unique_ptr< sal_Int32[]> pData
sal_uInt16 char char * pDesc
Definition: callform.cxx:57
constexpr OUStringLiteral CFGSTR_ADDINFUNCTIONS
Definition: addincol.cxx:324
static OUString convertToBcp47(LanguageType nLangID)
sal_uIntPtr sal_uLong
long Long
Stores whether a parameter is optional or suppressed.
Definition: funcdesc.hxx:209
static const AllSettings & GetSettings()
const OUString & GetLocalName() const
Definition: addincol.hxx:112
const OUString & getBcp47(bool bResolveSystem=true) const
static bool ConvertAnyToDouble(double &o_fVal, css::uno::TypeClass &o_eClass, const css::uno::Any &rAny)
Convert a uno::Any to double if possible, including integer types.
Definition: rangeseq.cxx:327
OUString aDescription
Definition: addincol.hxx:68
void LoadComponent(const ScUnoAddInFuncData &rFuncData)
Definition: addincol.cxx:535
void SetCallerPos(tools::Long nNewPos)
Definition: addincol.cxx:209
Sequence< OUString > aServiceNames
tools::Long nFuncCount
Definition: addincol.hxx:138
std::unordered_map< OUString, const ScUnoAddInFuncData * > ScAddInHashMap
Definition: addincol.hxx:44
void SetParam(tools::Long nPos, const css::uno::Any &rValue)
Definition: addincol.cxx:1311
const OUString & GetUpperName() const
Definition: addincol.hxx:113
OUString aUpperName
for entering formulas
Definition: addincol.hxx:87
const OUString & GetDescription() const
Definition: addincol.hxx:121
const css::uno::Any & GetObject() const
Definition: addincol.hxx:117
#define CFG_FUNCPROP_COUNT
Definition: addincol.cxx:329
OString GetHelpId(const OUString &rFuncName) const
#define SC_FUNCGROUP_COUNT
Definition: funcdesc.hxx:301
bool equalsAscii(std::u16string_view s1, const char *s2)
css::uno::Reference< css::sheet::XVolatileResult > xVarRes
Definition: addincol.hxx:198
void SetFunction(const css::uno::Reference< css::reflection::XIdlMethod > &rNewFunc, const css::uno::Any &rNewObj)
Definition: addincol.cxx:190
std::unique_ptr< ScAddInHashMap > pExactHashMap
exact internal name
Definition: addincol.hxx:140
bool GetExcelName(const OUString &rCalcName, LanguageType eDestLang, OUString &rRetExcelName)
leave rRetExcelName unchanged, if no matching name is found
Definition: addincol.cxx:559
constexpr OUStringLiteral CFGSTR_COMPATIBILITYNAME
Definition: addincol.cxx:335
char sal_uInt16 & nParamCount
Definition: callform.cxx:53
void SetCaller(const css::uno::Reference< css::uno::XInterface > &rInterface)
Definition: addincol.cxx:1297
#define SAL_MAX_UINT16
ScAddInArgumentType eType
Definition: addincol.hxx:69
#define CFG_FUNCPROP_DISPLAYNAME
Definition: addincol.cxx:326
int nCount
constexpr OUStringLiteral CFGPATH_ADDINS
Definition: addincol.cxx:323
Generates help IDs for standard Calc AddIns.
Definition: addinhelpid.hxx:28
ParameterFlags * pDefArgFlags
Flags for each parameter.
Definition: funcdesc.hxx:220
void ExecuteCall()
Definition: addincol.cxx:1336
ScAddInArgumentType GetArgType(tools::Long nPos)
Definition: addincol.cxx:1275
constexpr OUStringLiteral CFGSTR_DESCRIPTION
Definition: addincol.cxx:331
void SetArguments(tools::Long nNewCount, const ScAddInArgDesc *pNewDescs)
Definition: addincol.cxx:196
const char * sName
const OUString & GetUpperLocal() const
Definition: addincol.hxx:114
css::uno::Reference< css::uno::XInterface > xCaller
Definition: addincol.hxx:190
constexpr OUStringLiteral CFGSTR_DISPLAYNAME
Definition: addincol.cxx:330
css::uno::Sequence< css::uno::Any > GetProperties(const css::uno::Sequence< OUString > &rNames)
Definition: addincfg.hxx:35
DocumentType eType
XPropertySet.
Definition: addincol.hxx:60
static sal_Int32 lcl_GetMaxColCount(const uno::Sequence< uno::Sequence< T > > *pRowSeq)
Definition: addincol.cxx:1426
sal_uInt16 nCategory
Function category.
Definition: funcdesc.hxx:222
OUString aUpperLocal
for entering formulas
Definition: addincol.hxx:88
int i
uno_Any a
static bool lcl_ValidReturnType(const uno::Reference< reflection::XIdlClass > &xClass)
Definition: addincol.cxx:602
std::unique_ptr< ScAddInHashMap > pLocalHashMap
localized name upper
Definition: addincol.hxx:142
#define VAR_ARGS
std::vector< OUString > maDefArgDescs
Description(s) of parameter(s)
Definition: funcdesc.hxx:219
#define SC_MOD()
Definition: scmod.hxx:249
mutable::std::vector< LocalizedName > maCompNames
Definition: addincol.hxx:98
static SC_DLLPUBLIC const CharClass & getCharClass()
Definition: global.cxx:1024
static bool FillFunctionDescFromData(const ScUnoAddInFuncData &rFuncData, ScFuncDesc &rDesc)
Definition: addincol.cxx:1168
void LocalizeString(OUString &rName)
modify rName - input: exact name
Definition: addincol.cxx:1135
OUString uppercase(const OUString &rStr, sal_Int32 nPos, sal_Int32 nCount) const
float u
std::unique_ptr< ScAddInHashMap > pNameHashMap
internal name upper
Definition: addincol.hxx:141
css::uno::Reference< css::frame::XModel3 > GetBaseModel() const
std::optional< OUString > mxFuncDesc
Description of function.
Definition: funcdesc.hxx:217
sal_uInt16 GetCategory() const
Definition: addincol.hxx:122
void ReadFromAddIn(const css::uno::Reference< css::uno::XInterface > &xInterface)
Definition: addincol.cxx:696
::std::vector< OUString > getFallbackStrings(bool bIncludeFullBcp47) const
Reference< XComponentContext > getComponentContext(Reference< XMultiServiceFactory > const &factory)
const OUString & GetOriginalName() const
Definition: addincol.hxx:111
const ScFuncDesc * GetFunction(sal_uInt32 nIndex) const
Definition: funcdesc.cxx:1009
OUString aInternalName
used to match configuration and reflection information
Definition: addincol.hxx:66
#define CFG_FUNCPROP_DESCRIPTION
Definition: addincol.cxx:327
const ScAddInArgDesc * GetArguments() const
Definition: addincol.hxx:119
FormulaError
static ScFunctionList * GetStarCalcFunctionList()
Definition: global.cxx:620
std::unique_ptr< ScAddInArgDesc[]> pArgDescs
Definition: addincol.hxx:94
static ScAddInArgumentType lcl_GetArgType(const uno::Reference< reflection::XIdlClass > &xClass)
Definition: addincol.cxx:650
const LanguageTag & getLocale()
static bool HasStarCalcFunctionList()
Definition: global.cxx:615
const css::uno::Reference< css::reflection::XIdlMethod > & GetFunction() const
Definition: addincol.hxx:115
css::uno::Sequence< css::uno::Any > aVarArg
Definition: addincol.hxx:189
FormulaError nErrCode
Definition: addincol.hxx:193
tools::Long nCallerPos
Definition: addincol.hxx:95
Reference< XMultiServiceFactory > getProcessServiceFactory()
std::optional< OUString > mxFuncName
Function name.
Definition: funcdesc.hxx:216
void Clear()
Clears the object.
Definition: funcdesc.cxx:118
css::uno::Sequence< css::uno::Any > aArgs
Definition: addincol.hxx:188
OUString FindFunction(const OUString &rUpperName, bool bLocalFirst)
User entered name. rUpperName MUST already be upper case!
Definition: addincol.cxx:1069
static const ScAddInArgDesc * lcl_FindArgDesc(const ScUnoAddInFuncData &rFuncData, std::u16string_view rArgIntName)
Definition: addincol.cxx:932
void SetCallerFromObjectShell(const SfxObjectShell *pSh)
Definition: addincol.cxx:1302
static ScMatrixRef CreateMixedMatrix(const css::uno::Any &rAny)
Convert a sequence of mixed elements to ScMatrix.
Definition: rangeseq.cxx:357
OUString aName
tools::Long GetArgumentCount() const
Definition: addincol.hxx:118
ScUnoAddInFuncData(const OUString &rNam, const OUString &rLoc, const OUString &rDesc, sal_uInt16 nCat, const OString &, const css::uno::Reference< css::reflection::XIdlMethod > &rFunc, const css::uno::Any &rO, tools::Long nAC, const ScAddInArgDesc *pAD, tools::Long nCP)
Definition: addincol.cxx:68
const ScUnoAddInFuncData * pFuncData
Definition: addincol.hxx:187
std::unique_ptr< std::unique_ptr< ScUnoAddInFuncData >[]> ppFuncData
Definition: addincol.hxx:139
css::uno::Reference< css::reflection::XIdlMethod > xFunction
Definition: addincol.hxx:90
tools::Long GetCallerPos() const
Definition: addincol.hxx:120
Reference< XComponentContext > getProcessComponentContext()
XCellRange.
Definition: addincol.hxx:59
OUString aString
Definition: addincol.hxx:196
sal_uInt32 GetCount() const
Definition: funcdesc.hxx:247
#define CFG_FUNCPROP_CATEGORY
Definition: addincol.cxx:328
void SetResult(const css::uno::Any &rNewRes)
Definition: addincol.cxx:1437
OString sHelpId
HelpId of function.
Definition: funcdesc.hxx:226
constexpr OUStringLiteral CFGSTR_PARAMETERS
Definition: addincol.cxx:336
#define SAL_WARN(area, stream)
const OString & GetHelpId() const
Definition: addincol.hxx:123
std::vector< OUString > maDefArgNames
Parameter name(s)
Definition: funcdesc.hxx:218
static void lcl_UpdateFunctionList(const ScFunctionList &rFunctionList, const ScUnoAddInFuncData &rFuncData)
Definition: addincol.cxx:916
ScAddInArgumentType
Definition: addincol.hxx:48
bool GetExcelName(LanguageType eDestLang, OUString &rRetExcelName) const
Definition: addincol.cxx:141
tools::Long nArgCount
Definition: addincol.hxx:92
bool FillFunctionDesc(tools::Long nFunc, ScFuncDesc &rDesc)
Definition: addincol.cxx:1155
#define SC_CALLERPOS_NONE
Definition: addincol.cxx:66
void ExecuteCallWithArgs(css::uno::Sequence< css::uno::Any > &rCallArgs)
Definition: addincol.cxx:1379
bool GetCalcName(const OUString &rExcelName, OUString &rRetCalcName)
leave rRetCalcName unchanged, if no matching name is found
Definition: addincol.cxx:568
static sal_uInt16 lcl_GetCategory(std::u16string_view rName)
Definition: addincol.cxx:298
bool bIncomplete
Incomplete argument info (set for add-in info from configuration)
Definition: funcdesc.hxx:227
css::uno::Sequence< css::uno::Any > GetProperties(const css::uno::Sequence< OUString > &rNames)
Definition: optutil.hxx:53
css::uno::Any aObject
Definition: addincol.hxx:91
ScUnoAddInCall(ScUnoAddInCollection &rColl, const OUString &rName, tools::Long nParamCount)
Definition: addincol.cxx:1232
Stores and generates human readable descriptions for spreadsheet-functions, e.g. functions used in fo...
Definition: funcdesc.hxx:40
sal_uInt16 nArgCount
All parameter count, suppressed and unsuppressed.
Definition: funcdesc.hxx:223
void UpdateFromAddIn(const css::uno::Reference< css::uno::XInterface > &xInterface, std::u16string_view rServiceName)
Definition: addincol.cxx:944
tools::Long GetFuncCount()
Definition: addincol.cxx:1147
sal_uInt16 nPos
bool m_bDetectedRangeSegmentation false
OUString sDisplayName
void SetCompNames(::std::vector< LocalizedName > &&rNew)
Definition: addincol.cxx:132