summaryrefslogtreecommitdiffstats
path: root/bf_sc/source/core/tool/sc_addincol.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'bf_sc/source/core/tool/sc_addincol.cxx')
-rw-r--r--bf_sc/source/core/tool/sc_addincol.cxx1103
1 files changed, 1103 insertions, 0 deletions
diff --git a/bf_sc/source/core/tool/sc_addincol.cxx b/bf_sc/source/core/tool/sc_addincol.cxx
new file mode 100644
index 000000000..f4095744b
--- /dev/null
+++ b/bf_sc/source/core/tool/sc_addincol.cxx
@@ -0,0 +1,1103 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <comphelper/processfactory.hxx>
+#include <tools/debug.hxx>
+#include <i18npool/mslangid.hxx>
+#include <vcl/svapp.hxx>
+#include <bf_sfx2/objsh.hxx>
+#include <unotools/charclass.hxx>
+
+#include <com/sun/star/container/XContentEnumerationAccess.hpp>
+#include <com/sun/star/lang/XServiceName.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/reflection/XIdlClass.hpp>
+#include <com/sun/star/beans/XIntrospectionAccess.hpp>
+#include <com/sun/star/beans/XIntrospection.hpp>
+#include <com/sun/star/beans/MethodConcept.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/sheet/XCompatibilityNames.hpp>
+
+#include "addincol.hxx"
+#include "addinhelpid.hxx"
+#include "compiler.hxx"
+#include "scmatrix.hxx"
+#include "addinlis.hxx"
+#include "scfuncs.hrc"
+#include <legacysmgr/legacy_binfilters_smgr.hxx>
+namespace binfilter {
+using namespace ::com::sun::star;
+
+//------------------------------------------------------------------------
+
+#define SC_CALLERPOS_NONE (-1)
+
+#define SCADDINSUPPLIER_SERVICE "com.sun.star.sheet.AddIn"
+
+//------------------------------------------------------------------------
+
+
+#define SC_FUNCGROUP_COUNT ID_FUNCTION_GRP_ADDINS
+
+static const sal_Char* aFuncNames[SC_FUNCGROUP_COUNT] =
+ {
+ // array index = ID - 1 (ID starts at 1)
+ // all upper case
+ "Database", // ID_FUNCTION_GRP_DATABASE
+ "Date&Time", // ID_FUNCTION_GRP_DATETIME
+ "Financial", // ID_FUNCTION_GRP_FINANZ
+ "Information", // ID_FUNCTION_GRP_INFO
+ "Logical", // ID_FUNCTION_GRP_LOGIC
+ "Mathematical", // ID_FUNCTION_GRP_MATH
+ "Matrix", // ID_FUNCTION_GRP_MATRIX
+ "Statistical", // ID_FUNCTION_GRP_STATISTIC
+ "Spreadsheet", // ID_FUNCTION_GRP_TABLE
+ "Text", // ID_FUNCTION_GRP_TEXT
+ "Add-In" // ID_FUNCTION_GRP_ADDINS
+ };
+
+
+//------------------------------------------------------------------------
+
+struct ScAddInArgDesc
+{
+ String aName;
+ String aDescription;
+ ScAddInArgumentType eType;
+ BOOL bOptional;
+};
+
+class ScUnoAddInFuncData
+{
+private:
+ String aOriginalName; // kept in formula
+ String aLocalName; // for display
+ String aUpperName; // for entering formulas
+ String aUpperLocal; // for entering formulas
+ String aDescription;
+ uno::Reference<reflection::XIdlMethod> xFunction;
+ uno::Any aObject;
+ long nArgCount;
+ ScAddInArgDesc* pArgDescs;
+ long nCallerPos;
+ USHORT nCategory;
+ USHORT nHelpId;
+ mutable uno::Sequence<sheet::LocalizedName> aCompNames;
+ mutable BOOL bCompInitialized;
+
+public:
+ ScUnoAddInFuncData( const String& rNam, const String& rLoc,
+ const String& rDesc,
+ USHORT nCat, USHORT nHelp,
+ const uno::Reference<reflection::XIdlMethod>& rFunc,
+ const uno::Any& rO,
+ long nAC, const ScAddInArgDesc* pAD,
+ long nCP );
+ ~ScUnoAddInFuncData();
+
+ const String& GetOriginalName() const { return aOriginalName; }
+ const String& GetLocalName() const { return aLocalName; }
+ const String& GetUpperName() const { return aUpperName; }
+ const String& GetUpperLocal() const { return aUpperLocal; }
+ const uno::Reference<reflection::XIdlMethod>& GetFunction() const
+ { return xFunction; }
+ const uno::Any& GetObject() const { return aObject; }
+ long GetArgumentCount() const { return nArgCount; }
+ const ScAddInArgDesc* GetArguments() const { return pArgDescs; }
+ long GetCallerPos() const { return nCallerPos; }
+ const String& GetDescription() const { return aDescription; }
+ USHORT GetCategory() const { return nCategory; }
+ USHORT GetHelpId() const { return nHelpId; }
+
+ const uno::Sequence<sheet::LocalizedName>& GetCompNames() const;
+};
+
+//------------------------------------------------------------------------
+
+/*N*/ ScUnoAddInFuncData::ScUnoAddInFuncData( const String& rNam, const String& rLoc,
+/*N*/ const String& rDesc,
+/*N*/ USHORT nCat, USHORT nHelp,
+/*N*/ const uno::Reference<reflection::XIdlMethod>& rFunc,
+/*N*/ const uno::Any& rO,
+/*N*/ long nAC, const ScAddInArgDesc* pAD,
+/*N*/ long nCP ) :
+/*N*/ aOriginalName( rNam ),
+/*N*/ aLocalName( rLoc ),
+/*N*/ aUpperName( rNam ),
+/*N*/ aUpperLocal( rLoc ),
+/*N*/ aDescription( rDesc ),
+/*N*/ xFunction( rFunc ),
+/*N*/ aObject( rO ),
+/*N*/ nArgCount( nAC ),
+/*N*/ nCallerPos( nCP ),
+/*N*/ nCategory( nCat ),
+/*N*/ nHelpId( nHelp ),
+/*N*/ bCompInitialized( FALSE )
+/*N*/ {
+/*N*/ if ( nArgCount )
+/*N*/ {
+/*N*/ pArgDescs = new ScAddInArgDesc[nArgCount];
+/*N*/ for (long i=0; i<nArgCount; i++)
+/*N*/ pArgDescs[i] = pAD[i];
+/*N*/ }
+/*N*/ else
+/*N*/ pArgDescs = NULL;
+/*N*/
+/*N*/ aUpperName = ScGlobal::pCharClass->uppercase(aUpperName);
+/*N*/ aUpperLocal = ScGlobal::pCharClass->uppercase(aUpperLocal);
+/*N*/ }
+
+/*N*/ ScUnoAddInFuncData::~ScUnoAddInFuncData()
+/*N*/ {
+/*N*/ delete[] pArgDescs;
+/*N*/ }
+
+
+//------------------------------------------------------------------------
+
+/*N*/ BOOL lcl_ConvertToDouble( const uno::Any& rAny, double& rOut )
+/*N*/ {
+/*N*/ BOOL bRet = FALSE;
+/*N*/ uno::TypeClass eClass = rAny.getValueTypeClass();
+/*N*/ switch (eClass)
+/*N*/ {
+/*N*/ //! extract integer values
+/*N*/ case uno::TypeClass_ENUM:
+/*N*/ case uno::TypeClass_BOOLEAN:
+/*N*/ case uno::TypeClass_CHAR:
+/*N*/ case uno::TypeClass_BYTE:
+/*N*/ case uno::TypeClass_SHORT:
+/*N*/ case uno::TypeClass_UNSIGNED_SHORT:
+/*N*/ case uno::TypeClass_LONG:
+/*N*/ case uno::TypeClass_UNSIGNED_LONG:
+/*N*/ case uno::TypeClass_FLOAT:
+/*N*/ case uno::TypeClass_DOUBLE:
+/*N*/ rAny >>= rOut;
+/*N*/ break;
+ default:
+ rOut = 0.0;
+ break;
+/*N*/ }
+/*N*/ return bRet;
+/*N*/ }
+
+//------------------------------------------------------------------------
+
+/*N*/ ScUnoAddInCollection::ScUnoAddInCollection() :
+/*N*/ nFuncCount( 0 ),
+/*N*/ ppFuncData( NULL ),
+/*N*/ pExactHashMap( NULL ),
+/*N*/ pNameHashMap( NULL ),
+/*N*/ pLocalHashMap( NULL ),
+/*N*/ bInitialized( FALSE )
+/*N*/ {
+/*N*/ }
+
+/*N*/ ScUnoAddInCollection::~ScUnoAddInCollection()
+/*N*/ {
+/*N*/ delete pExactHashMap;
+/*N*/ delete pNameHashMap;
+/*N*/ delete pLocalHashMap;
+/*N*/ if ( ppFuncData )
+/*N*/ {
+/*N*/ for ( long i=0; i<nFuncCount; i++ )
+/*N*/ delete ppFuncData[i];
+/*N*/ delete[] ppFuncData;
+/*N*/ }
+/*N*/ }
+
+/*N*/ void ScUnoAddInCollection::Initialize()
+/*N*/ {
+/*N*/ DBG_ASSERT( !bInitialized, "Initialize twice?" );
+/*N*/
+/*N*/ uno::Reference<lang::XMultiServiceFactory> xManager = ::legacy_binfilters::getLegacyProcessServiceFactory();
+/*N*/ uno::Reference<container::XContentEnumerationAccess> xEnAc( xManager, uno::UNO_QUERY );
+/*N*/ if ( xEnAc.is() )
+/*N*/ {
+/*N*/ uno::Reference<container::XEnumeration> xEnum =
+/*N*/ xEnAc->createContentEnumeration(
+/*N*/ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SCADDINSUPPLIER_SERVICE)) );
+/*N*/ if ( xEnum.is() )
+/*N*/ {
+/*N*/ // loop through all AddIns
+/*N*/ while ( xEnum->hasMoreElements() )
+/*N*/ {
+/*N*/ uno::Any aAddInAny = xEnum->nextElement();
+/*N*/ //? if ( aAddInAny.getReflection()->getTypeClass() == uno::TypeClass_INTERFACE )
+/*N*/ {
+/*N*/ uno::Reference<uno::XInterface> xIntFac;
+/*N*/ aAddInAny >>= xIntFac;
+/*N*/ if ( xIntFac.is() )
+/*N*/ {
+/*N*/ uno::Reference<lang::XSingleServiceFactory> xFac( xIntFac, uno::UNO_QUERY );
+/*N*/ if ( xFac.is() )
+/*N*/ {
+/*N*/ uno::Reference<uno::XInterface> xInterface = xFac->createInstance();
+/*N*/ ReadFromAddIn( xInterface );
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ bInitialized = TRUE; // with or without functions
+/*N*/ }
+
+
+
+/*N*/ USHORT lcl_GetCategory( const String& rName )
+/*N*/ {
+/*N*/ for (USHORT i=0; i<SC_FUNCGROUP_COUNT; i++)
+/*N*/ if ( rName.EqualsAscii( aFuncNames[i] ) )
+/*N*/ return i+1; // IDs start at 1
+/*N*/
+/*N*/ return ID_FUNCTION_GRP_ADDINS; // if not found, use Add-In group
+/*N*/ }
+
+/*N*/ inline BOOL IsTypeName( const ::rtl::OUString& rName, const uno::Type& rType )
+/*N*/ {
+/*N*/ return rName == rType.getTypeName();
+/*N*/ }
+
+/*N*/ BOOL lcl_ValidReturnType( const uno::Reference<reflection::XIdlClass>& xClass )
+/*N*/ {
+/*N*/ // this must match with ScUnoAddInCall::SetResult
+/*N*/
+/*N*/ if ( !xClass.is() ) return FALSE;
+/*N*/
+/*N*/ switch (xClass->getTypeClass())
+/*N*/ {
+/*N*/ // case uno::TypeClass_VOID:
+/*N*/ // ???
+/*N*/
+/*N*/ case uno::TypeClass_ANY: // variable type
+/*N*/ case uno::TypeClass_ENUM: //! ???
+/*N*/ case uno::TypeClass_BOOLEAN:
+/*N*/ case uno::TypeClass_CHAR:
+/*N*/ case uno::TypeClass_BYTE:
+/*N*/ case uno::TypeClass_SHORT:
+/*N*/ case uno::TypeClass_UNSIGNED_SHORT:
+/*N*/ case uno::TypeClass_LONG:
+/*N*/ case uno::TypeClass_UNSIGNED_LONG:
+/*N*/ case uno::TypeClass_FLOAT:
+/*N*/ case uno::TypeClass_DOUBLE:
+/*N*/ case uno::TypeClass_STRING:
+/*N*/ return TRUE; // values or string
+/*N*/
+/*N*/ case uno::TypeClass_INTERFACE:
+/*N*/ {
+/*N*/ // return type XInterface may contain a XVolatileResult
+/*N*/ //! XIdlClass needs getType() method!
+/*N*/
+/*N*/ ::rtl::OUString sName = xClass->getName();
+/*N*/ return (
+/*N*/ IsTypeName( sName, getCppuType((uno::Reference<sheet::XVolatileResult>*)0) ) ||
+/*N*/ IsTypeName( sName, getCppuType((uno::Reference<uno::XInterface>*)0) ) );
+/*N*/ }
+/*N*/
+/*N*/ default:
+/*N*/ {
+/*N*/ // nested sequences for arrays
+/*N*/ //! XIdlClass needs getType() method!
+/*N*/
+/*N*/ ::rtl::OUString sName = xClass->getName();
+/*N*/ return (
+/*N*/ IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<INT32> >*)0) ) ||
+/*N*/ IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<double> >*)0) ) ||
+/*N*/ IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<rtl::OUString> >*)0) ) ||
+/*N*/ IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<uno::Any> >*)0) ) );
+/*N*/ }
+/*N*/ }
+/*N*/ return FALSE;
+/*N*/ }
+
+/*N*/ ScAddInArgumentType lcl_GetArgType( const uno::Reference<reflection::XIdlClass>& xClass )
+/*N*/ {
+/*N*/ if (!xClass.is())
+/*N*/ return SC_ADDINARG_NONE;
+/*N*/
+/*N*/ uno::TypeClass eType = xClass->getTypeClass();
+/*N*/
+/*N*/ if ( eType == uno::TypeClass_LONG ) //! other integer types?
+/*N*/ return SC_ADDINARG_INTEGER;
+/*N*/
+/*N*/ if ( eType == uno::TypeClass_DOUBLE )
+/*N*/ return SC_ADDINARG_DOUBLE;
+/*N*/
+/*N*/ if ( eType == uno::TypeClass_STRING )
+/*N*/ return SC_ADDINARG_STRING;
+/*N*/
+/*N*/ //! XIdlClass needs getType() method!
+/*N*/ ::rtl::OUString sName = xClass->getName();
+/*N*/
+/*N*/ if (IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<INT32> >*)0) ))
+/*N*/ return SC_ADDINARG_INTEGER_ARRAY;
+/*N*/
+/*N*/ if (IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<double> >*)0) ))
+/*N*/ return SC_ADDINARG_DOUBLE_ARRAY;
+/*N*/
+/*N*/ if (IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<rtl::OUString> >*)0) ))
+/*N*/ return SC_ADDINARG_STRING_ARRAY;
+/*N*/
+/*N*/ if (IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<uno::Any> >*)0) ))
+/*N*/ return SC_ADDINARG_MIXED_ARRAY;
+/*N*/
+/*N*/ if (IsTypeName( sName, getCppuType((uno::Any*)0) ))
+/*N*/ return SC_ADDINARG_VALUE_OR_ARRAY;
+/*N*/
+/*N*/ if (IsTypeName( sName, getCppuType((uno::Reference<table::XCellRange>*)0) ))
+/*N*/ return SC_ADDINARG_CELLRANGE;
+/*N*/
+/*N*/ if (IsTypeName( sName, getCppuType((uno::Reference<beans::XPropertySet>*)0) ))
+/*N*/ return SC_ADDINARG_CALLER;
+/*N*/
+/*N*/ if (IsTypeName( sName, getCppuType((uno::Sequence<uno::Any>*)0) ))
+/*N*/ return SC_ADDINARG_VARARGS;
+/*N*/
+/*N*/ return SC_ADDINARG_NONE;
+/*N*/ }
+
+/*N*/ void ScUnoAddInCollection::ReadFromAddIn( const uno::Reference<uno::XInterface>& xInterface )
+/*N*/ {
+/*N*/ uno::Reference<sheet::XAddIn> xAddIn( xInterface, uno::UNO_QUERY );
+/*N*/ uno::Reference<lang::XServiceName> xName( xInterface, uno::UNO_QUERY );
+/*N*/ if ( xAddIn.is() && xName.is() )
+/*N*/ {
+/*N*/ // AddIns must use the language for which the office is installed
+/*N*/ LanguageType eOfficeLang = Application::GetSettings().GetUILanguage();
+/*N*/
+/*N*/ lang::Locale aLocale( MsLangId::convertLanguageToLocale( eOfficeLang ));
+/*N*/ xAddIn->setLocale( aLocale );
+/*N*/
+/*N*/ String aServiceName = String( xName->getServiceName() );
+/*N*/ ScUnoAddInHelpIdGenerator aHelpIdGenerator( xName->getServiceName() );
+/*N*/
+/*N*/ //! pass XIntrospection to ReadFromAddIn
+/*N*/
+/*N*/ uno::Reference<lang::XMultiServiceFactory> xManager = ::legacy_binfilters::getLegacyProcessServiceFactory();
+/*N*/ if ( xManager.is() )
+/*N*/ {
+/*N*/ uno::Reference<beans::XIntrospection> xIntro(
+/*N*/ xManager->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+/*N*/ "com.sun.star.beans.Introspection" ))),
+/*N*/ uno::UNO_QUERY );
+/*N*/ if ( xIntro.is() )
+/*N*/ {
+/*N*/ uno::Any aObject;
+/*N*/ aObject <<= xAddIn;
+/*N*/ uno::Reference<beans::XIntrospectionAccess> xAcc = xIntro->inspect(aObject);
+/*N*/ if (xAcc.is())
+/*N*/ {
+/*N*/ uno::Sequence< uno::Reference<reflection::XIdlMethod> > aMethods =
+/*N*/ xAcc->getMethods( beans::MethodConcept::ALL );
+/*N*/ long nNewCount = aMethods.getLength();
+/*N*/ if ( nNewCount )
+/*N*/ {
+/*N*/ long nOld = nFuncCount;
+/*N*/ nFuncCount = nNewCount+nOld;
+/*N*/ if ( nOld )
+/*N*/ {
+/*N*/ ScUnoAddInFuncData** ppNew = new ScUnoAddInFuncData*[nFuncCount];
+/*N*/ for (long i=0; i<nOld; i++)
+/*N*/ ppNew[i] = ppFuncData[i];
+/*N*/ delete[] ppFuncData;
+/*N*/ ppFuncData = ppNew;
+/*N*/ }
+/*N*/ else
+/*N*/ ppFuncData = new ScUnoAddInFuncData*[nFuncCount];
+/*N*/
+/*N*/ //! TODO: adjust bucket count?
+/*N*/ if ( !pExactHashMap )
+/*N*/ pExactHashMap = new ScAddInHashMap;
+/*N*/ if ( !pNameHashMap )
+/*N*/ pNameHashMap = new ScAddInHashMap;
+/*N*/ if ( !pLocalHashMap )
+/*N*/ pLocalHashMap = new ScAddInHashMap;
+/*N*/
+/*N*/ const uno::Reference<reflection::XIdlMethod>* pArray = aMethods.getConstArray();
+/*N*/ for (long nFuncPos=0; nFuncPos<nNewCount; nFuncPos++)
+/*N*/ {
+/*N*/ ppFuncData[nFuncPos+nOld] = NULL;
+/*N*/
+/*N*/ uno::Reference<reflection::XIdlMethod> xFunc = pArray[nFuncPos];
+/*N*/ if (xFunc.is())
+/*N*/ {
+/*N*/ // leave out internal functions
+/*N*/ uno::Reference<reflection::XIdlClass> xClass =
+/*N*/ xFunc->getDeclaringClass();
+/*N*/ BOOL bSkip = TRUE;
+/*N*/ if ( xClass.is() )
+/*N*/ {
+/*N*/ //! XIdlClass needs getType() method!
+/*N*/ ::rtl::OUString sName = xClass->getName();
+/*N*/ bSkip = (
+/*N*/ IsTypeName( sName,
+/*N*/ getCppuType((uno::Reference<uno::XInterface>*)0) ) ||
+/*N*/ IsTypeName( sName,
+/*N*/ getCppuType((uno::Reference<lang::XServiceName>*)0) ) ||
+/*N*/ IsTypeName( sName,
+/*N*/ getCppuType((uno::Reference<lang::XServiceInfo>*)0) ) ||
+/*N*/ IsTypeName( sName,
+/*N*/ getCppuType((uno::Reference<sheet::XAddIn>*)0) ) );
+/*N*/ }
+/*N*/ if (!bSkip)
+/*N*/ {
+/*N*/ uno::Reference<reflection::XIdlClass> xReturn =
+/*N*/ xFunc->getReturnType();
+/*N*/ if ( !lcl_ValidReturnType( xReturn ) )
+/*N*/ bSkip = TRUE;
+/*N*/ }
+/*N*/ if (!bSkip)
+/*N*/ {
+/*N*/ ::rtl::OUString aFuncU = xFunc->getName();
+/*N*/
+/*N*/ // stored function name: (service name).(function)
+/*N*/ String aFuncName = aServiceName;
+/*N*/ aFuncName += '.';
+/*N*/ aFuncName += String( aFuncU );
+/*N*/
+/*N*/ BOOL bValid = TRUE;
+/*N*/ long nVisibleCount = 0;
+/*N*/ long nCallerPos = SC_CALLERPOS_NONE;
+/*N*/
+/*N*/ uno::Sequence<reflection::ParamInfo> aParams =
+/*N*/ xFunc->getParameterInfos();
+/*N*/ long nParamCount = aParams.getLength();
+/*N*/ const reflection::ParamInfo* pParArr = aParams.getConstArray();
+/*N*/ long nParamPos;
+/*N*/ for (nParamPos=0; nParamPos<nParamCount; nParamPos++)
+/*N*/ {
+/*N*/ if ( pParArr[nParamPos].aMode != reflection::ParamMode_IN )
+/*N*/ bValid = FALSE;
+/*N*/ uno::Reference<reflection::XIdlClass> xParClass =
+/*N*/ pParArr[nParamPos].aType;
+/*N*/ ScAddInArgumentType eArgType = lcl_GetArgType( xParClass );
+/*N*/ if ( eArgType == SC_ADDINARG_NONE )
+/*N*/ bValid = FALSE;
+/*N*/ else if ( eArgType == SC_ADDINARG_CALLER )
+/*N*/ nCallerPos = nParamPos;
+/*N*/ else
+/*N*/ ++nVisibleCount;
+/*N*/ }
+/*N*/ if (bValid)
+/*N*/ {
+/*N*/ USHORT nCategory = lcl_GetCategory(
+/*N*/ String(
+/*N*/ xAddIn->getProgrammaticCategoryName(
+/*N*/ aFuncU ) ) );
+/*N*/
+/*N*/ USHORT nHelpId = aHelpIdGenerator.GetHelpId( aFuncU );
+/*N*/
+/*N*/ ::rtl::OUString aLocalU;
+/*N*/ try
+/*N*/ {
+/*N*/ aLocalU = xAddIn->
+/*N*/ getDisplayFunctionName( aFuncU );
+/*N*/ }
+/*N*/ catch(uno::Exception&)
+/*N*/ {
+/*N*/ aLocalU = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "###" ));
+/*N*/ }
+/*N*/ String aLocalName = String( aLocalU );
+/*N*/
+/*N*/ ::rtl::OUString aDescU;
+/*N*/ try
+/*N*/ {
+/*N*/ aDescU = xAddIn->
+/*N*/ getFunctionDescription( aFuncU );
+/*N*/ }
+/*N*/ catch(uno::Exception&)
+/*N*/ {
+/*N*/ aDescU = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "###" ));
+/*N*/ }
+/*N*/ String aDescription = String( aDescU );
+/*N*/
+/*N*/ ScAddInArgDesc* pVisibleArgs = NULL;
+/*N*/ if ( nVisibleCount > 0 )
+/*N*/ {
+/*N*/ ScAddInArgDesc aDesc;
+/*N*/ pVisibleArgs = new ScAddInArgDesc[nVisibleCount];
+/*N*/ long nDestPos = 0;
+/*N*/ for (nParamPos=0; nParamPos<nParamCount; nParamPos++)
+/*N*/ {
+/*N*/ uno::Reference<reflection::XIdlClass> xParClass =
+/*N*/ pParArr[nParamPos].aType;
+/*N*/ ScAddInArgumentType eArgType = lcl_GetArgType( xParClass );
+/*N*/ if ( eArgType != SC_ADDINARG_CALLER )
+/*N*/ {
+/*N*/ ::rtl::OUString aArgName;
+/*N*/ try
+/*N*/ {
+/*N*/ aArgName = xAddIn->
+/*N*/ getDisplayArgumentName( aFuncU, nParamPos );
+/*N*/ }
+/*N*/ catch(uno::Exception&)
+/*N*/ {
+/*N*/ aArgName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "###" ));
+/*N*/ }
+/*N*/ ::rtl::OUString aArgDesc;
+/*N*/ try
+/*N*/ {
+/*N*/ aArgDesc = xAddIn->
+/*N*/ getArgumentDescription( aFuncU, nParamPos );
+/*N*/ }
+/*N*/ catch(uno::Exception&)
+/*N*/ {
+/*N*/ aArgName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "###" ));
+/*N*/ }
+/*N*/
+/*N*/ BOOL bOptional =
+/*N*/ ( eArgType == SC_ADDINARG_VALUE_OR_ARRAY ||
+/*N*/ eArgType == SC_ADDINARG_VARARGS );
+/*N*/
+/*N*/ aDesc.eType = eArgType;
+/*N*/ aDesc.aName = String( aArgName );
+/*N*/ aDesc.aDescription = String( aArgDesc );
+/*N*/ aDesc.bOptional = bOptional;
+/*N*/
+/*N*/ pVisibleArgs[nDestPos++] = aDesc;
+/*N*/ }
+/*N*/ }
+/*N*/ DBG_ASSERT( nDestPos==nVisibleCount, "wrong count" );
+/*N*/ }
+/*N*/
+/*N*/ ppFuncData[nFuncPos+nOld] = new ScUnoAddInFuncData(
+/*N*/ aFuncName, aLocalName, aDescription,
+/*N*/ nCategory, nHelpId,
+/*N*/ xFunc, aObject,
+/*N*/ nVisibleCount, pVisibleArgs, nCallerPos );
+/*N*/
+/*N*/ const ScUnoAddInFuncData* pData =
+/*N*/ ppFuncData[nFuncPos+nOld];
+/*N*/ pExactHashMap->insert(
+/*N*/ ScAddInHashMap::value_type(
+/*N*/ pData->GetOriginalName(),
+/*N*/ pData ) );
+/*N*/ pNameHashMap->insert(
+/*N*/ ScAddInHashMap::value_type(
+/*N*/ pData->GetUpperName(),
+/*N*/ pData ) );
+/*N*/ pLocalHashMap->insert(
+/*N*/ ScAddInHashMap::value_type(
+/*N*/ pData->GetUpperLocal(),
+/*N*/ pData ) );
+/*N*/
+/*N*/ delete[] pVisibleArgs;
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ }
+
+/*N*/ String ScUnoAddInCollection::FindFunction( const String& rUpperName, BOOL bLocalFirst )
+/*N*/ {
+/*N*/ if (!bInitialized)
+/*N*/ Initialize();
+/*N*/
+/*N*/ if (nFuncCount == 0)
+/*N*/ return EMPTY_STRING;
+/*N*/
+/*N*/ if ( bLocalFirst )
+/*N*/ {
+/*N*/ // first scan all local names (used for entering formulas)
+/*N*/
+/*N*/ ScAddInHashMap::const_iterator iLook( pLocalHashMap->find( rUpperName ) );
+/*N*/ if ( iLook != pLocalHashMap->end() )
+/*?*/ return iLook->second->GetOriginalName();
+/*N*/
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ // first scan international names (used when calling a function)
+/*N*/ //! before that, check for exact match???
+/*N*/
+/*N*/ ScAddInHashMap::const_iterator iLook( pNameHashMap->find( rUpperName ) );
+/*N*/ if ( iLook != pNameHashMap->end() )
+/*N*/ return iLook->second->GetOriginalName();
+/*N*/
+/*N*/ // after that, scan all local names (to allow replacing old AddIns with Uno)
+/*N*/
+/*N*/ iLook = pLocalHashMap->find( rUpperName );
+/*N*/ if ( iLook != pLocalHashMap->end() )
+/*N*/ return iLook->second->GetOriginalName();
+/*N*/ }
+/*N*/
+/*N*/ return EMPTY_STRING;
+/*N*/ }
+
+/*N*/ const ScUnoAddInFuncData* ScUnoAddInCollection::GetFuncData( const String& rName )
+/*N*/ {
+/*N*/ if (!bInitialized)
+/*?*/ Initialize();
+/*N*/
+/*N*/ // rName must be the exact internal name
+/*N*/
+/*N*/ ScAddInHashMap::const_iterator iLook( pExactHashMap->find( rName ) );
+/*N*/ if ( iLook != pExactHashMap->end() )
+/*N*/ return iLook->second;
+/*N*/
+/*N*/ return NULL;
+/*N*/ }
+
+
+
+
+
+
+//------------------------------------------------------------------------
+
+/*N*/ ScUnoAddInCall::ScUnoAddInCall( ScUnoAddInCollection& rColl, const String& rName,
+/*N*/ long nParamCount ) :
+/*N*/ bValidCount( FALSE ),
+/*N*/ nErrCode( errNoCode ), // before function was called
+/*N*/ bHasString( TRUE ),
+/*N*/ fValue( 0.0 ),
+/*N*/ pMatrix( NULL )
+/*N*/ {
+/*N*/ pFuncData = rColl.GetFuncData( rName );
+/*N*/ DBG_ASSERT( pFuncData, "Function Data missing" );
+/*N*/ if ( pFuncData )
+/*N*/ {
+/*N*/ long nDescCount = pFuncData->GetArgumentCount();
+/*N*/ const ScAddInArgDesc* pArgs = pFuncData->GetArguments();
+/*N*/
+/*N*/ // is aVarArg sequence needed?
+/*N*/ if ( !( nParamCount >= nDescCount
+ && nDescCount > 0
+ && pArgs[nDescCount-1].eType == SC_ADDINARG_VARARGS
+ )
+ )
+ {
+/*N*/ if ( nParamCount <= nDescCount )
+/*N*/ {
+/*N*/ // all args behind nParamCount must be optional
+/*N*/ bValidCount = TRUE;
+/*N*/ for (long i=nParamCount; i<nDescCount; i++)
+/*?*/ if ( !pArgs[i].bOptional )
+/*?*/ bValidCount = FALSE;
+/*N*/ }
+ }
+/*N*/
+/*N*/ if ( bValidCount )
+/*N*/ aArgs.realloc( nDescCount ); // sequence must always match function signature
+/*N*/ }
+/*N*/ }
+
+/*N*/ ScUnoAddInCall::~ScUnoAddInCall()
+/*N*/ {
+/*N*/ // pFuncData is deleted with ScUnoAddInCollection
+/*N*/
+/*N*/ delete pMatrix;
+/*N*/ }
+
+/*N*/ BOOL ScUnoAddInCall::ValidParamCount()
+/*N*/ {
+/*N*/ return bValidCount;
+/*N*/ }
+
+/*N*/ ScAddInArgumentType ScUnoAddInCall::GetArgType( long nPos )
+/*N*/ {
+/*N*/ if ( pFuncData )
+/*N*/ {
+/*N*/ long nCount = pFuncData->GetArgumentCount();
+/*N*/ const ScAddInArgDesc* pArgs = pFuncData->GetArguments();
+/*N*/
+/*N*/ // if last arg is sequence, use "any" type
+/*N*/ if ( nCount > 0 && nPos >= nCount-1 && pArgs[nCount-1].eType == SC_ADDINARG_VARARGS )
+/*N*/ return SC_ADDINARG_VALUE_OR_ARRAY;
+/*N*/
+/*N*/ if ( nPos < nCount )
+/*N*/ return pArgs[nPos].eType;
+/*N*/ }
+/*N*/ return SC_ADDINARG_VALUE_OR_ARRAY; //! error code !!!!
+/*N*/ }
+
+/*N*/ BOOL ScUnoAddInCall::NeedsCaller() const
+/*N*/ {
+/*N*/ return pFuncData && pFuncData->GetCallerPos() != SC_CALLERPOS_NONE;
+/*N*/ }
+
+/*N*/ void ScUnoAddInCall::SetCaller( const uno::Reference<uno::XInterface>& rInterface )
+/*N*/ {
+/*N*/ xCaller = rInterface;
+/*N*/ }
+
+/*N*/ void ScUnoAddInCall::SetCallerFromObjectShell( SfxObjectShell* pObjSh )
+/*N*/ {
+/*N*/ if (pObjSh)
+/*N*/ {
+/*N*/ uno::Reference<uno::XInterface> xInt( pObjSh->GetBaseModel(), uno::UNO_QUERY );
+/*N*/ SetCaller( xInt );
+/*N*/ }
+/*N*/ }
+
+/*N*/ void ScUnoAddInCall::SetParam( long nPos, const uno::Any& rValue )
+/*N*/ {
+/*N*/ if ( pFuncData )
+/*N*/ {
+/*N*/ long nCount = pFuncData->GetArgumentCount();
+/*N*/ const ScAddInArgDesc* pArgs = pFuncData->GetArguments();
+/*N*/ if ( nCount > 0 && nPos >= nCount-1 && pArgs[nCount-1].eType == SC_ADDINARG_VARARGS )
+/*N*/ {
+/*N*/ long nVarPos = nPos-(nCount-1);
+/*N*/ if ( nVarPos < aVarArg.getLength() )
+/*N*/ aVarArg.getArray()[nVarPos] = rValue;
+/*N*/ else
+/*N*/ OSL_FAIL("wrong argument number");
+/*N*/ }
+/*N*/ else if ( nPos < aArgs.getLength() )
+/*N*/ aArgs.getArray()[nPos] = rValue;
+/*N*/ else
+/*N*/ OSL_FAIL("wrong argument number");
+/*N*/ }
+/*N*/ }
+
+/*N*/ void ScUnoAddInCall::ExecuteCall()
+/*N*/ {
+/*N*/ if ( !pFuncData )
+/*N*/ return;
+/*N*/
+/*N*/ long nCount = pFuncData->GetArgumentCount();
+/*N*/ const ScAddInArgDesc* pArgs = pFuncData->GetArguments();
+/*N*/ if ( nCount > 0 && pArgs[nCount-1].eType == SC_ADDINARG_VARARGS )
+/*N*/ {
+/*N*/ // insert aVarArg as last argument
+/*N*/ //! after inserting caller (to prevent copying twice)?
+/*N*/
+/*N*/ DBG_ASSERT( aArgs.getLength() == nCount, "wrong argument count" );
+/*N*/ aArgs.getArray()[nCount-1] <<= aVarArg;
+/*N*/ }
+/*N*/
+/*N*/ if ( pFuncData->GetCallerPos() != SC_CALLERPOS_NONE )
+/*N*/ {
+/*N*/ uno::Any aCallerAny;
+/*N*/ aCallerAny <<= xCaller;
+/*N*/
+/*N*/ long nUserLen = aArgs.getLength();
+/*N*/ long nCallPos = pFuncData->GetCallerPos();
+/*N*/ if (nCallPos>nUserLen) // should not happen
+/*N*/ {
+/*N*/ OSL_FAIL("wrong CallPos");
+/*N*/ nCallPos = nUserLen;
+/*N*/ }
+/*N*/
+/*N*/ long nDestLen = nUserLen + 1;
+/*N*/ uno::Sequence<uno::Any> aRealArgs( nDestLen );
+/*N*/ uno::Any* pDest = aRealArgs.getArray();
+/*N*/
+/*N*/ const uno::Any* pSource = aArgs.getConstArray();
+/*N*/ long nSrcPos = 0;
+/*N*/
+/*N*/ for ( long nDestPos = 0; nDestPos < nDestLen; nDestPos++ )
+/*N*/ {
+/*N*/ if ( nDestPos == nCallPos )
+/*N*/ pDest[nDestPos] = aCallerAny;
+/*N*/ else
+/*N*/ pDest[nDestPos] = pSource[nSrcPos++];
+/*N*/ }
+/*N*/
+/*N*/ ExecuteCallWithArgs( aRealArgs );
+/*N*/ }
+/*N*/ else
+/*N*/ ExecuteCallWithArgs( aArgs );
+/*N*/ }
+
+/*N*/ void ScUnoAddInCall::ExecuteCallWithArgs(uno::Sequence<uno::Any>& rCallArgs)
+/*N*/ {
+/*N*/ // rCallArgs may not match argument descriptions (because of caller)
+/*N*/
+/*N*/ uno::Reference<reflection::XIdlMethod> xFunction;
+/*N*/ uno::Any aObject;
+/*N*/ if ( pFuncData )
+/*N*/ {
+/*N*/ xFunction = pFuncData->GetFunction();
+/*N*/ aObject = pFuncData->GetObject();
+/*N*/ }
+/*N*/
+/*N*/ if ( xFunction.is() )
+/*N*/ {
+/*N*/ uno::Any aAny;
+/*N*/ nErrCode = 0;
+/*N*/
+/*N*/ try
+/*N*/ {
+/*N*/ aAny = xFunction->invoke( aObject, rCallArgs );
+/*N*/ }
+/*N*/ catch(lang::IllegalArgumentException&)
+/*N*/ {
+/*N*/ nErrCode = errIllegalArgument;
+/*N*/ }
+/*N*/ catch(reflection::InvocationTargetException& rWrapped)
+/*N*/ {
+/*N*/ if ( rWrapped.TargetException.getValueType().equals(
+/*N*/ getCppuType( (lang::IllegalArgumentException*)0 ) ) )
+/*N*/ nErrCode = errIllegalArgument;
+/*N*/ else
+/*N*/ nErrCode = errNoValue;
+/*N*/ }
+/*N*/ catch(uno::Exception&)
+/*N*/ {
+/*N*/ nErrCode = errNoValue;
+/*N*/ }
+/*N*/
+/*N*/ if (!nErrCode)
+/*N*/ SetResult( aAny ); // convert result to Calc types
+/*N*/ }
+/*N*/ }
+
+/*N*/ void ScUnoAddInCall::SetResult( const uno::Any& rNewRes )
+/*N*/ {
+/*N*/ nErrCode = 0;
+/*N*/ xVarRes = NULL;
+/*N*/
+/*N*/ // Reflection* pRefl = rNewRes.getReflection();
+/*N*/
+/*N*/ uno::TypeClass eClass = rNewRes.getValueTypeClass();
+/*N*/ uno::Type aType = rNewRes.getValueType();
+/*N*/ switch (eClass)
+/*N*/ {
+/*N*/ case uno::TypeClass_VOID:
+/*N*/ nErrCode = NOVALUE; // #nv
+/*N*/ break;
+/*N*/
+/*N*/ case uno::TypeClass_ENUM:
+/*N*/ case uno::TypeClass_BOOLEAN:
+/*N*/ case uno::TypeClass_CHAR:
+/*N*/ case uno::TypeClass_BYTE:
+/*N*/ case uno::TypeClass_SHORT:
+/*N*/ case uno::TypeClass_UNSIGNED_SHORT:
+/*N*/ case uno::TypeClass_LONG:
+/*N*/ case uno::TypeClass_UNSIGNED_LONG:
+/*N*/ case uno::TypeClass_FLOAT:
+/*N*/ case uno::TypeClass_DOUBLE:
+/*N*/ lcl_ConvertToDouble( rNewRes, fValue );
+/*N*/ bHasString = FALSE;
+/*N*/ break;
+/*N*/
+/*N*/ case uno::TypeClass_STRING:
+/*N*/ {
+/*N*/ ::rtl::OUString aUStr;
+/*N*/ rNewRes >>= aUStr;
+/*N*/ aString = String( aUStr );
+/*N*/ bHasString = TRUE;
+/*N*/ }
+/*N*/ break;
+/*N*/
+/*N*/ case uno::TypeClass_INTERFACE:
+/*N*/ {
+/*N*/ //! directly extract XVolatileResult from any?
+/*N*/ uno::Reference<uno::XInterface> xInterface;
+/*N*/ rNewRes >>= xInterface;
+/*N*/ if ( xInterface.is() )
+/*N*/ xVarRes = uno::Reference<sheet::XVolatileResult>( xInterface, uno::UNO_QUERY );
+/*N*/
+/*N*/ if (!xVarRes.is())
+/*N*/ nErrCode = errNoValue; // unknown interface
+/*N*/ }
+/*N*/ break;
+/*N*/
+/*N*/ default:
+/*N*/ if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<INT32> > *)0 ) ) )
+/*N*/ {
+/*N*/ const uno::Sequence< uno::Sequence<INT32> >* pRowSeq = NULL;
+/*N*/
+/*N*/ //! use pointer from any!
+/*N*/ uno::Sequence< uno::Sequence<INT32> > aSequence;
+/*N*/ if ( rNewRes >>= aSequence )
+/*N*/ pRowSeq = &aSequence;
+/*N*/
+/*N*/ if ( pRowSeq )
+/*N*/ {
+/*N*/ long nRowCount = pRowSeq->getLength();
+/*N*/ const uno::Sequence<INT32>* pRowArr = pRowSeq->getConstArray();
+/*N*/ long nMaxColCount = 0;
+/*N*/ long nCol, nRow;
+/*N*/ for (nRow=0; nRow<nRowCount; nRow++)
+/*N*/ {
+/*N*/ long nTmp = pRowArr[nRow].getLength();
+/*N*/ if ( nTmp > nMaxColCount )
+/*N*/ nMaxColCount = nTmp;
+/*N*/ }
+/*N*/ if ( nMaxColCount && nRowCount )
+/*N*/ {
+/*N*/ pMatrix = new ScMatrix( (USHORT)nMaxColCount, (USHORT)nRowCount );
+/*N*/ for (nRow=0; nRow<nRowCount; nRow++)
+/*N*/ {
+/*N*/ long nColCount = pRowArr[nRow].getLength();
+/*N*/ const INT32* pColArr = pRowArr[nRow].getConstArray();
+/*N*/ for (nCol=0; nCol<nColCount; nCol++)
+/*N*/ pMatrix->PutDouble( pColArr[nCol], (USHORT)nCol, (USHORT)nRow );
+/*N*/ for (nCol=nColCount; nCol<nMaxColCount; nCol++)
+/*N*/ pMatrix->PutDouble( 0.0, (USHORT)nCol, (USHORT)nRow );
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<double> > *)0 ) ) )
+/*N*/ {
+/*N*/ const uno::Sequence< uno::Sequence<double> >* pRowSeq = NULL;
+/*N*/
+/*N*/ //! use pointer from any!
+/*N*/ uno::Sequence< uno::Sequence<double> > aSequence;
+/*N*/ if ( rNewRes >>= aSequence )
+/*N*/ pRowSeq = &aSequence;
+/*N*/
+/*N*/ if ( pRowSeq )
+/*N*/ {
+/*N*/ long nRowCount = pRowSeq->getLength();
+/*N*/ const uno::Sequence<double>* pRowArr = pRowSeq->getConstArray();
+/*N*/ long nMaxColCount = 0;
+/*N*/ long nCol, nRow;
+/*N*/ for (nRow=0; nRow<nRowCount; nRow++)
+/*N*/ {
+/*N*/ long nTmp = pRowArr[nRow].getLength();
+/*N*/ if ( nTmp > nMaxColCount )
+/*N*/ nMaxColCount = nTmp;
+/*N*/ }
+/*N*/ if ( nMaxColCount && nRowCount )
+/*N*/ {
+/*N*/ pMatrix = new ScMatrix( (USHORT)nMaxColCount, (USHORT)nRowCount );
+/*N*/ for (nRow=0; nRow<nRowCount; nRow++)
+/*N*/ {
+/*N*/ long nColCount = pRowArr[nRow].getLength();
+/*N*/ const double* pColArr = pRowArr[nRow].getConstArray();
+/*N*/ for (nCol=0; nCol<nColCount; nCol++)
+/*N*/ pMatrix->PutDouble( pColArr[nCol], (USHORT)nCol, (USHORT)nRow );
+/*N*/ for (nCol=nColCount; nCol<nMaxColCount; nCol++)
+/*N*/ pMatrix->PutDouble( 0.0, (USHORT)nCol, (USHORT)nRow );
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<rtl::OUString> > *)0 ) ) )
+/*N*/ {
+/*N*/ const uno::Sequence< uno::Sequence<rtl::OUString> >* pRowSeq = NULL;
+/*N*/
+/*N*/ //! use pointer from any!
+/*N*/ uno::Sequence< uno::Sequence<rtl::OUString> > aSequence;
+/*N*/ if ( rNewRes >>= aSequence )
+/*N*/ pRowSeq = &aSequence;
+/*N*/
+/*N*/ if ( pRowSeq )
+/*N*/ {
+/*N*/ long nRowCount = pRowSeq->getLength();
+/*N*/ const uno::Sequence<rtl::OUString>* pRowArr = pRowSeq->getConstArray();
+/*N*/ long nMaxColCount = 0;
+/*N*/ long nCol, nRow;
+/*N*/ for (nRow=0; nRow<nRowCount; nRow++)
+/*N*/ {
+/*N*/ long nTmp = pRowArr[nRow].getLength();
+/*N*/ if ( nTmp > nMaxColCount )
+/*N*/ nMaxColCount = nTmp;
+/*N*/ }
+/*N*/ if ( nMaxColCount && nRowCount )
+/*N*/ {
+/*N*/ pMatrix = new ScMatrix( (USHORT)nMaxColCount, (USHORT)nRowCount );
+/*N*/ for (nRow=0; nRow<nRowCount; nRow++)
+/*N*/ {
+/*N*/ long nColCount = pRowArr[nRow].getLength();
+/*N*/ const ::rtl::OUString* pColArr = pRowArr[nRow].getConstArray();
+/*N*/ for (nCol=0; nCol<nColCount; nCol++)
+/*N*/ pMatrix->PutString( String( pColArr[nCol] ),
+/*N*/ (USHORT)nCol, (USHORT)nRow );
+/*N*/ for (nCol=nColCount; nCol<nMaxColCount; nCol++)
+/*N*/ pMatrix->PutString( EMPTY_STRING, (USHORT)nCol, (USHORT)nRow );
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<uno::Any> > *)0 ) ) )
+/*N*/ {
+/*N*/ const uno::Sequence< uno::Sequence<uno::Any> >* pRowSeq = NULL;
+/*N*/
+/*N*/ //! use pointer from any!
+/*N*/ uno::Sequence< uno::Sequence<uno::Any> > aSequence;
+/*N*/ if ( rNewRes >>= aSequence )
+/*N*/ pRowSeq = &aSequence;
+/*N*/
+/*N*/ if ( pRowSeq )
+/*N*/ {
+/*N*/ long nRowCount = pRowSeq->getLength();
+/*N*/ const uno::Sequence<uno::Any>* pRowArr = pRowSeq->getConstArray();
+/*N*/ long nMaxColCount = 0;
+/*N*/ long nCol, nRow;
+/*N*/ for (nRow=0; nRow<nRowCount; nRow++)
+/*N*/ {
+/*N*/ long nTmp = pRowArr[nRow].getLength();
+/*N*/ if ( nTmp > nMaxColCount )
+/*N*/ nMaxColCount = nTmp;
+/*N*/ }
+/*N*/ if ( nMaxColCount && nRowCount )
+/*N*/ {
+/*N*/ ::rtl::OUString aUStr;
+/*N*/ pMatrix = new ScMatrix( (USHORT)nMaxColCount, (USHORT)nRowCount );
+/*N*/ for (nRow=0; nRow<nRowCount; nRow++)
+/*N*/ {
+/*N*/ long nColCount = pRowArr[nRow].getLength();
+/*N*/ const uno::Any* pColArr = pRowArr[nRow].getConstArray();
+/*N*/ for (nCol=0; nCol<nColCount; nCol++)
+/*N*/ {
+/*N*/ //Reflection* pRefl = pColArr[nCol].getReflection();
+/*N*/ //if ( pRefl->equals( *OUString_getReflection() ) )
+/*N*/ if ( pColArr[nCol] >>= aUStr )
+/*N*/ pMatrix->PutString( String( aUStr ),
+/*N*/ (USHORT)nCol, (USHORT)nRow );
+/*N*/ else
+/*N*/ {
+/*N*/ // try to convert to double, empty if not possible
+/*N*/
+/*N*/ double fCellVal;
+/*N*/ if ( lcl_ConvertToDouble( pColArr[nCol], fCellVal ) )
+/*N*/ pMatrix->PutDouble( fCellVal, (USHORT)nCol, (USHORT)nRow );
+/*N*/ else
+/*N*/ pMatrix->PutEmpty( (USHORT)nCol, (USHORT)nRow );
+/*N*/ }
+/*N*/ }
+/*N*/ for (nCol=nColCount; nCol<nMaxColCount; nCol++)
+/*N*/ pMatrix->PutString( EMPTY_STRING, (USHORT)nCol, (USHORT)nRow );
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ if (!pMatrix) // no array found
+/*N*/ nErrCode = errNoValue; //! code for error in return type???
+/*N*/ }
+/*N*/ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */