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
10*b3f79822SAndrew Rist *
11*b3f79822SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*b3f79822SAndrew Rist *
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.
19*b3f79822SAndrew Rist *
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
lcl_GetFormulaParserMap()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
ScFormulaParserObj(ScDocShell * pDocSh)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
~ScFormulaParserObj()81cdf0e10cSrcweir ScFormulaParserObj::~ScFormulaParserObj()
82cdf0e10cSrcweir {
83cdf0e10cSrcweir if (mpDocShell)
84cdf0e10cSrcweir mpDocShell->GetDocument()->RemoveUnoObject(*this);
85cdf0e10cSrcweir }
86cdf0e10cSrcweir
Notify(SfxBroadcaster &,const SfxHint & rHint)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
SetCompilerFlags(ScCompiler & rCompiler) const95cdf0e10cSrcweir 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
parseFormula(const rtl::OUString & aFormula,const table::CellAddress & rReferencePos)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
printFormula(const uno::Sequence<sheet::FormulaToken> & aTokens,const table::CellAddress & rReferencePos)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
getPropertySetInfo()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
setPropertyValue(const rtl::OUString & aPropertyName,const uno::Any & aValue)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
getPropertyValue(const rtl::OUString & aPropertyName)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
SC_IMPL_DUMMY_PROPERTY_LISTENER(ScFormulaParserObj)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
lcl_SingleRefToApi(sheet::SingleReference & rAPI,const ScSingleRefData & rRef)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
ConvertToTokenArray(ScDocument & rDoc,ScTokenArray & rTokenArray,const uno::Sequence<sheet::FormulaToken> & rSequence)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
ConvertToTokenSequence(ScDocument & rDoc,uno::Sequence<sheet::FormulaToken> & rSequence,const ScTokenArray & rTokenArray)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
ScFormulaOpCodeMapperObj(::std::auto_ptr<formula::FormulaCompiler> _pCompiler)457cdf0e10cSrcweir ScFormulaOpCodeMapperObj::ScFormulaOpCodeMapperObj(::std::auto_ptr<formula::FormulaCompiler> _pCompiler)
458cdf0e10cSrcweir : formula::FormulaOpCodeMapperObj(_pCompiler)
459cdf0e10cSrcweir {
460cdf0e10cSrcweir }
461cdf0e10cSrcweir
462cdf0e10cSrcweir // ============================================================================
463cdf0e10cSrcweir
464