1*b3f79822SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*b3f79822SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*b3f79822SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*b3f79822SAndrew Rist * distributed with this work for additional information 6*b3f79822SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*b3f79822SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*b3f79822SAndrew Rist * "License"); you may not use this file except in compliance 9*b3f79822SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*b3f79822SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*b3f79822SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*b3f79822SAndrew Rist * software distributed under the License is distributed on an 15*b3f79822SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b3f79822SAndrew Rist * KIND, either express or implied. See the License for the 17*b3f79822SAndrew Rist * specific language governing permissions and limitations 18*b3f79822SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*b3f79822SAndrew Rist *************************************************************/ 21*b3f79822SAndrew Rist 22*b3f79822SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_sc.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include "tokenuno.hxx" 28cdf0e10cSrcweir 29cdf0e10cSrcweir #include <com/sun/star/sheet/ComplexReference.hpp> 30cdf0e10cSrcweir #include <com/sun/star/sheet/ExternalReference.hpp> 31cdf0e10cSrcweir #include <com/sun/star/sheet/ReferenceFlags.hpp> 32cdf0e10cSrcweir #include <com/sun/star/sheet/AddressConvention.hpp> 33cdf0e10cSrcweir #include <com/sun/star/table/CellAddress.hpp> 34cdf0e10cSrcweir 35cdf0e10cSrcweir #include <svl/itemprop.hxx> 36cdf0e10cSrcweir 37cdf0e10cSrcweir #include "miscuno.hxx" 38cdf0e10cSrcweir #include "convuno.hxx" 39cdf0e10cSrcweir #include "unonames.hxx" 40cdf0e10cSrcweir #include "unoguard.hxx" 41cdf0e10cSrcweir #include "token.hxx" 42cdf0e10cSrcweir #include "compiler.hxx" 43cdf0e10cSrcweir #include "tokenarray.hxx" 44cdf0e10cSrcweir #include "docsh.hxx" 45cdf0e10cSrcweir #include "rangeseq.hxx" 46cdf0e10cSrcweir #include "externalrefmgr.hxx" 47cdf0e10cSrcweir 48cdf0e10cSrcweir using namespace ::formula; 49cdf0e10cSrcweir using namespace ::com::sun::star; 50cdf0e10cSrcweir 51cdf0e10cSrcweir // ============================================================================ 52cdf0e10cSrcweir 53cdf0e10cSrcweir const SfxItemPropertyMapEntry* lcl_GetFormulaParserMap() 54cdf0e10cSrcweir { 55cdf0e10cSrcweir static SfxItemPropertyMapEntry aFormulaParserMap_Impl[] = 56cdf0e10cSrcweir { 57cdf0e10cSrcweir {MAP_CHAR_LEN(SC_UNO_COMPILEFAP), 0, &getBooleanCppuType(), 0, 0 }, 58cdf0e10cSrcweir {MAP_CHAR_LEN(SC_UNO_COMPILEENGLISH), 0, &getBooleanCppuType(), 0, 0 }, 59cdf0e10cSrcweir {MAP_CHAR_LEN(SC_UNO_IGNORELEADING), 0, &getBooleanCppuType(), 0, 0 }, 60cdf0e10cSrcweir {MAP_CHAR_LEN(SC_UNO_FORMULACONVENTION), 0, &getCppuType(&sheet::AddressConvention::UNSPECIFIED), 0, 0 }, 61cdf0e10cSrcweir {MAP_CHAR_LEN(SC_UNO_OPCODEMAP), 0, &getCppuType((uno::Sequence< sheet::FormulaOpCodeMapEntry >*)0), 0, 0 }, 62cdf0e10cSrcweir {0,0,0,0,0,0} 63cdf0e10cSrcweir }; 64cdf0e10cSrcweir return aFormulaParserMap_Impl; 65cdf0e10cSrcweir } 66cdf0e10cSrcweir 67cdf0e10cSrcweir SC_SIMPLE_SERVICE_INFO( ScFormulaParserObj, "ScFormulaParserObj", SC_SERVICENAME_FORMULAPARS ) 68cdf0e10cSrcweir 69cdf0e10cSrcweir // ============================================================================ 70cdf0e10cSrcweir 71cdf0e10cSrcweir ScFormulaParserObj::ScFormulaParserObj(ScDocShell* pDocSh) : 72cdf0e10cSrcweir mpDocShell( pDocSh ), 73cdf0e10cSrcweir mnConv( sheet::AddressConvention::UNSPECIFIED ), 74cdf0e10cSrcweir mbEnglish( false ), 75cdf0e10cSrcweir mbIgnoreSpaces( true ), 76cdf0e10cSrcweir mbCompileFAP( false ) 77cdf0e10cSrcweir { 78cdf0e10cSrcweir mpDocShell->GetDocument()->AddUnoObject(*this); 79cdf0e10cSrcweir } 80cdf0e10cSrcweir 81cdf0e10cSrcweir ScFormulaParserObj::~ScFormulaParserObj() 82cdf0e10cSrcweir { 83cdf0e10cSrcweir if (mpDocShell) 84cdf0e10cSrcweir mpDocShell->GetDocument()->RemoveUnoObject(*this); 85cdf0e10cSrcweir } 86cdf0e10cSrcweir 87cdf0e10cSrcweir void ScFormulaParserObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) 88cdf0e10cSrcweir { 89cdf0e10cSrcweir if ( rHint.ISA( SfxSimpleHint ) && ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) 90cdf0e10cSrcweir mpDocShell = NULL; 91cdf0e10cSrcweir } 92cdf0e10cSrcweir 93cdf0e10cSrcweir // XFormulaParser 94cdf0e10cSrcweir 95cdf0e10cSrcweir void ScFormulaParserObj::SetCompilerFlags( ScCompiler& rCompiler ) const 96cdf0e10cSrcweir { 97cdf0e10cSrcweir static const formula::FormulaGrammar::AddressConvention aConvMap[] = { 98cdf0e10cSrcweir formula::FormulaGrammar::CONV_OOO, // <- AddressConvention::OOO 99cdf0e10cSrcweir formula::FormulaGrammar::CONV_XL_A1, // <- AddressConvention::XL_A1 100cdf0e10cSrcweir formula::FormulaGrammar::CONV_XL_R1C1, // <- AddressConvention::XL_R1C1 101cdf0e10cSrcweir formula::FormulaGrammar::CONV_XL_OOX, // <- AddressConvention::XL_OOX 102cdf0e10cSrcweir formula::FormulaGrammar::CONV_LOTUS_A1 // <- AddressConvention::LOTUS_A1 103cdf0e10cSrcweir }; 104cdf0e10cSrcweir static const sal_Int16 nConvMapCount = sizeof(aConvMap)/sizeof(aConvMap[0]); 105cdf0e10cSrcweir 106cdf0e10cSrcweir // If mxOpCodeMap is not empty it overrides mbEnglish, and vice versa. We 107cdf0e10cSrcweir // don't need to initialize things twice. 108cdf0e10cSrcweir if (mxOpCodeMap.get()) 109cdf0e10cSrcweir rCompiler.SetFormulaLanguage( mxOpCodeMap ); 110cdf0e10cSrcweir else 111cdf0e10cSrcweir { 112cdf0e10cSrcweir sal_Int32 nFormulaLanguage = mbEnglish ? 113cdf0e10cSrcweir sheet::FormulaLanguage::ENGLISH : 114cdf0e10cSrcweir sheet::FormulaLanguage::NATIVE; 115cdf0e10cSrcweir ScCompiler::OpCodeMapPtr xMap = rCompiler.GetOpCodeMap( nFormulaLanguage); 116cdf0e10cSrcweir rCompiler.SetFormulaLanguage( xMap); 117cdf0e10cSrcweir } 118cdf0e10cSrcweir 119cdf0e10cSrcweir formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_UNSPECIFIED; 120cdf0e10cSrcweir if (mnConv >= 0 && mnConv < nConvMapCount) 121cdf0e10cSrcweir eConv = aConvMap[mnConv]; 122cdf0e10cSrcweir 123cdf0e10cSrcweir rCompiler.SetRefConvention( eConv ); 124cdf0e10cSrcweir 125cdf0e10cSrcweir rCompiler.SetCompileForFAP(mbCompileFAP); 126cdf0e10cSrcweir 127cdf0e10cSrcweir rCompiler.SetExternalLinks( maExternalLinks); 128cdf0e10cSrcweir } 129cdf0e10cSrcweir 130cdf0e10cSrcweir uno::Sequence<sheet::FormulaToken> SAL_CALL ScFormulaParserObj::parseFormula( 131cdf0e10cSrcweir const rtl::OUString& aFormula, const table::CellAddress& rReferencePos ) 132cdf0e10cSrcweir throw (uno::RuntimeException) 133cdf0e10cSrcweir { 134cdf0e10cSrcweir ScUnoGuard aGuard; 135cdf0e10cSrcweir uno::Sequence<sheet::FormulaToken> aRet; 136cdf0e10cSrcweir 137cdf0e10cSrcweir if (mpDocShell) 138cdf0e10cSrcweir { 139cdf0e10cSrcweir ScDocument* pDoc = mpDocShell->GetDocument(); 140cdf0e10cSrcweir ScExternalRefManager::ApiGuard aExtRefGuard(pDoc); 141cdf0e10cSrcweir 142cdf0e10cSrcweir ScAddress aRefPos( ScAddress::UNINITIALIZED ); 143cdf0e10cSrcweir ScUnoConversion::FillScAddress( aRefPos, rReferencePos ); 144cdf0e10cSrcweir ScCompiler aCompiler( pDoc, aRefPos); 145cdf0e10cSrcweir aCompiler.SetGrammar(pDoc->GetGrammar()); 146cdf0e10cSrcweir SetCompilerFlags( aCompiler ); 147cdf0e10cSrcweir 148cdf0e10cSrcweir ScTokenArray* pCode = aCompiler.CompileString( aFormula ); 149cdf0e10cSrcweir (void)ScTokenConversion::ConvertToTokenSequence( *pDoc, aRet, *pCode ); 150cdf0e10cSrcweir delete pCode; 151cdf0e10cSrcweir } 152cdf0e10cSrcweir 153cdf0e10cSrcweir return aRet; 154cdf0e10cSrcweir } 155cdf0e10cSrcweir 156cdf0e10cSrcweir rtl::OUString SAL_CALL ScFormulaParserObj::printFormula( 157cdf0e10cSrcweir const uno::Sequence<sheet::FormulaToken>& aTokens, const table::CellAddress& rReferencePos ) 158cdf0e10cSrcweir throw (uno::RuntimeException) 159cdf0e10cSrcweir { 160cdf0e10cSrcweir ScUnoGuard aGuard; 161cdf0e10cSrcweir rtl::OUString aRet; 162cdf0e10cSrcweir 163cdf0e10cSrcweir if (mpDocShell) 164cdf0e10cSrcweir { 165cdf0e10cSrcweir ScDocument* pDoc = mpDocShell->GetDocument(); 166cdf0e10cSrcweir ScTokenArray aCode; 167cdf0e10cSrcweir (void)ScTokenConversion::ConvertToTokenArray( *pDoc, aCode, aTokens ); 168cdf0e10cSrcweir ScAddress aRefPos( ScAddress::UNINITIALIZED ); 169cdf0e10cSrcweir ScUnoConversion::FillScAddress( aRefPos, rReferencePos ); 170cdf0e10cSrcweir ScCompiler aCompiler( pDoc, aRefPos, aCode); 171cdf0e10cSrcweir aCompiler.SetGrammar(pDoc->GetGrammar()); 172cdf0e10cSrcweir SetCompilerFlags( aCompiler ); 173cdf0e10cSrcweir 174cdf0e10cSrcweir rtl::OUStringBuffer aBuffer; 175cdf0e10cSrcweir aCompiler.CreateStringFromTokenArray( aBuffer ); 176cdf0e10cSrcweir aRet = aBuffer.makeStringAndClear(); 177cdf0e10cSrcweir } 178cdf0e10cSrcweir 179cdf0e10cSrcweir return aRet; 180cdf0e10cSrcweir } 181cdf0e10cSrcweir 182cdf0e10cSrcweir // XPropertySet 183cdf0e10cSrcweir 184cdf0e10cSrcweir uno::Reference<beans::XPropertySetInfo> SAL_CALL ScFormulaParserObj::getPropertySetInfo() 185cdf0e10cSrcweir throw(uno::RuntimeException) 186cdf0e10cSrcweir { 187cdf0e10cSrcweir ScUnoGuard aGuard; 188cdf0e10cSrcweir static uno::Reference< beans::XPropertySetInfo > aRef(new SfxItemPropertySetInfo( lcl_GetFormulaParserMap() )); 189cdf0e10cSrcweir return aRef; 190cdf0e10cSrcweir } 191cdf0e10cSrcweir 192cdf0e10cSrcweir void SAL_CALL ScFormulaParserObj::setPropertyValue( 193cdf0e10cSrcweir const rtl::OUString& aPropertyName, const uno::Any& aValue ) 194cdf0e10cSrcweir throw(beans::UnknownPropertyException, beans::PropertyVetoException, 195cdf0e10cSrcweir lang::IllegalArgumentException, lang::WrappedTargetException, 196cdf0e10cSrcweir uno::RuntimeException) 197cdf0e10cSrcweir { 198cdf0e10cSrcweir ScUnoGuard aGuard; 199cdf0e10cSrcweir String aString(aPropertyName); 200cdf0e10cSrcweir if ( aString.EqualsAscii( SC_UNO_COMPILEFAP ) ) 201cdf0e10cSrcweir { 202cdf0e10cSrcweir aValue >>= mbCompileFAP; 203cdf0e10cSrcweir } 204cdf0e10cSrcweir else if ( aString.EqualsAscii( SC_UNO_COMPILEENGLISH ) ) 205cdf0e10cSrcweir { 206cdf0e10cSrcweir bool bOldEnglish = mbEnglish; 207cdf0e10cSrcweir if (aValue >>= mbEnglish) 208cdf0e10cSrcweir { 209cdf0e10cSrcweir // Need to recreate the symbol map to change English property 210cdf0e10cSrcweir // because the map is const. So for performance reasons set 211cdf0e10cSrcweir // CompileEnglish _before_ OpCodeMap! 212cdf0e10cSrcweir if (mxOpCodeMap.get() && mbEnglish != bOldEnglish) 213cdf0e10cSrcweir { 214cdf0e10cSrcweir ScDocument* pDoc = mpDocShell->GetDocument(); 215cdf0e10cSrcweir ScCompiler aCompiler( pDoc, ScAddress()); 216cdf0e10cSrcweir aCompiler.SetGrammar(pDoc->GetGrammar()); 217cdf0e10cSrcweir mxOpCodeMap = aCompiler.CreateOpCodeMap( maOpCodeMapping, mbEnglish); 218cdf0e10cSrcweir } 219cdf0e10cSrcweir } 220cdf0e10cSrcweir else 221cdf0e10cSrcweir throw lang::IllegalArgumentException(); 222cdf0e10cSrcweir } 223cdf0e10cSrcweir else if ( aString.EqualsAscii( SC_UNO_FORMULACONVENTION ) ) 224cdf0e10cSrcweir { 225cdf0e10cSrcweir aValue >>= mnConv; 226cdf0e10cSrcweir } 227cdf0e10cSrcweir else if ( aString.EqualsAscii( SC_UNO_IGNORELEADING ) ) 228cdf0e10cSrcweir { 229cdf0e10cSrcweir aValue >>= mbIgnoreSpaces; 230cdf0e10cSrcweir } 231cdf0e10cSrcweir else if ( aString.EqualsAscii( SC_UNO_OPCODEMAP ) ) 232cdf0e10cSrcweir { 233cdf0e10cSrcweir if (aValue >>= maOpCodeMapping) 234cdf0e10cSrcweir { 235cdf0e10cSrcweir ScDocument* pDoc = mpDocShell->GetDocument(); 236cdf0e10cSrcweir ScCompiler aCompiler( pDoc, ScAddress()); 237cdf0e10cSrcweir aCompiler.SetGrammar(pDoc->GetGrammar()); 238cdf0e10cSrcweir mxOpCodeMap = aCompiler.CreateOpCodeMap( maOpCodeMapping, mbEnglish); 239cdf0e10cSrcweir } 240cdf0e10cSrcweir else 241cdf0e10cSrcweir throw lang::IllegalArgumentException(); 242cdf0e10cSrcweir } 243cdf0e10cSrcweir else if ( aString.EqualsAscii( SC_UNO_EXTERNALLINKS ) ) 244cdf0e10cSrcweir { 245cdf0e10cSrcweir if (!(aValue >>= maExternalLinks)) 246cdf0e10cSrcweir throw lang::IllegalArgumentException(); 247cdf0e10cSrcweir } 248cdf0e10cSrcweir else 249cdf0e10cSrcweir throw beans::UnknownPropertyException(); 250cdf0e10cSrcweir } 251cdf0e10cSrcweir 252cdf0e10cSrcweir uno::Any SAL_CALL ScFormulaParserObj::getPropertyValue( const rtl::OUString& aPropertyName ) 253cdf0e10cSrcweir throw(beans::UnknownPropertyException, lang::WrappedTargetException, 254cdf0e10cSrcweir uno::RuntimeException) 255cdf0e10cSrcweir { 256cdf0e10cSrcweir ScUnoGuard aGuard; 257cdf0e10cSrcweir uno::Any aRet; 258cdf0e10cSrcweir String aString(aPropertyName); 259cdf0e10cSrcweir if ( aString.EqualsAscii( SC_UNO_COMPILEFAP ) ) 260cdf0e10cSrcweir { 261cdf0e10cSrcweir aRet <<= mbCompileFAP; 262cdf0e10cSrcweir } 263cdf0e10cSrcweir else if ( aString.EqualsAscii( SC_UNO_COMPILEENGLISH ) ) 264cdf0e10cSrcweir { 265cdf0e10cSrcweir aRet <<= mbEnglish; 266cdf0e10cSrcweir } 267cdf0e10cSrcweir else if ( aString.EqualsAscii( SC_UNO_FORMULACONVENTION ) ) 268cdf0e10cSrcweir { 269cdf0e10cSrcweir aRet <<= mnConv; 270cdf0e10cSrcweir } 271cdf0e10cSrcweir else if ( aString.EqualsAscii( SC_UNO_IGNORELEADING ) ) 272cdf0e10cSrcweir { 273cdf0e10cSrcweir aRet <<= mbIgnoreSpaces; 274cdf0e10cSrcweir } 275cdf0e10cSrcweir else if ( aString.EqualsAscii( SC_UNO_OPCODEMAP ) ) 276cdf0e10cSrcweir { 277cdf0e10cSrcweir aRet <<= maOpCodeMapping; 278cdf0e10cSrcweir } 279cdf0e10cSrcweir else if ( aString.EqualsAscii( SC_UNO_EXTERNALLINKS ) ) 280cdf0e10cSrcweir { 281cdf0e10cSrcweir aRet <<= maExternalLinks; 282cdf0e10cSrcweir } 283cdf0e10cSrcweir else 284cdf0e10cSrcweir throw beans::UnknownPropertyException(); 285cdf0e10cSrcweir return aRet; 286cdf0e10cSrcweir } 287cdf0e10cSrcweir 288cdf0e10cSrcweir SC_IMPL_DUMMY_PROPERTY_LISTENER( ScFormulaParserObj ) 289cdf0e10cSrcweir 290cdf0e10cSrcweir // ============================================================================ 291cdf0e10cSrcweir 292cdf0e10cSrcweir void lcl_ExternalRefToApi( sheet::SingleReference& rAPI, const ScSingleRefData& rRef ) 293cdf0e10cSrcweir { 294cdf0e10cSrcweir rAPI.Column = rRef.nCol; 295cdf0e10cSrcweir rAPI.Row = rRef.nRow; 296cdf0e10cSrcweir rAPI.Sheet = 0; 297cdf0e10cSrcweir rAPI.RelativeColumn = rRef.nRelCol; 298cdf0e10cSrcweir rAPI.RelativeRow = rRef.nRelRow; 299cdf0e10cSrcweir rAPI.RelativeSheet = 0; 300cdf0e10cSrcweir 301cdf0e10cSrcweir sal_Int32 nFlags = 0; 302cdf0e10cSrcweir if ( rRef.IsColRel() ) nFlags |= sheet::ReferenceFlags::COLUMN_RELATIVE; 303cdf0e10cSrcweir if ( rRef.IsRowRel() ) nFlags |= sheet::ReferenceFlags::ROW_RELATIVE; 304cdf0e10cSrcweir if ( rRef.IsColDeleted() ) nFlags |= sheet::ReferenceFlags::COLUMN_DELETED; 305cdf0e10cSrcweir if ( rRef.IsRowDeleted() ) nFlags |= sheet::ReferenceFlags::ROW_DELETED; 306cdf0e10cSrcweir if ( rRef.IsFlag3D() ) nFlags |= sheet::ReferenceFlags::SHEET_3D; 307cdf0e10cSrcweir if ( rRef.IsRelName() ) nFlags |= sheet::ReferenceFlags::RELATIVE_NAME; 308cdf0e10cSrcweir rAPI.Flags = nFlags; 309cdf0e10cSrcweir } 310cdf0e10cSrcweir 311cdf0e10cSrcweir void lcl_SingleRefToApi( sheet::SingleReference& rAPI, const ScSingleRefData& rRef ) 312cdf0e10cSrcweir { 313cdf0e10cSrcweir rAPI.Column = rRef.nCol; 314cdf0e10cSrcweir rAPI.Row = rRef.nRow; 315cdf0e10cSrcweir rAPI.Sheet = rRef.nTab; 316cdf0e10cSrcweir rAPI.RelativeColumn = rRef.nRelCol; 317cdf0e10cSrcweir rAPI.RelativeRow = rRef.nRelRow; 318cdf0e10cSrcweir rAPI.RelativeSheet = rRef.nRelTab; 319cdf0e10cSrcweir 320cdf0e10cSrcweir sal_Int32 nFlags = 0; 321cdf0e10cSrcweir if ( rRef.IsColRel() ) nFlags |= sheet::ReferenceFlags::COLUMN_RELATIVE; 322cdf0e10cSrcweir if ( rRef.IsRowRel() ) nFlags |= sheet::ReferenceFlags::ROW_RELATIVE; 323cdf0e10cSrcweir if ( rRef.IsTabRel() ) nFlags |= sheet::ReferenceFlags::SHEET_RELATIVE; 324cdf0e10cSrcweir if ( rRef.IsColDeleted() ) nFlags |= sheet::ReferenceFlags::COLUMN_DELETED; 325cdf0e10cSrcweir if ( rRef.IsRowDeleted() ) nFlags |= sheet::ReferenceFlags::ROW_DELETED; 326cdf0e10cSrcweir if ( rRef.IsTabDeleted() ) nFlags |= sheet::ReferenceFlags::SHEET_DELETED; 327cdf0e10cSrcweir if ( rRef.IsFlag3D() ) nFlags |= sheet::ReferenceFlags::SHEET_3D; 328cdf0e10cSrcweir if ( rRef.IsRelName() ) nFlags |= sheet::ReferenceFlags::RELATIVE_NAME; 329cdf0e10cSrcweir rAPI.Flags = nFlags; 330cdf0e10cSrcweir } 331cdf0e10cSrcweir 332cdf0e10cSrcweir // static 333cdf0e10cSrcweir bool ScTokenConversion::ConvertToTokenArray( ScDocument& rDoc, 334cdf0e10cSrcweir ScTokenArray& rTokenArray, const uno::Sequence<sheet::FormulaToken>& rSequence ) 335cdf0e10cSrcweir { 336cdf0e10cSrcweir return !rTokenArray.Fill(rSequence,rDoc.GetExternalRefManager()); 337cdf0e10cSrcweir } 338cdf0e10cSrcweir 339cdf0e10cSrcweir // static 340cdf0e10cSrcweir bool ScTokenConversion::ConvertToTokenSequence( ScDocument& rDoc, 341cdf0e10cSrcweir uno::Sequence<sheet::FormulaToken>& rSequence, const ScTokenArray& rTokenArray ) 342cdf0e10cSrcweir { 343cdf0e10cSrcweir bool bError = false; 344cdf0e10cSrcweir 345cdf0e10cSrcweir sal_Int32 nLen = static_cast<sal_Int32>(rTokenArray.GetLen()); 346cdf0e10cSrcweir formula::FormulaToken** pTokens = rTokenArray.GetArray(); 347cdf0e10cSrcweir if ( pTokens ) 348cdf0e10cSrcweir { 349cdf0e10cSrcweir rSequence.realloc(nLen); 350cdf0e10cSrcweir for (sal_Int32 nPos=0; nPos<nLen; nPos++) 351cdf0e10cSrcweir { 352cdf0e10cSrcweir const formula::FormulaToken& rToken = *pTokens[nPos]; 353cdf0e10cSrcweir sheet::FormulaToken& rAPI = rSequence[nPos]; 354cdf0e10cSrcweir 355cdf0e10cSrcweir OpCode eOpCode = rToken.GetOpCode(); 356cdf0e10cSrcweir // eOpCode may be changed in the following switch/case 357cdf0e10cSrcweir switch ( rToken.GetType() ) 358cdf0e10cSrcweir { 359cdf0e10cSrcweir case svByte: 360cdf0e10cSrcweir // Only the count of spaces is stored as "long". Parameter count is ignored. 361cdf0e10cSrcweir if ( eOpCode == ocSpaces ) 362cdf0e10cSrcweir rAPI.Data <<= (sal_Int32) rToken.GetByte(); 363cdf0e10cSrcweir else 364cdf0e10cSrcweir rAPI.Data.clear(); // no data 365cdf0e10cSrcweir break; 366cdf0e10cSrcweir case formula::svDouble: 367cdf0e10cSrcweir rAPI.Data <<= rToken.GetDouble(); 368cdf0e10cSrcweir break; 369cdf0e10cSrcweir case formula::svString: 370cdf0e10cSrcweir rAPI.Data <<= rtl::OUString( rToken.GetString() ); 371cdf0e10cSrcweir break; 372cdf0e10cSrcweir case svExternal: 373cdf0e10cSrcweir // Function name is stored as string. 374cdf0e10cSrcweir // Byte (parameter count) is ignored. 375cdf0e10cSrcweir rAPI.Data <<= rtl::OUString( rToken.GetExternal() ); 376cdf0e10cSrcweir break; 377cdf0e10cSrcweir case svSingleRef: 378cdf0e10cSrcweir { 379cdf0e10cSrcweir sheet::SingleReference aSingleRef; 380cdf0e10cSrcweir lcl_SingleRefToApi( aSingleRef, static_cast<const ScToken&>(rToken).GetSingleRef() ); 381cdf0e10cSrcweir rAPI.Data <<= aSingleRef; 382cdf0e10cSrcweir } 383cdf0e10cSrcweir break; 384cdf0e10cSrcweir case formula::svDoubleRef: 385cdf0e10cSrcweir { 386cdf0e10cSrcweir sheet::ComplexReference aCompRef; 387cdf0e10cSrcweir lcl_SingleRefToApi( aCompRef.Reference1, static_cast<const ScToken&>(rToken).GetSingleRef() ); 388cdf0e10cSrcweir lcl_SingleRefToApi( aCompRef.Reference2, static_cast<const ScToken&>(rToken).GetSingleRef2() ); 389cdf0e10cSrcweir rAPI.Data <<= aCompRef; 390cdf0e10cSrcweir } 391cdf0e10cSrcweir break; 392cdf0e10cSrcweir case svIndex: 393cdf0e10cSrcweir rAPI.Data <<= static_cast<sal_Int32>( rToken.GetIndex() ); 394cdf0e10cSrcweir break; 395cdf0e10cSrcweir case svMatrix: 396cdf0e10cSrcweir if (!ScRangeToSequence::FillMixedArray( rAPI.Data, static_cast<const ScToken&>(rToken).GetMatrix(), true)) 397cdf0e10cSrcweir rAPI.Data.clear(); 398cdf0e10cSrcweir break; 399cdf0e10cSrcweir case svExternalSingleRef: 400cdf0e10cSrcweir { 401cdf0e10cSrcweir sheet::SingleReference aSingleRef; 402cdf0e10cSrcweir lcl_ExternalRefToApi( aSingleRef, static_cast<const ScToken&>(rToken).GetSingleRef() ); 403cdf0e10cSrcweir size_t nCacheId; 404cdf0e10cSrcweir rDoc.GetExternalRefManager()->getCacheTable( rToken.GetIndex(), rToken.GetString(), false, &nCacheId ); 405cdf0e10cSrcweir aSingleRef.Sheet = static_cast< sal_Int32 >( nCacheId ); 406cdf0e10cSrcweir sheet::ExternalReference aExtRef; 407cdf0e10cSrcweir aExtRef.Index = rToken.GetIndex(); 408cdf0e10cSrcweir aExtRef.Reference <<= aSingleRef; 409cdf0e10cSrcweir rAPI.Data <<= aExtRef; 410cdf0e10cSrcweir eOpCode = ocPush; 411cdf0e10cSrcweir } 412cdf0e10cSrcweir break; 413cdf0e10cSrcweir case svExternalDoubleRef: 414cdf0e10cSrcweir { 415cdf0e10cSrcweir sheet::ComplexReference aComplRef; 416cdf0e10cSrcweir lcl_ExternalRefToApi( aComplRef.Reference1, static_cast<const ScToken&>(rToken).GetSingleRef() ); 417cdf0e10cSrcweir lcl_ExternalRefToApi( aComplRef.Reference2, static_cast<const ScToken&>(rToken).GetSingleRef2() ); 418cdf0e10cSrcweir size_t nCacheId; 419cdf0e10cSrcweir rDoc.GetExternalRefManager()->getCacheTable( rToken.GetIndex(), rToken.GetString(), false, &nCacheId ); 420cdf0e10cSrcweir aComplRef.Reference1.Sheet = static_cast< sal_Int32 >( nCacheId ); 421cdf0e10cSrcweir // NOTE: This assumes that cached sheets are in consecutive order! 422cdf0e10cSrcweir aComplRef.Reference2.Sheet = aComplRef.Reference1.Sheet + (static_cast<const ScToken&>(rToken).GetSingleRef2().nTab - static_cast<const ScToken&>(rToken).GetSingleRef().nTab); 423cdf0e10cSrcweir sheet::ExternalReference aExtRef; 424cdf0e10cSrcweir aExtRef.Index = rToken.GetIndex(); 425cdf0e10cSrcweir aExtRef.Reference <<= aComplRef; 426cdf0e10cSrcweir rAPI.Data <<= aExtRef; 427cdf0e10cSrcweir eOpCode = ocPush; 428cdf0e10cSrcweir } 429cdf0e10cSrcweir break; 430cdf0e10cSrcweir case svExternalName: 431cdf0e10cSrcweir { 432cdf0e10cSrcweir sheet::ExternalReference aExtRef; 433cdf0e10cSrcweir aExtRef.Index = rToken.GetIndex(); 434cdf0e10cSrcweir aExtRef.Reference <<= ::rtl::OUString( rToken.GetString() ); 435cdf0e10cSrcweir rAPI.Data <<= aExtRef; 436cdf0e10cSrcweir eOpCode = ocPush; 437cdf0e10cSrcweir } 438cdf0e10cSrcweir break; 439cdf0e10cSrcweir default: 440cdf0e10cSrcweir DBG_ERROR1( "ScTokenConversion::ConvertToTokenSequence: unhandled token type SvStackVar %d", rToken.GetType()); 441cdf0e10cSrcweir case svSep: // occurs with ocSep, ocOpen, ocClose, ocArray* 442cdf0e10cSrcweir case svJump: // occurs with ocIf, ocChose 443cdf0e10cSrcweir case svMissing: // occurs with ocMissing 444cdf0e10cSrcweir rAPI.Data.clear(); // no data 445cdf0e10cSrcweir } 446cdf0e10cSrcweir rAPI.OpCode = static_cast<sal_Int32>(eOpCode); //! assuming equal values for the moment 447cdf0e10cSrcweir } 448cdf0e10cSrcweir } 449cdf0e10cSrcweir else 450cdf0e10cSrcweir rSequence.realloc(0); 451cdf0e10cSrcweir 452cdf0e10cSrcweir return !bError; 453cdf0e10cSrcweir } 454cdf0e10cSrcweir 455cdf0e10cSrcweir // ============================================================================ 456cdf0e10cSrcweir 457cdf0e10cSrcweir ScFormulaOpCodeMapperObj::ScFormulaOpCodeMapperObj(::std::auto_ptr<formula::FormulaCompiler> _pCompiler) 458cdf0e10cSrcweir : formula::FormulaOpCodeMapperObj(_pCompiler) 459cdf0e10cSrcweir { 460cdf0e10cSrcweir } 461cdf0e10cSrcweir 462cdf0e10cSrcweir // ============================================================================ 463cdf0e10cSrcweir 464