sync master with lastest vba changes
[ooovba.git] / sc / inc / token.hxx
blobab6a83c2cd35979d3f01ebda7c1ccfef3525f168
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: token.hxx,v $
10 * $Revision: 1.15.32.3 $
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 #ifndef SC_TOKEN_HXX
32 #define SC_TOKEN_HXX
34 #include <memory>
35 #include <vector>
36 #include <boost/shared_ptr.hpp>
38 #include "formula/opcode.hxx"
39 #include "refdata.hxx"
40 #include "scmatrix.hxx"
41 #include "formula/intruref.hxx"
42 #include <tools/mempool.hxx>
43 #include "scdllapi.h"
44 #include "formula/IFunctionDescription.hxx"
45 #include "formula/token.hxx"
48 class ScJumpMatrix;
49 class ScToken;
51 typedef ::std::vector< ScComplexRefData > ScRefList;
52 typedef formula::SimpleIntrusiveReference< class ScToken > ScTokenRef;
54 /**
55 * Another ref-counted token type using shared_ptr. <b>Be extra careful
56 * not to mix use of this smart pointer type with ScTokenRef</b>, since
57 * mixing them might cause a premature object deletion because the same
58 * object may be ref-counted by two different smart pointer wrappers.
60 * You have been warned.
62 typedef ::boost::shared_ptr< ScToken > ScSharedTokenRef;
64 class SC_DLLPUBLIC ScToken : public formula::FormulaToken
66 private:
67 // not implemented, prevent usage
68 ScToken();
69 ScToken& operator=( const ScToken& );
71 protected:
73 ScToken( formula::StackVar eTypeP,OpCode e = ocPush ) : formula::FormulaToken(eTypeP,e) {}
74 ScToken( const ScToken& r ): formula::FormulaToken(r) {}
76 public:
78 virtual ~ScToken();
80 /**
81 Dummy methods to avoid switches and casts where possible,
82 the real token classes have to overload the appropriate method[s].
83 The only methods valid anytime if not overloaded are:
85 - GetByte() since this represents the count of parameters to a function
86 which of course is 0 on non-functions. formula::FormulaByteToken and ScExternal do
87 overload it.
89 - HasForceArray() since also this is only used for operators and
90 functions and is 0 for other tokens.
92 Any other non-overloaded method pops up an assertion.
95 virtual const ScSingleRefData& GetSingleRef() const;
96 virtual ScSingleRefData& GetSingleRef();
97 virtual const ScComplexRefData& GetDoubleRef() const;
98 virtual ScComplexRefData& GetDoubleRef();
99 virtual const ScSingleRefData& GetSingleRef2() const;
100 virtual ScSingleRefData& GetSingleRef2();
101 virtual void CalcAbsIfRel( const ScAddress& );
102 virtual void CalcRelFromAbs( const ScAddress& );
103 virtual const ScMatrix* GetMatrix() const;
104 virtual ScMatrix* GetMatrix();
105 virtual ScJumpMatrix* GetJumpMatrix() const;
106 virtual const ScRefList* GetRefList() const;
107 virtual ScRefList* GetRefList();
109 virtual BOOL TextEqual( const formula::FormulaToken& rToken ) const;
110 virtual BOOL Is3DRef() const; // reference with 3D flag set
112 /** If rTok1 and rTok2 both are SingleRef or DoubleRef tokens, extend/merge
113 ranges as needed for ocRange.
114 @param rPos
115 The formula's position, used to calculate absolute positions from
116 relative references.
117 @param bReuseDoubleRef
118 If TRUE, a DoubleRef token is reused if passed as rTok1 or rTok2,
119 else a new DoubleRef token is created and returned.
120 @return
121 A reused or new'ed ScDoubleRefToken, or a NULL TokenRef if rTok1 or
122 rTok2 are not of sv(Single|Double)Ref
124 static formula::FormulaTokenRef ExtendRangeReference( formula::FormulaToken & rTok1, formula::FormulaToken & rTok2, const ScAddress & rPos, bool bReuseDoubleRef );
127 class ScSingleRefToken : public ScToken
129 private:
130 ScSingleRefData aSingleRef;
131 public:
132 ScSingleRefToken( const ScSingleRefData& r, OpCode e = ocPush ) :
133 ScToken( formula::svSingleRef, e ), aSingleRef( r ) {}
134 ScSingleRefToken( const ScSingleRefToken& r ) :
135 ScToken( r ), aSingleRef( r.aSingleRef ) {}
136 virtual const ScSingleRefData& GetSingleRef() const;
137 virtual ScSingleRefData& GetSingleRef();
138 virtual void CalcAbsIfRel( const ScAddress& );
139 virtual void CalcRelFromAbs( const ScAddress& );
140 virtual BOOL operator==( const formula::FormulaToken& rToken ) const;
141 virtual FormulaToken* Clone() const { return new ScSingleRefToken(*this); }
143 DECL_FIXEDMEMPOOL_NEWDEL( ScSingleRefToken );
146 class ScDoubleRefToken : public ScToken
148 private:
149 ScComplexRefData aDoubleRef;
150 public:
151 ScDoubleRefToken( const ScComplexRefData& r, OpCode e = ocPush ) :
152 ScToken( formula::svDoubleRef, e ), aDoubleRef( r ) {}
153 ScDoubleRefToken( const ScSingleRefData& r, OpCode e = ocPush ) :
154 ScToken( formula::svDoubleRef, e )
156 aDoubleRef.Ref1 = r;
157 aDoubleRef.Ref2 = r;
159 ScDoubleRefToken( const ScDoubleRefToken& r ) :
160 ScToken( r ), aDoubleRef( r.aDoubleRef ) {}
161 virtual const ScSingleRefData& GetSingleRef() const;
162 virtual ScSingleRefData& GetSingleRef();
163 virtual const ScComplexRefData& GetDoubleRef() const;
164 virtual ScComplexRefData& GetDoubleRef();
165 virtual const ScSingleRefData& GetSingleRef2() const;
166 virtual ScSingleRefData& GetSingleRef2();
167 virtual void CalcAbsIfRel( const ScAddress& );
168 virtual void CalcRelFromAbs( const ScAddress& );
169 virtual BOOL operator==( const formula::FormulaToken& rToken ) const;
170 virtual FormulaToken* Clone() const { return new ScDoubleRefToken(*this); }
172 DECL_FIXEDMEMPOOL_NEWDEL( ScDoubleRefToken );
175 class ScMatrixToken : public ScToken
177 private:
178 ScMatrixRef pMatrix;
179 public:
180 ScMatrixToken( ScMatrix* p ) :
181 ScToken( formula::svMatrix ), pMatrix( p ) {}
182 ScMatrixToken( const ScMatrixToken& r ) :
183 ScToken( r ), pMatrix( r.pMatrix ) {}
184 virtual const ScMatrix* GetMatrix() const;
185 virtual ScMatrix* GetMatrix();
186 virtual BOOL operator==( const formula::FormulaToken& rToken ) const;
187 virtual FormulaToken* Clone() const { return new ScMatrixToken(*this); }
191 class ScExternalSingleRefToken : public ScToken
193 private:
194 sal_uInt16 mnFileId;
195 String maTabName;
196 ScSingleRefData maSingleRef;
198 ScExternalSingleRefToken(); // disabled
199 public:
200 ScExternalSingleRefToken( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& r );
201 ScExternalSingleRefToken( const ScExternalSingleRefToken& r );
202 virtual ~ScExternalSingleRefToken();
204 virtual USHORT GetIndex() const;
205 virtual const String& GetString() const;
206 virtual const ScSingleRefData& GetSingleRef() const;
207 virtual ScSingleRefData& GetSingleRef();
208 virtual void CalcAbsIfRel( const ScAddress& );
209 virtual void CalcRelFromAbs( const ScAddress& );
210 virtual BOOL operator==( const formula::FormulaToken& rToken ) const;
211 virtual FormulaToken* Clone() const { return new ScExternalSingleRefToken(*this); }
215 class ScExternalDoubleRefToken : public ScToken
217 private:
218 sal_uInt16 mnFileId;
219 String maTabName; // name of the first sheet
220 ScComplexRefData maDoubleRef;
222 ScExternalDoubleRefToken(); // disabled
223 public:
224 ScExternalDoubleRefToken( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& r );
225 ScExternalDoubleRefToken( const ScExternalDoubleRefToken& r );
226 virtual ~ScExternalDoubleRefToken();
228 virtual USHORT GetIndex() const;
229 virtual const String& GetString() const;
230 virtual const ScSingleRefData& GetSingleRef() const;
231 virtual ScSingleRefData& GetSingleRef();
232 virtual const ScSingleRefData& GetSingleRef2() const;
233 virtual ScSingleRefData& GetSingleRef2();
234 virtual const ScComplexRefData& GetDoubleRef() const;
235 virtual ScComplexRefData& GetDoubleRef();
236 virtual void CalcAbsIfRel( const ScAddress& );
237 virtual void CalcRelFromAbs( const ScAddress& );
238 virtual BOOL operator==( const formula::FormulaToken& rToken ) const;
239 virtual FormulaToken* Clone() const { return new ScExternalDoubleRefToken(*this); }
243 class ScExternalNameToken : public ScToken
245 private:
246 sal_uInt16 mnFileId;
247 String maName;
248 private:
249 ScExternalNameToken(); // disabled
250 public:
251 ScExternalNameToken( sal_uInt16 nFileId, const String& rName );
252 ScExternalNameToken( const ScExternalNameToken& r );
253 virtual ~ScExternalNameToken();
254 virtual USHORT GetIndex() const;
255 virtual const String& GetString() const;
256 virtual BOOL operator==( const formula::FormulaToken& rToken ) const;
257 virtual FormulaToken* Clone() const { return new ScExternalNameToken(*this); }
261 // Only created from within the interpreter, no conversion from ScRawToken,
262 // never added to ScTokenArray!
263 class ScJumpMatrixToken : public ScToken
265 private:
266 ScJumpMatrix* pJumpMatrix;
267 public:
268 ScJumpMatrixToken( ScJumpMatrix* p ) :
269 ScToken( formula::svJumpMatrix ), pJumpMatrix( p ) {}
270 ScJumpMatrixToken( const ScJumpMatrixToken& r ) :
271 ScToken( r ), pJumpMatrix( r.pJumpMatrix ) {}
272 virtual ~ScJumpMatrixToken();
273 virtual ScJumpMatrix* GetJumpMatrix() const;
274 virtual BOOL operator==( const formula::FormulaToken& rToken ) const;
275 virtual FormulaToken* Clone() const { return new ScJumpMatrixToken(*this); }
279 // Only created from within the interpreter, no conversion from ScRawToken,
280 // never added to ScTokenArray!
281 class ScRefListToken : public ScToken
283 private:
284 ScRefList aRefList;
285 public:
286 ScRefListToken() :
287 ScToken( formula::svRefList ) {}
288 ScRefListToken( const ScRefListToken & r ) :
289 ScToken( r ), aRefList( r.aRefList ) {}
290 virtual void CalcAbsIfRel( const ScAddress& );
291 virtual void CalcRelFromAbs( const ScAddress& );
292 virtual const ScRefList* GetRefList() const;
293 virtual ScRefList* GetRefList();
294 virtual BOOL operator==( const formula::FormulaToken& rToken ) const;
295 virtual FormulaToken* Clone() const { return new ScRefListToken(*this); }
299 class SC_DLLPUBLIC ScEmptyCellToken : public ScToken
301 bool bInherited :1;
302 bool bDisplayedAsString :1;
303 public:
304 explicit ScEmptyCellToken( bool bInheritedP, bool bDisplayAsString ) :
305 ScToken( formula::svEmptyCell ),
306 bInherited( bInheritedP ),
307 bDisplayedAsString( bDisplayAsString ) {}
308 ScEmptyCellToken( const ScEmptyCellToken& r ) :
309 ScToken( r ),
310 bInherited( r.bInherited ),
311 bDisplayedAsString( r.bDisplayedAsString ) {}
312 bool IsInherited() const { return bInherited; }
313 bool IsDisplayedAsString() const { return bDisplayedAsString; }
314 virtual double GetDouble() const;
315 virtual const String & GetString() const;
316 virtual BOOL operator==( const formula::FormulaToken& rToken ) const;
317 virtual FormulaToken* Clone() const { return new ScEmptyCellToken(*this); }
321 /** Transports the result from the interpreter to the formula cell. */
322 class SC_DLLPUBLIC ScMatrixCellResultToken : public ScToken
324 // No non-const access implemented, silence down unxsols4 complaining about
325 // the public GetMatrix() hiding the one from ScToken.
326 virtual ScMatrix* GetMatrix();
328 protected:
329 ScConstMatrixRef xMatrix;
330 formula::FormulaConstTokenRef xUpperLeft;
331 public:
332 ScMatrixCellResultToken( ScMatrix* pMat, formula::FormulaToken* pUL ) :
333 ScToken( formula::svMatrixCell ),
334 xMatrix( pMat), xUpperLeft( pUL) {}
335 ScMatrixCellResultToken( const ScMatrixCellResultToken& r ) :
336 ScToken( r ), xMatrix( r.xMatrix ),
337 xUpperLeft( r.xUpperLeft ) {}
338 virtual double GetDouble() const;
339 virtual const String & GetString() const;
340 virtual const ScMatrix* GetMatrix() const;
341 virtual BOOL operator==( const formula::FormulaToken& rToken ) const;
342 virtual FormulaToken* Clone() const { return new ScMatrixCellResultToken(*this); }
343 formula::StackVar GetUpperLeftType() const
345 return xUpperLeft ?
346 xUpperLeft->GetType() :
347 static_cast<formula::StackVar>(formula::svUnknown);
349 inline formula::FormulaConstTokenRef GetUpperLeftToken() const { return xUpperLeft; }
350 void Assign( const ScMatrixCellResultToken & r )
352 xMatrix = r.xMatrix;
353 xUpperLeft = r.xUpperLeft;
358 /** Stores the matrix result at the formula cell, additionally the range the
359 matrix formula occupies. */
360 class SC_DLLPUBLIC ScMatrixFormulaCellToken : public ScMatrixCellResultToken
362 private:
363 SCROW nRows;
364 SCCOL nCols;
365 public:
366 ScMatrixFormulaCellToken( SCCOL nC, SCROW nR ) :
367 ScMatrixCellResultToken( NULL, NULL ),
368 nRows( nR ), nCols( nC ) {}
369 ScMatrixFormulaCellToken( const ScMatrixFormulaCellToken& r ) :
370 ScMatrixCellResultToken( r ),
371 nRows( r.nRows ), nCols( r.nCols )
373 // xUpperLeft is modifiable through
374 // SetUpperLeftDouble(), so clone it.
375 if (xUpperLeft)
376 xUpperLeft = xUpperLeft->Clone();
378 virtual BOOL operator==( const formula::FormulaToken& rToken ) const;
379 virtual FormulaToken* Clone() const { return new ScMatrixFormulaCellToken(*this); }
380 void SetMatColsRows( SCCOL nC, SCROW nR )
382 nRows = nR;
383 nCols = nC;
385 void GetMatColsRows( SCCOL & nC, SCROW & nR ) const
387 nR = nRows;
388 nC = nCols;
390 SCCOL GetMatCols() const { return nCols; }
391 SCROW GetMatRows() const { return nRows; }
393 /** Assign matrix result, keep matrix formula
394 dimension. */
395 void Assign( const ScMatrixCellResultToken & r )
397 ScMatrixCellResultToken::Assign( r);
400 /** Assign any result, keep matrix formula
401 dimension. If token is of type
402 ScMatrixCellResultToken uses the
403 appropriate Assign() call, other tokens
404 are assigned to xUpperLeft and xMatrix will
405 be assigned NULL. */
406 void Assign( const formula::FormulaToken & r );
408 /** Modify xUpperLeft if formula::svDouble, or create
409 new formula::FormulaDoubleToken if not set yet. Does
410 nothing if xUpperLeft is of different type! */
411 void SetUpperLeftDouble( double f);
413 /** Reset matrix and upper left, keep matrix
414 formula dimension. */
415 void ResetResult()
417 xMatrix = NULL;
418 xUpperLeft = NULL;
423 class SC_DLLPUBLIC ScHybridCellToken : public ScToken
425 private:
426 double fDouble;
427 String aString;
428 String aFormula;
429 public:
430 ScHybridCellToken( double f,
431 const String & rStr,
432 const String & rFormula ) :
433 ScToken( formula::svHybridCell ),
434 fDouble( f ), aString( rStr ),
435 aFormula( rFormula ) {}
436 ScHybridCellToken( const ScHybridCellToken& r ) :
437 ScToken( r ), fDouble( r.fDouble),
438 aString( r.aString), aFormula( r.aFormula) {}
439 const String & GetFormula() const { return aFormula; }
440 virtual double GetDouble() const;
441 virtual const String & GetString() const;
442 virtual BOOL operator==( const formula::FormulaToken& rToken ) const;
443 virtual FormulaToken* Clone() const { return new ScHybridCellToken(*this); }
447 // Simplify argument passing to RefUpdate methods with ScSingleRefToken or
448 // ScDoubleRefToken
449 class SingleDoubleRefModifier
451 ScComplexRefData aDub;
452 ScSingleRefData* pS;
453 ScComplexRefData* pD;
455 // not implemented, prevent usage
456 SingleDoubleRefModifier( const SingleDoubleRefModifier& );
457 SingleDoubleRefModifier& operator=( const SingleDoubleRefModifier& );
459 public:
460 SingleDoubleRefModifier( ScToken& rT )
462 if ( rT.GetType() == formula::svSingleRef )
464 pS = &rT.GetSingleRef();
465 aDub.Ref1 = aDub.Ref2 = *pS;
466 pD = &aDub;
468 else
470 pS = 0;
471 pD = &rT.GetDoubleRef();
474 SingleDoubleRefModifier( ScSingleRefData& rS )
476 pS = &rS;
477 aDub.Ref1 = aDub.Ref2 = *pS;
478 pD = &aDub;
480 ~SingleDoubleRefModifier()
482 if ( pS )
483 *pS = (*pD).Ref1;
485 inline ScComplexRefData& Ref() { return *pD; }
488 class SingleDoubleRefProvider
490 public:
492 const ScSingleRefData& Ref1;
493 const ScSingleRefData& Ref2;
495 SingleDoubleRefProvider( const ScToken& r )
496 : Ref1( r.GetSingleRef() ),
497 Ref2( r.GetType() == formula::svDoubleRef ?
498 r.GetDoubleRef().Ref2 : Ref1 )
500 SingleDoubleRefProvider( const ScSingleRefData& r )
501 : Ref1( r ), Ref2( r )
503 SingleDoubleRefProvider( const ScComplexRefData& r )
504 : Ref1( r.Ref1 ), Ref2( r.Ref2 )
506 ~SingleDoubleRefProvider()
510 #endif