merge the formfield patch from ooo-build
[ooovba.git] / sc / source / ui / vba / vbawsfunction.cxx
blobdf41e57b2b9a4f9641856bf8dd7ab07962485e00
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: vbawsfunction.cxx,v $
10 * $Revision: 1.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
30 #include <com/sun/star/beans/XPropertySet.hpp>
31 #include <com/sun/star/table/XCell.hpp>
32 #include <com/sun/star/table/XColumnRowRange.hpp>
33 #include <com/sun/star/beans/XIntrospection.hpp>
34 #include <com/sun/star/beans/XIntrospectionAccess.hpp>
35 #include <com/sun/star/sheet/XFunctionAccess.hpp>
36 #include <com/sun/star/sheet/XCellRangesQuery.hpp>
37 #include <com/sun/star/sheet/CellFlags.hpp>
38 #include <com/sun/star/reflection/XIdlMethod.hpp>
39 #include <com/sun/star/beans/MethodConcept.hpp>
40 #include <comphelper/processfactory.hxx>
41 #include <cppuhelper/queryinterface.hxx>
42 #include <comphelper/anytostring.hxx>
44 #include "vbawsfunction.hxx"
45 #include "compiler.hxx"
47 using namespace com::sun::star;
48 using namespace ooo::vba;
50 ScVbaWSFunction::ScVbaWSFunction( const uno::Reference< XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext): ScVbaWSFunction_BASE( xParent, xContext )
55 uno::Reference< beans::XIntrospectionAccess >
56 ScVbaWSFunction::getIntrospection(void) throw(uno::RuntimeException)
58 return uno::Reference<beans::XIntrospectionAccess>();
61 uno::Any SAL_CALL
62 ScVbaWSFunction::invoke(const rtl::OUString& FunctionName, const uno::Sequence< uno::Any >& Params, uno::Sequence< sal_Int16 >& /*OutParamIndex*/, uno::Sequence< uno::Any >& /*OutParam*/) throw(lang::IllegalArgumentException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException)
64 uno::Reference< lang::XMultiComponentFactory > xSMgr( mxContext->getServiceManager(), uno::UNO_QUERY_THROW );
65 uno::Reference< sheet::XFunctionAccess > xFunctionAccess(
66 xSMgr->createInstanceWithContext(::rtl::OUString::createFromAscii(
67 "com.sun.star.sheet.FunctionAccess"), mxContext),
68 ::uno::UNO_QUERY_THROW);
69 uno::Sequence< uno::Any > aParamTemp;
70 sal_Int32 nParamCount = Params.getLength();
71 aParamTemp.realloc(nParamCount);
72 const uno::Any* aArray = Params.getConstArray();
73 uno::Any* aArrayTemp = aParamTemp.getArray();
75 for (int i=0; i < Params.getLength();i++)
77 aArrayTemp[i]= aArray[i];
78 uno::Reference<excel::XRange> myRange( aArray[ i ], uno::UNO_QUERY );
79 if ( myRange.is() )
81 aArrayTemp[i] = myRange->getCellRange();
82 continue;
84 else if ( aArray[ i ].getValueType().getTypeClass() == uno::TypeClass_BOOLEAN )
86 sal_Bool bValue( sal_False );
87 aArray[ i ] >>= bValue;
88 if ( bValue )
89 aArrayTemp[ i ] <<= double( 1.0 );
90 else
91 aArrayTemp[ i ] <<= double( 0.0 );
94 else if ( aArray[ i ].getValueType().getTypeClass() == uno::TypeClass_SEQUENCE )
96 // the sheet.FunctionAccess service doesn't deal with Sequences, only Sequences of Sequence
97 uno::Type aType = aArray[ i ].getValueType();
98 if ( aType.equals( getCppuType( (uno::Sequence<sal_Int16>*)0 ) ) )
100 uno::Sequence< uno::Sequence< sal_Int16 > > aTmp(1);
101 aArray[ i ] >>= aTmp[ 0 ];
102 aArrayTemp[i] <<= aTmp;
104 else if ( aType.equals( getCppuType( (uno::Sequence<sal_Int32>*)0 ) ) )
106 uno::Sequence< uno::Sequence< sal_Int32 > > aTmp(1);
107 aArray[ i ] >>= aTmp[ 0 ];
108 aArrayTemp[i] <<= aTmp;
110 else if ( aType.equals( getCppuType( (uno::Sequence<double>*)0 ) ) )
112 uno::Sequence< uno::Sequence< double > > aTmp(1);
113 aArray[ i ] >>= aTmp[ 0 ];
114 aArrayTemp[i] <<= aTmp;
116 else if ( aType.equals( getCppuType( (uno::Sequence<rtl::OUString>*)0 ) ) )
118 uno::Sequence< uno::Sequence< rtl::OUString > > aTmp(1);
119 aArray[ i ] >>= aTmp[ 0 ];
120 aArrayTemp[i] <<= aTmp;
122 else if ( aType.equals( getCppuType( (uno::Sequence<uno::Any>*)0 ) ) )
124 uno::Sequence< uno::Sequence<uno::Any > > aTmp(1);
125 aArray[ i ] >>= aTmp[ 0 ];
126 aArrayTemp[i] <<= aTmp;
131 for ( int count=0; count < aParamTemp.getLength(); ++count )
132 OSL_TRACE("Param[%d] is %s",
133 count, rtl::OUStringToOString( comphelper::anyToString( aParamTemp[count] ), RTL_TEXTENCODING_UTF8 ).getStr() );
135 uno::Any aRet = xFunctionAccess->callFunction(FunctionName,aParamTemp);
137 // MATCH function should alwayse return a double value, but currently if the first argument is XCellRange, MATCH function returns an array instead of a double value. Don't know why?
138 // To fix this issue in safe, current solution is to convert this array to a double value just for MATCH function.
139 String aUpper( FunctionName );
140 ScCompiler aCompiler( NULL, ScAddress() );
141 OpCode eOp = aCompiler.GetEnglishOpCode( aUpper.ToUpperAscii() );
142 if( eOp == ocMatch || eOp == ocIsError )
144 double fVal = 0.0;
145 if( aRet >>= fVal )
146 return aRet;
147 uno::Sequence< uno::Sequence< uno::Any > > aSequence;
148 if( !( ( aRet >>= aSequence ) && ( aSequence.getLength() > 0 ) &&
149 ( aSequence[0].getLength() > 0 ) && ( aSequence[0][0] >>= fVal ) ) )
150 throw uno::RuntimeException();
151 aRet <<= fVal;
153 return aRet;
156 void SAL_CALL
157 ScVbaWSFunction::setValue(const rtl::OUString& /*PropertyName*/, const uno::Any& /*Value*/) throw(beans::UnknownPropertyException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException)
159 throw beans::UnknownPropertyException();
162 uno::Any SAL_CALL
163 ScVbaWSFunction::getValue(const rtl::OUString& /*PropertyName*/) throw(beans::UnknownPropertyException, uno::RuntimeException)
165 throw beans::UnknownPropertyException();
168 sal_Bool SAL_CALL
169 ScVbaWSFunction::hasMethod(const rtl::OUString& Name) throw(uno::RuntimeException)
171 sal_Bool bIsFound = sal_False;
172 try
174 // the function name contained in the com.sun.star.sheet.FunctionDescription service is alwayse localized.
175 // but the function name used in WorksheetFunction is a programmatic name (seems English).
176 // So m_xNameAccess->hasByName( Name ) may fail to find name when a function name has a localized name.
177 ScCompiler aCompiler( NULL, ScAddress() );
178 if( aCompiler.IsEnglishSymbol( Name ) )
179 bIsFound = sal_True;
181 catch( uno::Exception& /*e*/ )
183 // failed to find name
185 return bIsFound;
188 sal_Bool SAL_CALL
189 ScVbaWSFunction::hasProperty(const rtl::OUString& /*Name*/) throw(uno::RuntimeException)
191 return sal_False;
194 ::rtl::OUString SAL_CALL
195 ScVbaWSFunction::getExactName( const ::rtl::OUString& aApproximateName ) throw (css::uno::RuntimeException)
197 rtl::OUString sName = aApproximateName.toAsciiUpperCase();
198 if ( !hasMethod( sName ) )
199 return rtl::OUString();
200 return sName;
203 rtl::OUString&
204 ScVbaWSFunction::getServiceImplName()
206 static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaWSFunction") );
207 return sImplName;
210 uno::Sequence< rtl::OUString >
211 ScVbaWSFunction::getServiceNames()
213 static uno::Sequence< rtl::OUString > aServiceNames;
214 if ( aServiceNames.getLength() == 0 )
216 aServiceNames.realloc( 1 );
217 aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.WorksheetFunction" ) );
219 return aServiceNames;