1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef SC_TOKEN_HXX 25 #define SC_TOKEN_HXX 26 27 #include <memory> 28 #include <vector> 29 #include <boost/shared_ptr.hpp> 30 31 #include "formula/opcode.hxx" 32 #include "refdata.hxx" 33 #include "scmatrix.hxx" 34 #include "formula/intruref.hxx" 35 #include <tools/mempool.hxx> 36 #include "scdllapi.h" 37 #include "formula/IFunctionDescription.hxx" 38 #include "formula/token.hxx" 39 40 41 class ScJumpMatrix; 42 class ScToken; 43 44 typedef ::std::vector< ScComplexRefData > ScRefList; 45 typedef formula::SimpleIntrusiveReference< class ScToken > ScTokenRef; 46 47 /** 48 * Another ref-counted token type using shared_ptr. <b>Be extra careful 49 * not to mix use of this smart pointer type with ScTokenRef</b>, since 50 * mixing them might cause a premature object deletion because the same 51 * object may be ref-counted by two different smart pointer wrappers. 52 * 53 * You have been warned. 54 */ 55 typedef ::boost::shared_ptr< ScToken > ScSharedTokenRef; 56 57 class SC_DLLPUBLIC ScToken : public formula::FormulaToken 58 { 59 private: 60 // not implemented, prevent usage 61 ScToken(); 62 ScToken& operator=( const ScToken& ); 63 64 protected: 65 ScToken(formula::StackVar eTypeP,OpCode e=ocPush)66 ScToken( formula::StackVar eTypeP,OpCode e = ocPush ) : formula::FormulaToken(eTypeP,e) {} ScToken(const ScToken & r)67 ScToken( const ScToken& r ): formula::FormulaToken(r) {} 68 69 public: 70 71 virtual ~ScToken(); 72 73 /** 74 Dummy methods to avoid switches and casts where possible, 75 the real token classes have to overload the appropriate method[s]. 76 The only methods valid anytime if not overloaded are: 77 78 - GetByte() since this represents the count of parameters to a function 79 which of course is 0 on non-functions. formula::FormulaByteToken and ScExternal do 80 overload it. 81 82 - HasForceArray() since also this is only used for operators and 83 functions and is 0 for other tokens. 84 85 Any other non-overloaded method pops up an assertion. 86 */ 87 88 virtual const ScSingleRefData& GetSingleRef() const; 89 virtual ScSingleRefData& GetSingleRef(); 90 virtual const ScComplexRefData& GetDoubleRef() const; 91 virtual ScComplexRefData& GetDoubleRef(); 92 virtual const ScSingleRefData& GetSingleRef2() const; 93 virtual ScSingleRefData& GetSingleRef2(); 94 virtual void CalcAbsIfRel( const ScAddress& ); 95 virtual void CalcRelFromAbs( const ScAddress& ); 96 virtual const ScMatrix* GetMatrix() const; 97 virtual ScMatrix* GetMatrix(); 98 virtual ScJumpMatrix* GetJumpMatrix() const; 99 virtual const ScRefList* GetRefList() const; 100 virtual ScRefList* GetRefList(); 101 102 virtual sal_Bool TextEqual( const formula::FormulaToken& rToken ) const; 103 virtual sal_Bool Is3DRef() const; // reference with 3D flag set 104 105 /** If rTok1 and rTok2 both are SingleRef or DoubleRef tokens, extend/merge 106 ranges as needed for ocRange. 107 @param rPos 108 The formula's position, used to calculate absolute positions from 109 relative references. 110 @param bReuseDoubleRef 111 If sal_True, a DoubleRef token is reused if passed as rTok1 or rTok2, 112 else a new DoubleRef token is created and returned. 113 @return 114 A reused or new'ed ScDoubleRefToken, or a NULL TokenRef if rTok1 or 115 rTok2 are not of sv(Single|Double)Ref 116 */ 117 static formula::FormulaTokenRef ExtendRangeReference( formula::FormulaToken & rTok1, formula::FormulaToken & rTok2, const ScAddress & rPos, bool bReuseDoubleRef ); 118 }; 119 120 class ScSingleRefToken : public ScToken 121 { 122 private: 123 ScSingleRefData aSingleRef; 124 public: ScSingleRefToken(const ScSingleRefData & r,OpCode e=ocPush)125 ScSingleRefToken( const ScSingleRefData& r, OpCode e = ocPush ) : 126 ScToken( formula::svSingleRef, e ), aSingleRef( r ) {} ScSingleRefToken(const ScSingleRefToken & r)127 ScSingleRefToken( const ScSingleRefToken& r ) : 128 ScToken( r ), aSingleRef( r.aSingleRef ) {} 129 virtual const ScSingleRefData& GetSingleRef() const; 130 virtual ScSingleRefData& GetSingleRef(); 131 virtual void CalcAbsIfRel( const ScAddress& ); 132 virtual void CalcRelFromAbs( const ScAddress& ); 133 virtual sal_Bool operator==( const formula::FormulaToken& rToken ) const; Clone() const134 virtual FormulaToken* Clone() const { return new ScSingleRefToken(*this); } 135 136 DECL_FIXEDMEMPOOL_NEWDEL( ScSingleRefToken ); 137 }; 138 139 class ScDoubleRefToken : public ScToken 140 { 141 private: 142 ScComplexRefData aDoubleRef; 143 public: ScDoubleRefToken(const ScComplexRefData & r,OpCode e=ocPush)144 ScDoubleRefToken( const ScComplexRefData& r, OpCode e = ocPush ) : 145 ScToken( formula::svDoubleRef, e ), aDoubleRef( r ) {} ScDoubleRefToken(const ScSingleRefData & r,OpCode e=ocPush)146 ScDoubleRefToken( const ScSingleRefData& r, OpCode e = ocPush ) : 147 ScToken( formula::svDoubleRef, e ) 148 { 149 aDoubleRef.Ref1 = r; 150 aDoubleRef.Ref2 = r; 151 } ScDoubleRefToken(const ScDoubleRefToken & r)152 ScDoubleRefToken( const ScDoubleRefToken& r ) : 153 ScToken( r ), aDoubleRef( r.aDoubleRef ) {} 154 virtual const ScSingleRefData& GetSingleRef() const; 155 virtual ScSingleRefData& GetSingleRef(); 156 virtual const ScComplexRefData& GetDoubleRef() const; 157 virtual ScComplexRefData& GetDoubleRef(); 158 virtual const ScSingleRefData& GetSingleRef2() const; 159 virtual ScSingleRefData& GetSingleRef2(); 160 virtual void CalcAbsIfRel( const ScAddress& ); 161 virtual void CalcRelFromAbs( const ScAddress& ); 162 virtual sal_Bool operator==( const formula::FormulaToken& rToken ) const; Clone() const163 virtual FormulaToken* Clone() const { return new ScDoubleRefToken(*this); } 164 165 DECL_FIXEDMEMPOOL_NEWDEL( ScDoubleRefToken ); 166 }; 167 168 class ScMatrixToken : public ScToken 169 { 170 private: 171 ScMatrixRef pMatrix; 172 public: ScMatrixToken(ScMatrix * p)173 ScMatrixToken( ScMatrix* p ) : 174 ScToken( formula::svMatrix ), pMatrix( p ) {} ScMatrixToken(const ScMatrixToken & r)175 ScMatrixToken( const ScMatrixToken& r ) : 176 ScToken( r ), pMatrix( r.pMatrix ) {} 177 virtual const ScMatrix* GetMatrix() const; 178 virtual ScMatrix* GetMatrix(); 179 virtual sal_Bool operator==( const formula::FormulaToken& rToken ) const; Clone() const180 virtual FormulaToken* Clone() const { return new ScMatrixToken(*this); } 181 }; 182 183 184 class ScExternalSingleRefToken : public ScToken 185 { 186 private: 187 sal_uInt16 mnFileId; 188 String maTabName; 189 ScSingleRefData maSingleRef; 190 191 ScExternalSingleRefToken(); // disabled 192 public: 193 ScExternalSingleRefToken( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& r ); 194 ScExternalSingleRefToken( const ScExternalSingleRefToken& r ); 195 virtual ~ScExternalSingleRefToken(); 196 197 virtual sal_uInt16 GetIndex() const; 198 virtual const String& GetString() const; 199 virtual const ScSingleRefData& GetSingleRef() const; 200 virtual ScSingleRefData& GetSingleRef(); 201 virtual void CalcAbsIfRel( const ScAddress& ); 202 virtual void CalcRelFromAbs( const ScAddress& ); 203 virtual sal_Bool operator==( const formula::FormulaToken& rToken ) const; Clone() const204 virtual FormulaToken* Clone() const { return new ScExternalSingleRefToken(*this); } 205 }; 206 207 208 class ScExternalDoubleRefToken : public ScToken 209 { 210 private: 211 sal_uInt16 mnFileId; 212 String maTabName; // name of the first sheet 213 ScComplexRefData maDoubleRef; 214 215 ScExternalDoubleRefToken(); // disabled 216 public: 217 ScExternalDoubleRefToken( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& r ); 218 ScExternalDoubleRefToken( const ScExternalDoubleRefToken& r ); 219 explicit ScExternalDoubleRefToken( const ScExternalSingleRefToken& r ); 220 virtual ~ScExternalDoubleRefToken(); 221 222 virtual sal_uInt16 GetIndex() const; 223 virtual const String& GetString() const; 224 virtual const ScSingleRefData& GetSingleRef() const; 225 virtual ScSingleRefData& GetSingleRef(); 226 virtual const ScSingleRefData& GetSingleRef2() const; 227 virtual ScSingleRefData& GetSingleRef2(); 228 virtual const ScComplexRefData& GetDoubleRef() const; 229 virtual ScComplexRefData& GetDoubleRef(); 230 virtual void CalcAbsIfRel( const ScAddress& ); 231 virtual void CalcRelFromAbs( const ScAddress& ); 232 virtual sal_Bool operator==( const formula::FormulaToken& rToken ) const; Clone() const233 virtual FormulaToken* Clone() const { return new ScExternalDoubleRefToken(*this); } 234 }; 235 236 237 class ScExternalNameToken : public ScToken 238 { 239 private: 240 sal_uInt16 mnFileId; 241 String maName; 242 private: 243 ScExternalNameToken(); // disabled 244 public: 245 ScExternalNameToken( sal_uInt16 nFileId, const String& rName ); 246 ScExternalNameToken( const ScExternalNameToken& r ); 247 virtual ~ScExternalNameToken(); 248 virtual sal_uInt16 GetIndex() const; 249 virtual const String& GetString() const; 250 virtual sal_Bool operator==( const formula::FormulaToken& rToken ) const; Clone() const251 virtual FormulaToken* Clone() const { return new ScExternalNameToken(*this); } 252 }; 253 254 255 // Only created from within the interpreter, no conversion from ScRawToken, 256 // never added to ScTokenArray! 257 class ScJumpMatrixToken : public ScToken 258 { 259 private: 260 ScJumpMatrix* pJumpMatrix; 261 public: ScJumpMatrixToken(ScJumpMatrix * p)262 ScJumpMatrixToken( ScJumpMatrix* p ) : 263 ScToken( formula::svJumpMatrix ), pJumpMatrix( p ) {} ScJumpMatrixToken(const ScJumpMatrixToken & r)264 ScJumpMatrixToken( const ScJumpMatrixToken& r ) : 265 ScToken( r ), pJumpMatrix( r.pJumpMatrix ) {} 266 virtual ~ScJumpMatrixToken(); 267 virtual ScJumpMatrix* GetJumpMatrix() const; 268 virtual sal_Bool operator==( const formula::FormulaToken& rToken ) const; Clone() const269 virtual FormulaToken* Clone() const { return new ScJumpMatrixToken(*this); } 270 }; 271 272 273 // Only created from within the interpreter, no conversion from ScRawToken, 274 // never added to ScTokenArray! 275 class ScRefListToken : public ScToken 276 { 277 private: 278 ScRefList aRefList; 279 public: ScRefListToken()280 ScRefListToken() : 281 ScToken( formula::svRefList ) {} ScRefListToken(const ScRefListToken & r)282 ScRefListToken( const ScRefListToken & r ) : 283 ScToken( r ), aRefList( r.aRefList ) {} 284 virtual void CalcAbsIfRel( const ScAddress& ); 285 virtual void CalcRelFromAbs( const ScAddress& ); 286 virtual const ScRefList* GetRefList() const; 287 virtual ScRefList* GetRefList(); 288 virtual sal_Bool operator==( const formula::FormulaToken& rToken ) const; Clone() const289 virtual FormulaToken* Clone() const { return new ScRefListToken(*this); } 290 }; 291 292 293 class SC_DLLPUBLIC ScEmptyCellToken : public ScToken 294 { 295 bool bInherited :1; 296 bool bDisplayedAsString :1; 297 public: ScEmptyCellToken(bool bInheritedP,bool bDisplayAsString)298 explicit ScEmptyCellToken( bool bInheritedP, bool bDisplayAsString ) : 299 ScToken( formula::svEmptyCell ), 300 bInherited( bInheritedP ), 301 bDisplayedAsString( bDisplayAsString ) {} ScEmptyCellToken(const ScEmptyCellToken & r)302 ScEmptyCellToken( const ScEmptyCellToken& r ) : 303 ScToken( r ), 304 bInherited( r.bInherited ), 305 bDisplayedAsString( r.bDisplayedAsString ) {} IsInherited() const306 bool IsInherited() const { return bInherited; } IsDisplayedAsString() const307 bool IsDisplayedAsString() const { return bDisplayedAsString; } 308 virtual double GetDouble() const; 309 virtual const String & GetString() const; 310 virtual sal_Bool operator==( const formula::FormulaToken& rToken ) const; Clone() const311 virtual FormulaToken* Clone() const { return new ScEmptyCellToken(*this); } 312 }; 313 314 315 /** Transports the result from the interpreter to the formula cell. */ 316 class SC_DLLPUBLIC ScMatrixCellResultToken : public ScToken 317 { 318 // No non-const access implemented, silence down unxsols4 complaining about 319 // the public GetMatrix() hiding the one from ScToken. 320 virtual ScMatrix* GetMatrix(); 321 322 protected: 323 ScConstMatrixRef xMatrix; 324 formula::FormulaConstTokenRef xUpperLeft; 325 public: ScMatrixCellResultToken(ScMatrix * pMat,formula::FormulaToken * pUL)326 ScMatrixCellResultToken( ScMatrix* pMat, formula::FormulaToken* pUL ) : 327 ScToken( formula::svMatrixCell ), 328 xMatrix( pMat), xUpperLeft( pUL) {} ScMatrixCellResultToken(const ScMatrixCellResultToken & r)329 ScMatrixCellResultToken( const ScMatrixCellResultToken& r ) : 330 ScToken( r ), xMatrix( r.xMatrix ), 331 xUpperLeft( r.xUpperLeft ) {} 332 virtual double GetDouble() const; 333 virtual const String & GetString() const; 334 virtual const ScMatrix* GetMatrix() const; 335 virtual sal_Bool operator==( const formula::FormulaToken& rToken ) const; Clone() const336 virtual FormulaToken* Clone() const { return new ScMatrixCellResultToken(*this); } GetUpperLeftType() const337 formula::StackVar GetUpperLeftType() const 338 { 339 return xUpperLeft ? 340 xUpperLeft->GetType() : 341 static_cast<formula::StackVar>(formula::svUnknown); 342 } GetUpperLeftToken() const343 inline formula::FormulaConstTokenRef GetUpperLeftToken() const { return xUpperLeft; } Assign(const ScMatrixCellResultToken & r)344 void Assign( const ScMatrixCellResultToken & r ) 345 { 346 xMatrix = r.xMatrix; 347 xUpperLeft = r.xUpperLeft; 348 } 349 }; 350 351 352 /** Stores the matrix result at the formula cell, additionally the range the 353 matrix formula occupies. */ 354 class SC_DLLPUBLIC ScMatrixFormulaCellToken : public ScMatrixCellResultToken 355 { 356 private: 357 SCROW nRows; 358 SCCOL nCols; 359 public: ScMatrixFormulaCellToken(SCCOL nC,SCROW nR)360 ScMatrixFormulaCellToken( SCCOL nC, SCROW nR ) : 361 ScMatrixCellResultToken( NULL, NULL ), 362 nRows( nR ), nCols( nC ) {} ScMatrixFormulaCellToken(const ScMatrixFormulaCellToken & r)363 ScMatrixFormulaCellToken( const ScMatrixFormulaCellToken& r ) : 364 ScMatrixCellResultToken( r ), 365 nRows( r.nRows ), nCols( r.nCols ) 366 { 367 // xUpperLeft is modifiable through 368 // SetUpperLeftDouble(), so clone it. 369 if (xUpperLeft) 370 xUpperLeft = xUpperLeft->Clone(); 371 } 372 virtual sal_Bool operator==( const formula::FormulaToken& rToken ) const; Clone() const373 virtual FormulaToken* Clone() const { return new ScMatrixFormulaCellToken(*this); } SetMatColsRows(SCCOL nC,SCROW nR)374 void SetMatColsRows( SCCOL nC, SCROW nR ) 375 { 376 nRows = nR; 377 nCols = nC; 378 } GetMatColsRows(SCCOL & nC,SCROW & nR) const379 void GetMatColsRows( SCCOL & nC, SCROW & nR ) const 380 { 381 nR = nRows; 382 nC = nCols; 383 } GetMatCols() const384 SCCOL GetMatCols() const { return nCols; } GetMatRows() const385 SCROW GetMatRows() const { return nRows; } 386 387 /** Assign matrix result, keep matrix formula 388 dimension. */ Assign(const ScMatrixCellResultToken & r)389 void Assign( const ScMatrixCellResultToken & r ) 390 { 391 ScMatrixCellResultToken::Assign( r); 392 } 393 394 /** Assign any result, keep matrix formula 395 dimension. If token is of type 396 ScMatrixCellResultToken uses the 397 appropriate Assign() call, other tokens 398 are assigned to xUpperLeft and xMatrix will 399 be assigned NULL. */ 400 void Assign( const formula::FormulaToken & r ); 401 402 /** Modify xUpperLeft if formula::svDouble, or create 403 new formula::FormulaDoubleToken if not set yet. Does 404 nothing if xUpperLeft is of different type! */ 405 void SetUpperLeftDouble( double f); 406 407 /** Reset matrix and upper left, keep matrix 408 formula dimension. */ ResetResult()409 void ResetResult() 410 { 411 xMatrix = NULL; 412 xUpperLeft = NULL; 413 } 414 }; 415 416 417 class SC_DLLPUBLIC ScHybridCellToken : public ScToken 418 { 419 private: 420 double fDouble; 421 String aString; 422 String aFormula; 423 public: ScHybridCellToken(double f,const String & rStr,const String & rFormula)424 ScHybridCellToken( double f, 425 const String & rStr, 426 const String & rFormula ) : 427 ScToken( formula::svHybridCell ), 428 fDouble( f ), aString( rStr ), 429 aFormula( rFormula ) {} ScHybridCellToken(const ScHybridCellToken & r)430 ScHybridCellToken( const ScHybridCellToken& r ) : 431 ScToken( r ), fDouble( r.fDouble), 432 aString( r.aString), aFormula( r.aFormula) {} GetFormula() const433 const String & GetFormula() const { return aFormula; } 434 virtual double GetDouble() const; 435 virtual const String & GetString() const; 436 virtual sal_Bool operator==( const formula::FormulaToken& rToken ) const; Clone() const437 virtual FormulaToken* Clone() const { return new ScHybridCellToken(*this); } 438 }; 439 440 441 // Simplify argument passing to RefUpdate methods with ScSingleRefToken or 442 // ScDoubleRefToken 443 class SingleDoubleRefModifier 444 { 445 ScComplexRefData aDub; 446 ScSingleRefData* pS; 447 ScComplexRefData* pD; 448 449 // not implemented, prevent usage 450 SingleDoubleRefModifier( const SingleDoubleRefModifier& ); 451 SingleDoubleRefModifier& operator=( const SingleDoubleRefModifier& ); 452 453 public: SingleDoubleRefModifier(ScToken & rT)454 SingleDoubleRefModifier( ScToken& rT ) 455 { 456 if ( rT.GetType() == formula::svSingleRef ) 457 { 458 pS = &rT.GetSingleRef(); 459 aDub.Ref1 = aDub.Ref2 = *pS; 460 pD = &aDub; 461 } 462 else 463 { 464 pS = 0; 465 pD = &rT.GetDoubleRef(); 466 } 467 } SingleDoubleRefModifier(ScSingleRefData & rS)468 SingleDoubleRefModifier( ScSingleRefData& rS ) 469 { 470 pS = &rS; 471 aDub.Ref1 = aDub.Ref2 = *pS; 472 pD = &aDub; 473 } ~SingleDoubleRefModifier()474 ~SingleDoubleRefModifier() 475 { 476 if ( pS ) 477 *pS = (*pD).Ref1; 478 } Ref()479 inline ScComplexRefData& Ref() { return *pD; } 480 }; 481 482 class SingleDoubleRefProvider 483 { 484 public: 485 486 const ScSingleRefData& Ref1; 487 const ScSingleRefData& Ref2; 488 SingleDoubleRefProvider(const ScToken & r)489 SingleDoubleRefProvider( const ScToken& r ) 490 : Ref1( r.GetSingleRef() ), 491 Ref2( r.GetType() == formula::svDoubleRef ? 492 r.GetDoubleRef().Ref2 : Ref1 ) 493 {} SingleDoubleRefProvider(const ScSingleRefData & r)494 SingleDoubleRefProvider( const ScSingleRefData& r ) 495 : Ref1( r ), Ref2( r ) 496 {} SingleDoubleRefProvider(const ScComplexRefData & r)497 SingleDoubleRefProvider( const ScComplexRefData& r ) 498 : Ref1( r.Ref1 ), Ref2( r.Ref2 ) 499 {} ~SingleDoubleRefProvider()500 ~SingleDoubleRefProvider() 501 {} 502 }; 503 504 #endif 505