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: 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 ************************************************************************/
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>
44 #include "formula/IFunctionDescription.hxx"
45 #include "formula/token.hxx"
51 typedef ::std::vector
< ScComplexRefData
> ScRefList
;
52 typedef formula::SimpleIntrusiveReference
< class ScToken
> ScTokenRef
;
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
67 // not implemented, prevent usage
69 ScToken
& operator=( const ScToken
& );
73 ScToken( formula::StackVar eTypeP
,OpCode e
= ocPush
) : formula::FormulaToken(eTypeP
,e
) {}
74 ScToken( const ScToken
& r
): formula::FormulaToken(r
) {}
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
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.
115 The formula's position, used to calculate absolute positions from
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.
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
130 ScSingleRefData aSingleRef
;
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
149 ScComplexRefData aDoubleRef
;
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
)
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
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
196 ScSingleRefData maSingleRef
;
198 ScExternalSingleRefToken(); // disabled
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
219 String maTabName
; // name of the first sheet
220 ScComplexRefData maDoubleRef
;
222 ScExternalDoubleRefToken(); // disabled
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
249 ScExternalNameToken(); // disabled
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
266 ScJumpMatrix
* pJumpMatrix
;
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
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
302 bool bDisplayedAsString
:1;
304 explicit ScEmptyCellToken( bool bInheritedP
, bool bDisplayAsString
) :
305 ScToken( formula::svEmptyCell
),
306 bInherited( bInheritedP
),
307 bDisplayedAsString( bDisplayAsString
) {}
308 ScEmptyCellToken( const ScEmptyCellToken
& 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();
329 ScConstMatrixRef xMatrix
;
330 formula::FormulaConstTokenRef xUpperLeft
;
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
346 xUpperLeft
->GetType() :
347 static_cast<formula::StackVar
>(formula::svUnknown
);
349 inline formula::FormulaConstTokenRef
GetUpperLeftToken() const { return xUpperLeft
; }
350 void Assign( const ScMatrixCellResultToken
& r
)
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
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.
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
)
385 void GetMatColsRows( SCCOL
& nC
, SCROW
& nR
) const
390 SCCOL
GetMatCols() const { return nCols
; }
391 SCROW
GetMatRows() const { return nRows
; }
393 /** Assign matrix result, keep matrix formula
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
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. */
423 class SC_DLLPUBLIC ScHybridCellToken
: public ScToken
430 ScHybridCellToken( double f
,
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
449 class SingleDoubleRefModifier
451 ScComplexRefData aDub
;
453 ScComplexRefData
* pD
;
455 // not implemented, prevent usage
456 SingleDoubleRefModifier( const SingleDoubleRefModifier
& );
457 SingleDoubleRefModifier
& operator=( const SingleDoubleRefModifier
& );
460 SingleDoubleRefModifier( ScToken
& rT
)
462 if ( rT
.GetType() == formula::svSingleRef
)
464 pS
= &rT
.GetSingleRef();
465 aDub
.Ref1
= aDub
.Ref2
= *pS
;
471 pD
= &rT
.GetDoubleRef();
474 SingleDoubleRefModifier( ScSingleRefData
& rS
)
477 aDub
.Ref1
= aDub
.Ref2
= *pS
;
480 ~SingleDoubleRefModifier()
485 inline ScComplexRefData
& Ref() { return *pD
; }
488 class SingleDoubleRefProvider
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()