Update ooo320-m1
[ooovba.git] / oox / source / xls / ooxformulaparser.cxx
blob62e8189bdd001b4fb10d32800bcbae16f5aa09ed
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ooxformulaparser.cxx,v $
10 * $Revision: 1.1 $
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 ************************************************************************/
31 #include "oox/xls/ooxformulaparser.hxx"
32 #include <com/sun/star/uno/XComponentContext.hpp>
33 #include "oox/xls/formulaparser.hxx"
35 using ::rtl::OUString;
36 using ::com::sun::star::uno::Any;
37 using ::com::sun::star::uno::Exception;
38 using ::com::sun::star::uno::Reference;
39 using ::com::sun::star::uno::RuntimeException;
40 using ::com::sun::star::uno::Sequence;
41 using ::com::sun::star::uno::UNO_QUERY_THROW;
42 using ::com::sun::star::uno::XComponentContext;
43 using ::com::sun::star::uno::XInterface;
44 using ::com::sun::star::lang::XMultiServiceFactory;
45 using ::com::sun::star::table::CellAddress;
46 using ::com::sun::star::sheet::FormulaToken;
48 namespace oox {
49 namespace xls {
51 // ============================================================================
53 class OOXMLFormulaParserImpl : private FormulaFinalizer
55 public:
56 explicit OOXMLFormulaParserImpl( const Reference< XMultiServiceFactory >& rxFactory );
58 Sequence< FormulaToken > parseFormula( const OUString& rFormula, const CellAddress& rReferencePos );
60 protected:
61 virtual const FunctionInfo* resolveBadFuncName( const OUString& rTokenData ) const;
63 private:
64 ApiParserWrapper maApiParser;
67 // ----------------------------------------------------------------------------
69 OOXMLFormulaParserImpl::OOXMLFormulaParserImpl( const Reference< XMultiServiceFactory >& rxFactory ) :
70 FormulaFinalizer( OpCodeProvider( rxFactory, FILTER_OOX, BIFF_UNKNOWN, true ) ),
71 maApiParser( rxFactory, *this )
75 Sequence< FormulaToken > OOXMLFormulaParserImpl::parseFormula( const OUString& rFormula, const CellAddress& rReferencePos )
77 return finalizeTokenArray( maApiParser.parseFormula( rFormula, rReferencePos ) );
80 const FunctionInfo* OOXMLFormulaParserImpl::resolveBadFuncName( const OUString& rTokenData ) const
82 /* Try to parse calls to library functions. The format of such a function
83 call is assumed to be
84 "'<path-to-office-install>\Library\<libname>'!<funcname>". */
86 // the string has to start with an apostroph (followed by the library URL)
87 if( (rTokenData.getLength() >= 6) && (rTokenData[ 0 ] == '\'') )
89 // library URL and function name are separated by an exclamation mark
90 sal_Int32 nExclamPos = rTokenData.lastIndexOf( '!' );
91 if( (1 < nExclamPos) && (nExclamPos + 1 < rTokenData.getLength()) && (rTokenData[ nExclamPos - 1 ] == '\'') )
93 // find the last backslash that separates library path and name
94 sal_Int32 nFileSep = rTokenData.lastIndexOf( '\\', nExclamPos - 2 );
95 if( nFileSep > 1 )
97 // find preceding backslash that separates the last directory name
98 sal_Int32 nDirSep = rTokenData.lastIndexOf( '\\', nFileSep - 1 );
99 // function library is located in a directory called 'library'
100 if( (nDirSep > 0) && rTokenData.matchIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "\\LIBRARY\\" ), nDirSep ) )
102 // try to find a function info for the function name
103 OUString aFuncName = rTokenData.copy( nExclamPos + 1 ).toAsciiUpperCase();
104 const FunctionInfo* pFuncInfo = getFuncInfoFromOoxFuncName( aFuncName );
105 if( pFuncInfo && (pFuncInfo->meFuncLibType != FUNCLIB_UNKNOWN) )
107 // check that the name of the library matches
108 OUString aLibName = rTokenData.copy( nFileSep + 1, nExclamPos - nFileSep - 2 );
109 if( pFuncInfo->meFuncLibType == getFuncLibTypeFromLibraryName( aLibName ) )
110 return pFuncInfo;
116 return 0;
119 // ============================================================================
121 class OOXMLFormulaPrinterImpl : public OpCodeProvider
123 public:
124 explicit OOXMLFormulaPrinterImpl( const Reference< XMultiServiceFactory >& rxFactory );
126 private:
127 ApiParserWrapper maApiParser;
130 // ----------------------------------------------------------------------------
132 OOXMLFormulaPrinterImpl::OOXMLFormulaPrinterImpl( const Reference< XMultiServiceFactory >& rxFactory ) :
133 OpCodeProvider( rxFactory, FILTER_OOX, BIFF_UNKNOWN, false ),
134 maApiParser( rxFactory, *this )
138 // ============================================================================
140 Sequence< OUString > OOXMLFormulaParser_getSupportedServiceNames()
142 Sequence< OUString > aServiceNames( 1 );
143 aServiceNames[ 0 ] = CREATE_OUSTRING( "com.sun.star.sheet.FilterFormulaParser" );
144 return aServiceNames;
147 OUString OOXMLFormulaParser_getImplementationName()
149 return CREATE_OUSTRING( "com.sun.star.comp.oox.OOXMLFormulaParser" );
152 Reference< XInterface > SAL_CALL OOXMLFormulaParser_createInstance( const Reference< XComponentContext >& ) throw( Exception )
154 return static_cast< ::cppu::OWeakObject* >( new OOXMLFormulaParser );
157 // ============================================================================
159 OOXMLFormulaParser::OOXMLFormulaParser()
163 OOXMLFormulaParser::~OOXMLFormulaParser()
167 // com.sun.star.lang.XServiceInfo interface -----------------------------------
169 OUString SAL_CALL OOXMLFormulaParser::getImplementationName() throw( RuntimeException )
171 return OOXMLFormulaParser_getImplementationName();
174 sal_Bool SAL_CALL OOXMLFormulaParser::supportsService( const OUString& rService ) throw( RuntimeException )
176 const Sequence< OUString > aServices( OOXMLFormulaParser_getSupportedServiceNames() );
177 const OUString* pArray = aServices.getConstArray();
178 const OUString* pArrayEnd = pArray + aServices.getLength();
179 return ::std::find( pArray, pArrayEnd, rService ) != pArrayEnd;
182 Sequence< OUString > SAL_CALL OOXMLFormulaParser::getSupportedServiceNames() throw( RuntimeException )
184 return OOXMLFormulaParser_getSupportedServiceNames();
187 // com.sun.star.lang.XInitialization interface --------------------------------
189 void SAL_CALL OOXMLFormulaParser::initialize( const Sequence< Any >& rArgs ) throw( Exception, RuntimeException )
191 OSL_ENSURE( rArgs.hasElements(), "OOXMLFormulaParser::initialize - missing arguments" );
192 if( !rArgs.hasElements() )
193 throw RuntimeException();
194 mxComponent.set( rArgs[ 0 ], UNO_QUERY_THROW );
197 // com.sun.star.sheet.XFilterFormulaParser interface --------------------------
199 OUString SAL_CALL OOXMLFormulaParser::getSupportedNamespace() throw( RuntimeException )
201 return CREATE_OUSTRING( "http://schemas.microsoft.com/office/excel/formula" );
204 // com.sun.star.sheet.XFormulaParser interface --------------------------------
206 Sequence< FormulaToken > SAL_CALL OOXMLFormulaParser::parseFormula(
207 const OUString& rFormula, const CellAddress& rReferencePos ) throw( RuntimeException )
209 if( !mxParserImpl )
211 Reference< XMultiServiceFactory > xFactory( mxComponent, UNO_QUERY_THROW );
212 mxParserImpl.reset( new OOXMLFormulaParserImpl( xFactory ) );
214 return mxParserImpl->parseFormula( rFormula, rReferencePos );
217 OUString SAL_CALL OOXMLFormulaParser::printFormula(
218 const Sequence< FormulaToken >& /*rTokens*/, const CellAddress& /*rReferencePos*/ ) throw( RuntimeException )
220 // not implemented
221 throw RuntimeException();
224 // ============================================================================
226 } // namespace xls
227 } // namespace oox