1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #ifndef OOX_XLS_FORMULAPARSER_HXX 29 #define OOX_XLS_FORMULAPARSER_HXX 30 31 #include "oox/xls/formulabase.hxx" 32 33 namespace oox { 34 namespace xls { 35 36 // formula finalizer ========================================================== 37 38 /** A generic formula token array finalizer. 39 40 After building a formula token array from alien binary file formats, or 41 parsing an XML formula string using the com.sun.star.sheet.FormulaParser 42 service, the token array is still not ready to be put into the spreadsheet 43 document. There may be functions with a wrong number of parameters (missing 44 but required parameters, or unsupported parameters) or intermediate tokens 45 used to encode references to macro functions or add-in functions. This 46 helper processes a passed token array and builds a new compatible token 47 array. 48 49 Derived classes may add more functionality by overwriting the virtual 50 functions. 51 */ 52 class FormulaFinalizer : public OpCodeProvider, protected ApiOpCodes 53 { 54 public: 55 explicit FormulaFinalizer( const OpCodeProvider& rOpCodeProv ); 56 57 /** Finalizes and returns the passed token array. */ 58 ApiTokenSequence finalizeTokenArray( const ApiTokenSequence& rTokens ); 59 60 protected: 61 /** Derived classed may try to find a function info struct from the passed 62 string extracted from an OPCODE_BAD token. 63 64 @param rTokenData The string that has been found in an OPCODE_BAD 65 token preceding the function parentheses. 66 */ 67 virtual const FunctionInfo* resolveBadFuncName( const ::rtl::OUString& rTokenData ) const; 68 69 /** Derived classed may try to find the name of a defined name with the 70 passed index extracted from an OPCODE_NAME token. 71 72 @param nTokenIndex The index of the defined name that has been found 73 in an OPCODE_NAME token preceding the function parentheses. 74 */ 75 virtual ::rtl::OUString resolveDefinedName( sal_Int32 nTokenIndex ) const; 76 77 private: 78 typedef ::std::vector< const ApiToken* > ParameterPosVector; 79 80 const FunctionInfo* getFunctionInfo( ApiToken& orFuncToken ); 81 const FunctionInfo* getExternCallInfo( ApiToken& orFuncToken, const ApiToken& rECToken ); 82 83 void processTokens( const ApiToken* pToken, const ApiToken* pTokenEnd ); 84 const ApiToken* processParameters( const FunctionInfo& rFuncInfo, const ApiToken* pToken, const ApiToken* pTokenEnd ); 85 86 bool isEmptyParameter( const ApiToken* pToken, const ApiToken* pTokenEnd ) const; 87 const ApiToken* getSingleToken( const ApiToken* pToken, const ApiToken* pTokenEnd ) const; 88 const ApiToken* skipParentheses( const ApiToken* pToken, const ApiToken* pTokenEnd ) const; 89 const ApiToken* findParameters( ParameterPosVector& rParams, const ApiToken* pToken, const ApiToken* pTokenEnd ) const; 90 void appendEmptyParameter( const FunctionInfo& rFuncInfo, size_t nParam ); 91 void appendCalcOnlyParameter( const FunctionInfo& rFuncInfo, size_t nParam ); 92 void appendRequiredParameters( const FunctionInfo& rFuncInfo, size_t nParamCount ); 93 94 bool appendFinalToken( const ApiToken& rToken ); 95 96 private: 97 ApiTokenVector maTokens; 98 }; 99 100 // ============================================================================ 101 102 class FormulaParserImpl; 103 104 /** Import formula parser for OOXML and BIFF filters. 105 106 This class implements formula import for the OOXML and BIFF filter. One 107 instance is contained in the global filter data to prevent construction and 108 destruction of internal buffers for every imported formula. 109 */ 110 class FormulaParser : public FormulaProcessorBase 111 { 112 public: 113 explicit FormulaParser( const WorkbookHelper& rHelper ); 114 virtual ~FormulaParser(); 115 116 /** Converts an OOXML formula string. */ 117 ApiTokenSequence importFormula( 118 const ::com::sun::star::table::CellAddress& rBaseAddr, 119 const ::rtl::OUString& rFormulaString ) const; 120 121 /** Imports and converts a BIFF12 token array from the passed stream. */ 122 ApiTokenSequence importFormula( 123 const ::com::sun::star::table::CellAddress& rBaseAddr, 124 FormulaType eType, 125 SequenceInputStream& rStrm ) const; 126 127 /** Imports and converts a BIFF2-BIFF8 token array from the passed stream. 128 @param pnFmlaSize Size of the token array. If null is passed, reads 129 it from stream (1 byte in BIFF2, 2 bytes otherwise) first. */ 130 ApiTokenSequence importFormula( 131 const ::com::sun::star::table::CellAddress& rBaseAddr, 132 FormulaType eType, 133 BiffInputStream& rStrm, 134 const sal_uInt16* pnFmlaSize = 0 ) const; 135 136 /** Converts the passed Boolean value to a similar formula. */ 137 ApiTokenSequence convertBoolToFormula( bool bValue ) const; 138 139 /** Converts the passed BIFF error code to a similar formula. */ 140 ApiTokenSequence convertErrorToFormula( sal_uInt8 nErrorCode ) const; 141 142 /** Converts the passed token index of a defined name to a formula calling that name. */ 143 ApiTokenSequence convertNameToFormula( sal_Int32 nTokenIndex ) const; 144 145 /** Converts the passed number into a HYPERLINK formula with the passed URL. */ 146 ApiTokenSequence convertNumberToHyperlink( const ::rtl::OUString& rUrl, double fValue ) const; 147 148 /** Converts the passed XML formula to an OLE link target. */ 149 ::rtl::OUString importOleTargetLink( const ::rtl::OUString& rFormulaString ); 150 151 /** Imports and converts an OLE link target from the passed stream. */ 152 ::rtl::OUString importOleTargetLink( SequenceInputStream& rStrm ); 153 154 /** Imports and converts an OLE link target from the passed stream. */ 155 ::rtl::OUString importOleTargetLink( BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize = 0 ) const; 156 157 /** Converts the passed formula to a macro name for a drawing shape. */ 158 ::rtl::OUString importMacroName( const ::rtl::OUString& rFormulaString ); 159 160 private: 161 ::std::auto_ptr< FormulaParserImpl > mxImpl; 162 }; 163 164 // ============================================================================ 165 166 } // namespace xls 167 } // namespace oox 168 169 #endif 170