1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir #ifndef SC_FORMULARESULT_HXX 29*cdf0e10cSrcweir #define SC_FORMULARESULT_HXX 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include "token.hxx" 32*cdf0e10cSrcweir 33*cdf0e10cSrcweir 34*cdf0e10cSrcweir /** Store a variable formula cell result, balancing between runtime performance 35*cdf0e10cSrcweir and memory consumption. */ 36*cdf0e10cSrcweir class ScFormulaResult 37*cdf0e10cSrcweir { 38*cdf0e10cSrcweir typedef unsigned char Multiline; 39*cdf0e10cSrcweir static const Multiline MULTILINE_UNKNOWN = 0; 40*cdf0e10cSrcweir static const Multiline MULTILINE_FALSE = 1; 41*cdf0e10cSrcweir static const Multiline MULTILINE_TRUE = 2; 42*cdf0e10cSrcweir 43*cdf0e10cSrcweir union 44*cdf0e10cSrcweir { 45*cdf0e10cSrcweir double mfValue; // double result direct for performance and memory consumption 46*cdf0e10cSrcweir const formula::FormulaToken* mpToken; // if not, result token obtained from interpreter 47*cdf0e10cSrcweir }; 48*cdf0e10cSrcweir sal_uInt16 mnError; // error code 49*cdf0e10cSrcweir bool mbToken :1; // whether content of union is a token 50*cdf0e10cSrcweir bool mbEmpty :1; // empty cell result 51*cdf0e10cSrcweir bool mbEmptyDisplayedAsString :1; // only if mbEmpty 52*cdf0e10cSrcweir Multiline meMultiline :2; // result is multiline 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir /** Reset mnError, mbEmpty and mbEmptyDisplayedAsString to their defaults 55*cdf0e10cSrcweir prior to assigning other types */ 56*cdf0e10cSrcweir inline void ResetToDefaults(); 57*cdf0e10cSrcweir 58*cdf0e10cSrcweir /** If token is of formula::svError set error code and decrement RefCount. 59*cdf0e10cSrcweir If token is of formula::svEmptyCell set mbEmpty and mbEmptyAsString and 60*cdf0e10cSrcweir decrement RefCount. 61*cdf0e10cSrcweir If token is of formula::svDouble set mfValue and decrement RefCount. 62*cdf0e10cSrcweir Else assign token to mpToken. NULL is valid => svUnknown. 63*cdf0e10cSrcweir Other member variables are set accordingly. 64*cdf0e10cSrcweir @precondition: Token MUST had been IncRef'ed prior to this call! 65*cdf0e10cSrcweir @precondition: An already existing different mpToken MUST had been 66*cdf0e10cSrcweir DecRef'ed prior to this call, p will be assigned to mpToken if not 67*cdf0e10cSrcweir resolved. 68*cdf0e10cSrcweir ATTENTION! Token may get deleted in this call! */ 69*cdf0e10cSrcweir inline void ResolveToken( const formula::FormulaToken * p ); 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir public: 72*cdf0e10cSrcweir /** Effectively type svUnknown. */ 73*cdf0e10cSrcweir ScFormulaResult() 74*cdf0e10cSrcweir : mpToken(NULL), mnError(0), mbToken(true), 75*cdf0e10cSrcweir mbEmpty(false), mbEmptyDisplayedAsString(false), 76*cdf0e10cSrcweir meMultiline(MULTILINE_UNKNOWN) {} 77*cdf0e10cSrcweir 78*cdf0e10cSrcweir ScFormulaResult( const ScFormulaResult & r ) 79*cdf0e10cSrcweir : mnError( r.mnError), mbToken( r.mbToken), 80*cdf0e10cSrcweir mbEmpty( r.mbEmpty), 81*cdf0e10cSrcweir mbEmptyDisplayedAsString( r.mbEmptyDisplayedAsString), 82*cdf0e10cSrcweir meMultiline( r.meMultiline) 83*cdf0e10cSrcweir { 84*cdf0e10cSrcweir if (mbToken) 85*cdf0e10cSrcweir { 86*cdf0e10cSrcweir mpToken = r.mpToken; 87*cdf0e10cSrcweir if (mpToken) 88*cdf0e10cSrcweir { 89*cdf0e10cSrcweir // Since matrix dimension and 90*cdf0e10cSrcweir // results are assigned to a matrix 91*cdf0e10cSrcweir // cell formula token we have to 92*cdf0e10cSrcweir // clone that instead of sharing it. 93*cdf0e10cSrcweir const ScMatrixFormulaCellToken* pMatFormula = 94*cdf0e10cSrcweir r.GetMatrixFormulaCellToken(); 95*cdf0e10cSrcweir if (pMatFormula) 96*cdf0e10cSrcweir mpToken = new ScMatrixFormulaCellToken( *pMatFormula); 97*cdf0e10cSrcweir mpToken->IncRef(); 98*cdf0e10cSrcweir } 99*cdf0e10cSrcweir } 100*cdf0e10cSrcweir else 101*cdf0e10cSrcweir mfValue = r.mfValue; 102*cdf0e10cSrcweir } 103*cdf0e10cSrcweir 104*cdf0e10cSrcweir /** Same comments as for SetToken() apply! */ 105*cdf0e10cSrcweir explicit ScFormulaResult( const formula::FormulaToken* p ) 106*cdf0e10cSrcweir : mnError(0), mbToken(false), 107*cdf0e10cSrcweir mbEmpty(false), mbEmptyDisplayedAsString(false), 108*cdf0e10cSrcweir meMultiline(MULTILINE_UNKNOWN) 109*cdf0e10cSrcweir { 110*cdf0e10cSrcweir SetToken( p); 111*cdf0e10cSrcweir } 112*cdf0e10cSrcweir 113*cdf0e10cSrcweir ~ScFormulaResult() 114*cdf0e10cSrcweir { 115*cdf0e10cSrcweir if (mbToken && mpToken) 116*cdf0e10cSrcweir mpToken->DecRef(); 117*cdf0e10cSrcweir } 118*cdf0e10cSrcweir 119*cdf0e10cSrcweir /** Well, guess what ... */ 120*cdf0e10cSrcweir inline ScFormulaResult & operator=( const ScFormulaResult & r ); 121*cdf0e10cSrcweir 122*cdf0e10cSrcweir /** Assignment as in operator=() but without return */ 123*cdf0e10cSrcweir inline void Assign( const ScFormulaResult & r ); 124*cdf0e10cSrcweir 125*cdf0e10cSrcweir /** Sets a direct double if token type is formula::svDouble, or mbEmpty if 126*cdf0e10cSrcweir formula::svEmptyCell, else token. If p is NULL, that is set as well, effectively 127*cdf0e10cSrcweir resulting in GetType()==svUnknown. If the already existing result is 128*cdf0e10cSrcweir ScMatrixFormulaCellToken, the upper left ist set to token. 129*cdf0e10cSrcweir 130*cdf0e10cSrcweir ATTENTION! formula::FormulaToken had to be allocated using 'new' and if of type 131*cdf0e10cSrcweir formula::svDouble and no RefCount was set may not be used after this call 132*cdf0e10cSrcweir because it was deleted after decrement! */ 133*cdf0e10cSrcweir inline void SetToken( const formula::FormulaToken* p ); 134*cdf0e10cSrcweir 135*cdf0e10cSrcweir /** May be NULL if SetToken() did so, also if type formula::svDouble or formula::svError! */ 136*cdf0e10cSrcweir inline formula::FormulaConstTokenRef GetToken() const; 137*cdf0e10cSrcweir 138*cdf0e10cSrcweir /** Return upper left token if formula::svMatrixCell, else return GetToken(). 139*cdf0e10cSrcweir May be NULL if SetToken() did so, also if type formula::svDouble or formula::svError! */ 140*cdf0e10cSrcweir inline formula::FormulaConstTokenRef GetCellResultToken() const; 141*cdf0e10cSrcweir 142*cdf0e10cSrcweir /** Return type of result, including formula::svError, formula::svEmptyCell, formula::svDouble and 143*cdf0e10cSrcweir formula::svMatrixCell. */ 144*cdf0e10cSrcweir inline formula::StackVar GetType() const; 145*cdf0e10cSrcweir 146*cdf0e10cSrcweir /** If type is formula::svMatrixCell return the type of upper left element, else 147*cdf0e10cSrcweir GetType() */ 148*cdf0e10cSrcweir inline formula::StackVar GetCellResultType() const; 149*cdf0e10cSrcweir 150*cdf0e10cSrcweir /** If type is formula::svEmptyCell (including matrix upper left) and should be 151*cdf0e10cSrcweir displayed as empty string */ 152*cdf0e10cSrcweir inline bool IsEmptyDisplayedAsString() const; 153*cdf0e10cSrcweir 154*cdf0e10cSrcweir /** Test for cell result type formula::svDouble, including upper left if 155*cdf0e10cSrcweir formula::svMatrixCell. Also included is formula::svError for legacy, because previously 156*cdf0e10cSrcweir an error result was treated like a numeric value at some places in 157*cdf0e10cSrcweir ScFormulaCell. Also included is formula::svEmptyCell as a reference to an empty 158*cdf0e10cSrcweir cell usually is treated as numeric 0. Use GetCellResultType() for 159*cdf0e10cSrcweir details instead. */ 160*cdf0e10cSrcweir inline bool IsValue() const; 161*cdf0e10cSrcweir 162*cdf0e10cSrcweir /** Determines whether or not the result is a string containing more than 163*cdf0e10cSrcweir one paragraph */ 164*cdf0e10cSrcweir inline bool IsMultiline() const; 165*cdf0e10cSrcweir 166*cdf0e10cSrcweir /** Get error code if set or GetCellResultType() is formula::svError or svUnknown, 167*cdf0e10cSrcweir else 0. */ 168*cdf0e10cSrcweir inline sal_uInt16 GetResultError() const; 169*cdf0e10cSrcweir 170*cdf0e10cSrcweir /** Set error code, don't touch token or double. */ 171*cdf0e10cSrcweir inline void SetResultError( sal_uInt16 nErr ); 172*cdf0e10cSrcweir 173*cdf0e10cSrcweir /** Set direct double. Shouldn't be used externally except in 174*cdf0e10cSrcweir ScFormulaCell for rounded CalcAsShown or SetErrCode(). If 175*cdf0e10cSrcweir ScMatrixFormulaCellToken the token isn't replaced but upper left result 176*cdf0e10cSrcweir is modified instead, but only if it was of type formula::svDouble before or not 177*cdf0e10cSrcweir set at all. */ 178*cdf0e10cSrcweir inline void SetDouble( double f ); 179*cdf0e10cSrcweir 180*cdf0e10cSrcweir /** Return value if type formula::svDouble or formula::svHybridCell or formula::svMatrixCell and upper 181*cdf0e10cSrcweir left formula::svDouble, else 0.0 */ 182*cdf0e10cSrcweir inline double GetDouble() const; 183*cdf0e10cSrcweir 184*cdf0e10cSrcweir /** Return string if type formula::svString or formula::svHybridCell or formula::svMatrixCell and 185*cdf0e10cSrcweir upper left formula::svString, else empty string. */ 186*cdf0e10cSrcweir inline const String & GetString() const; 187*cdf0e10cSrcweir 188*cdf0e10cSrcweir /** Return matrix if type formula::svMatrixCell and ScMatrix present, else NULL. */ 189*cdf0e10cSrcweir inline ScConstMatrixRef GetMatrix() const; 190*cdf0e10cSrcweir 191*cdf0e10cSrcweir /** Return formula string if type formula::svHybridCell, else empty string. */ 192*cdf0e10cSrcweir inline const String & GetHybridFormula() const; 193*cdf0e10cSrcweir 194*cdf0e10cSrcweir /** Should only be used by import filters, best in the order 195*cdf0e10cSrcweir SetHybridDouble(), SetHybridString(), or only SetHybridString() for 196*cdf0e10cSrcweir formula string to be compiled later. */ 197*cdf0e10cSrcweir inline void SetHybridDouble( double f ); 198*cdf0e10cSrcweir 199*cdf0e10cSrcweir /** Should only be used by import filters, best in the order 200*cdf0e10cSrcweir SetHybridDouble(), SetHybridString()/SetHybridFormula(), or only 201*cdf0e10cSrcweir SetHybridFormula() for formula string to be compiled later. */ 202*cdf0e10cSrcweir inline void SetHybridString( const String & rStr ); 203*cdf0e10cSrcweir 204*cdf0e10cSrcweir /** Should only be used by import filters, best in the order 205*cdf0e10cSrcweir SetHybridDouble(), SetHybridString()/SetHybridFormula(), or only 206*cdf0e10cSrcweir SetHybridFormula() for formula string to be compiled later. */ 207*cdf0e10cSrcweir inline void SetHybridFormula( const String & rFormula ); 208*cdf0e10cSrcweir 209*cdf0e10cSrcweir /** Get the const ScMatrixFormulaCellToken* if token is of that type, else 210*cdf0e10cSrcweir NULL. */ 211*cdf0e10cSrcweir inline const ScMatrixFormulaCellToken* GetMatrixFormulaCellToken() const; 212*cdf0e10cSrcweir 213*cdf0e10cSrcweir /** Get the ScMatrixFormulaCellToken* if token is of that type, else NULL. 214*cdf0e10cSrcweir Shouldn't be used externally except by ScFormulaCell::SetMatColsRows(). */ 215*cdf0e10cSrcweir inline ScMatrixFormulaCellToken* GetMatrixFormulaCellTokenNonConst(); 216*cdf0e10cSrcweir }; 217*cdf0e10cSrcweir 218*cdf0e10cSrcweir 219*cdf0e10cSrcweir inline void ScFormulaResult::ResetToDefaults() 220*cdf0e10cSrcweir { 221*cdf0e10cSrcweir mnError = 0; 222*cdf0e10cSrcweir mbEmpty = false; 223*cdf0e10cSrcweir mbEmptyDisplayedAsString = false; 224*cdf0e10cSrcweir meMultiline = MULTILINE_UNKNOWN; 225*cdf0e10cSrcweir } 226*cdf0e10cSrcweir 227*cdf0e10cSrcweir 228*cdf0e10cSrcweir inline void ScFormulaResult::ResolveToken( const formula::FormulaToken * p ) 229*cdf0e10cSrcweir { 230*cdf0e10cSrcweir ResetToDefaults(); 231*cdf0e10cSrcweir if (!p) 232*cdf0e10cSrcweir { 233*cdf0e10cSrcweir mpToken = p; 234*cdf0e10cSrcweir mbToken = true; 235*cdf0e10cSrcweir } 236*cdf0e10cSrcweir else 237*cdf0e10cSrcweir { 238*cdf0e10cSrcweir switch (p->GetType()) 239*cdf0e10cSrcweir { 240*cdf0e10cSrcweir case formula::svError: 241*cdf0e10cSrcweir mnError = p->GetError(); 242*cdf0e10cSrcweir p->DecRef(); 243*cdf0e10cSrcweir mbToken = false; 244*cdf0e10cSrcweir // set in case mnError is 0 now, which shouldn't happen but ... 245*cdf0e10cSrcweir mfValue = 0.0; 246*cdf0e10cSrcweir meMultiline = MULTILINE_FALSE; 247*cdf0e10cSrcweir break; 248*cdf0e10cSrcweir case formula::svEmptyCell: 249*cdf0e10cSrcweir mbEmpty = true; 250*cdf0e10cSrcweir mbEmptyDisplayedAsString = static_cast<const ScEmptyCellToken*>(p)->IsDisplayedAsString(); 251*cdf0e10cSrcweir p->DecRef(); 252*cdf0e10cSrcweir mbToken = false; 253*cdf0e10cSrcweir meMultiline = MULTILINE_FALSE; 254*cdf0e10cSrcweir break; 255*cdf0e10cSrcweir case formula::svDouble: 256*cdf0e10cSrcweir mfValue = p->GetDouble(); 257*cdf0e10cSrcweir p->DecRef(); 258*cdf0e10cSrcweir mbToken = false; 259*cdf0e10cSrcweir meMultiline = MULTILINE_FALSE; 260*cdf0e10cSrcweir break; 261*cdf0e10cSrcweir default: 262*cdf0e10cSrcweir mpToken = p; 263*cdf0e10cSrcweir mbToken = true; 264*cdf0e10cSrcweir } 265*cdf0e10cSrcweir } 266*cdf0e10cSrcweir } 267*cdf0e10cSrcweir 268*cdf0e10cSrcweir 269*cdf0e10cSrcweir inline ScFormulaResult & ScFormulaResult::operator=( const ScFormulaResult & r ) 270*cdf0e10cSrcweir { 271*cdf0e10cSrcweir Assign( r); 272*cdf0e10cSrcweir return *this; 273*cdf0e10cSrcweir } 274*cdf0e10cSrcweir 275*cdf0e10cSrcweir 276*cdf0e10cSrcweir inline void ScFormulaResult::Assign( const ScFormulaResult & r ) 277*cdf0e10cSrcweir { 278*cdf0e10cSrcweir if (this == &r) 279*cdf0e10cSrcweir return; 280*cdf0e10cSrcweir if (r.mbEmpty) 281*cdf0e10cSrcweir { 282*cdf0e10cSrcweir if (mbToken && mpToken) 283*cdf0e10cSrcweir mpToken->DecRef(); 284*cdf0e10cSrcweir mbToken = false; 285*cdf0e10cSrcweir mbEmpty = true; 286*cdf0e10cSrcweir mbEmptyDisplayedAsString = r.mbEmptyDisplayedAsString; 287*cdf0e10cSrcweir meMultiline = r.meMultiline; 288*cdf0e10cSrcweir } 289*cdf0e10cSrcweir else if (r.mbToken) 290*cdf0e10cSrcweir { 291*cdf0e10cSrcweir // Matrix formula cell token must be cloned, see copy-ctor. 292*cdf0e10cSrcweir const ScMatrixFormulaCellToken* pMatFormula = 293*cdf0e10cSrcweir r.GetMatrixFormulaCellToken(); 294*cdf0e10cSrcweir if (pMatFormula) 295*cdf0e10cSrcweir SetToken( new ScMatrixFormulaCellToken( *pMatFormula)); 296*cdf0e10cSrcweir else 297*cdf0e10cSrcweir SetToken( r.mpToken); 298*cdf0e10cSrcweir } 299*cdf0e10cSrcweir else 300*cdf0e10cSrcweir SetDouble( r.mfValue); 301*cdf0e10cSrcweir // If there was an error there will be an error, no matter what Set...() 302*cdf0e10cSrcweir // methods did. 303*cdf0e10cSrcweir mnError = r.mnError; 304*cdf0e10cSrcweir } 305*cdf0e10cSrcweir 306*cdf0e10cSrcweir 307*cdf0e10cSrcweir inline void ScFormulaResult::SetToken( const formula::FormulaToken* p ) 308*cdf0e10cSrcweir { 309*cdf0e10cSrcweir ResetToDefaults(); 310*cdf0e10cSrcweir if (p) 311*cdf0e10cSrcweir p->IncRef(); 312*cdf0e10cSrcweir // Handle a result obtained from the interpreter to be assigned to a matrix 313*cdf0e10cSrcweir // formula cell's ScMatrixFormulaCellToken. 314*cdf0e10cSrcweir ScMatrixFormulaCellToken* pMatFormula = GetMatrixFormulaCellTokenNonConst(); 315*cdf0e10cSrcweir if (pMatFormula) 316*cdf0e10cSrcweir { 317*cdf0e10cSrcweir const ScMatrixCellResultToken* pMatResult = 318*cdf0e10cSrcweir (p && p->GetType() == formula::svMatrixCell ? 319*cdf0e10cSrcweir dynamic_cast<const ScMatrixCellResultToken*>(p) : NULL); 320*cdf0e10cSrcweir if (pMatResult) 321*cdf0e10cSrcweir { 322*cdf0e10cSrcweir const ScMatrixFormulaCellToken* pNewMatFormula = 323*cdf0e10cSrcweir dynamic_cast<const ScMatrixFormulaCellToken*>(pMatResult); 324*cdf0e10cSrcweir if (pNewMatFormula) 325*cdf0e10cSrcweir { 326*cdf0e10cSrcweir DBG_ERRORFILE( "ScFormulaResult::SetToken: pNewMatFormula and pMatFormula, overriding matrix formula dimension; intended?"); 327*cdf0e10cSrcweir pMatFormula->SetMatColsRows( pNewMatFormula->GetMatCols(), 328*cdf0e10cSrcweir pNewMatFormula->GetMatRows()); 329*cdf0e10cSrcweir } 330*cdf0e10cSrcweir pMatFormula->Assign( *pMatResult); 331*cdf0e10cSrcweir p->DecRef(); 332*cdf0e10cSrcweir } 333*cdf0e10cSrcweir else if (p) 334*cdf0e10cSrcweir { 335*cdf0e10cSrcweir // This may be the result of some constant expression like 336*cdf0e10cSrcweir // {="string"} that doesn't result in a matrix but still would 337*cdf0e10cSrcweir // display the result in all cells of this matrix formula. 338*cdf0e10cSrcweir pMatFormula->Assign( *p); 339*cdf0e10cSrcweir p->DecRef(); 340*cdf0e10cSrcweir } 341*cdf0e10cSrcweir else 342*cdf0e10cSrcweir { 343*cdf0e10cSrcweir // NULL result? Well, if you say so ... 344*cdf0e10cSrcweir pMatFormula->ResetResult(); 345*cdf0e10cSrcweir } 346*cdf0e10cSrcweir } 347*cdf0e10cSrcweir else 348*cdf0e10cSrcweir { 349*cdf0e10cSrcweir if (mbToken && mpToken) 350*cdf0e10cSrcweir mpToken->DecRef(); 351*cdf0e10cSrcweir ResolveToken( p); 352*cdf0e10cSrcweir } 353*cdf0e10cSrcweir } 354*cdf0e10cSrcweir 355*cdf0e10cSrcweir 356*cdf0e10cSrcweir inline void ScFormulaResult::SetDouble( double f ) 357*cdf0e10cSrcweir { 358*cdf0e10cSrcweir ResetToDefaults(); 359*cdf0e10cSrcweir // Handle a result obtained from the interpreter to be assigned to a matrix 360*cdf0e10cSrcweir // formula cell's ScMatrixFormulaCellToken. 361*cdf0e10cSrcweir ScMatrixFormulaCellToken* pMatFormula = GetMatrixFormulaCellTokenNonConst(); 362*cdf0e10cSrcweir if (pMatFormula) 363*cdf0e10cSrcweir pMatFormula->SetUpperLeftDouble( f); 364*cdf0e10cSrcweir else 365*cdf0e10cSrcweir { 366*cdf0e10cSrcweir if (mbToken && mpToken) 367*cdf0e10cSrcweir mpToken->DecRef(); 368*cdf0e10cSrcweir mfValue = f; 369*cdf0e10cSrcweir mbToken = false; 370*cdf0e10cSrcweir meMultiline = MULTILINE_FALSE; 371*cdf0e10cSrcweir } 372*cdf0e10cSrcweir } 373*cdf0e10cSrcweir 374*cdf0e10cSrcweir 375*cdf0e10cSrcweir inline formula::StackVar ScFormulaResult::GetType() const 376*cdf0e10cSrcweir { 377*cdf0e10cSrcweir // Order is significant. 378*cdf0e10cSrcweir if (mnError) 379*cdf0e10cSrcweir return formula::svError; 380*cdf0e10cSrcweir if (mbEmpty) 381*cdf0e10cSrcweir return formula::svEmptyCell; 382*cdf0e10cSrcweir if (!mbToken) 383*cdf0e10cSrcweir return formula::svDouble; 384*cdf0e10cSrcweir if (mpToken) 385*cdf0e10cSrcweir return mpToken->GetType(); 386*cdf0e10cSrcweir return formula::svUnknown; 387*cdf0e10cSrcweir } 388*cdf0e10cSrcweir 389*cdf0e10cSrcweir 390*cdf0e10cSrcweir inline formula::StackVar ScFormulaResult::GetCellResultType() const 391*cdf0e10cSrcweir { 392*cdf0e10cSrcweir formula::StackVar sv = GetType(); 393*cdf0e10cSrcweir if (sv == formula::svMatrixCell) 394*cdf0e10cSrcweir // don't need to test for mpToken here, GetType() already did it 395*cdf0e10cSrcweir sv = static_cast<const ScMatrixCellResultToken*>(mpToken)->GetUpperLeftType(); 396*cdf0e10cSrcweir return sv; 397*cdf0e10cSrcweir } 398*cdf0e10cSrcweir 399*cdf0e10cSrcweir 400*cdf0e10cSrcweir inline bool ScFormulaResult::IsEmptyDisplayedAsString() const 401*cdf0e10cSrcweir { 402*cdf0e10cSrcweir if (mbEmpty) 403*cdf0e10cSrcweir return mbEmptyDisplayedAsString; 404*cdf0e10cSrcweir if (GetType() == formula::svMatrixCell) 405*cdf0e10cSrcweir { 406*cdf0e10cSrcweir // don't need to test for mpToken here, GetType() already did it 407*cdf0e10cSrcweir const ScEmptyCellToken* p = dynamic_cast<const ScEmptyCellToken*>( 408*cdf0e10cSrcweir static_cast<const ScMatrixCellResultToken*>( 409*cdf0e10cSrcweir mpToken)->GetUpperLeftToken().operator->()); 410*cdf0e10cSrcweir if (p) 411*cdf0e10cSrcweir return p->IsDisplayedAsString(); 412*cdf0e10cSrcweir } 413*cdf0e10cSrcweir return false; 414*cdf0e10cSrcweir } 415*cdf0e10cSrcweir 416*cdf0e10cSrcweir 417*cdf0e10cSrcweir inline bool ScFormulaResult::IsValue() const 418*cdf0e10cSrcweir { 419*cdf0e10cSrcweir formula::StackVar sv = GetCellResultType(); 420*cdf0e10cSrcweir return sv == formula::svDouble || sv == formula::svError || sv == formula::svEmptyCell; 421*cdf0e10cSrcweir } 422*cdf0e10cSrcweir 423*cdf0e10cSrcweir inline bool ScFormulaResult::IsMultiline() const 424*cdf0e10cSrcweir { 425*cdf0e10cSrcweir if (meMultiline == MULTILINE_UNKNOWN) 426*cdf0e10cSrcweir { 427*cdf0e10cSrcweir const String& rStr = GetString(); 428*cdf0e10cSrcweir if (rStr.Len() && rStr.Search( _LF ) != STRING_NOTFOUND) 429*cdf0e10cSrcweir const_cast<ScFormulaResult*>(this)->meMultiline = MULTILINE_TRUE; 430*cdf0e10cSrcweir else 431*cdf0e10cSrcweir const_cast<ScFormulaResult*>(this)->meMultiline = MULTILINE_FALSE; 432*cdf0e10cSrcweir } 433*cdf0e10cSrcweir return meMultiline == MULTILINE_TRUE; 434*cdf0e10cSrcweir } 435*cdf0e10cSrcweir 436*cdf0e10cSrcweir 437*cdf0e10cSrcweir inline sal_uInt16 ScFormulaResult::GetResultError() const 438*cdf0e10cSrcweir { 439*cdf0e10cSrcweir if (mnError) 440*cdf0e10cSrcweir return mnError; 441*cdf0e10cSrcweir formula::StackVar sv = GetCellResultType(); 442*cdf0e10cSrcweir if (sv == formula::svError) 443*cdf0e10cSrcweir { 444*cdf0e10cSrcweir if (GetType() == formula::svMatrixCell) 445*cdf0e10cSrcweir // don't need to test for mpToken here, GetType() already did it 446*cdf0e10cSrcweir return static_cast<const ScMatrixCellResultToken*>(mpToken)-> 447*cdf0e10cSrcweir GetUpperLeftToken()->GetError(); 448*cdf0e10cSrcweir if (mpToken) 449*cdf0e10cSrcweir return mpToken->GetError(); 450*cdf0e10cSrcweir } 451*cdf0e10cSrcweir return 0; 452*cdf0e10cSrcweir } 453*cdf0e10cSrcweir 454*cdf0e10cSrcweir 455*cdf0e10cSrcweir inline void ScFormulaResult::SetResultError( sal_uInt16 nErr ) 456*cdf0e10cSrcweir { 457*cdf0e10cSrcweir mnError = nErr; 458*cdf0e10cSrcweir } 459*cdf0e10cSrcweir 460*cdf0e10cSrcweir 461*cdf0e10cSrcweir inline formula::FormulaConstTokenRef ScFormulaResult::GetToken() const 462*cdf0e10cSrcweir { 463*cdf0e10cSrcweir if (mbToken) 464*cdf0e10cSrcweir return mpToken; 465*cdf0e10cSrcweir return NULL; 466*cdf0e10cSrcweir } 467*cdf0e10cSrcweir 468*cdf0e10cSrcweir 469*cdf0e10cSrcweir inline formula::FormulaConstTokenRef ScFormulaResult::GetCellResultToken() const 470*cdf0e10cSrcweir { 471*cdf0e10cSrcweir if (GetType() == formula::svMatrixCell) 472*cdf0e10cSrcweir // don't need to test for mpToken here, GetType() already did it 473*cdf0e10cSrcweir return static_cast<const ScMatrixCellResultToken*>(mpToken)->GetUpperLeftToken(); 474*cdf0e10cSrcweir return GetToken(); 475*cdf0e10cSrcweir } 476*cdf0e10cSrcweir 477*cdf0e10cSrcweir 478*cdf0e10cSrcweir inline double ScFormulaResult::GetDouble() const 479*cdf0e10cSrcweir { 480*cdf0e10cSrcweir if (mbToken) 481*cdf0e10cSrcweir { 482*cdf0e10cSrcweir // Should really not be of type formula::svDouble here. 483*cdf0e10cSrcweir if (mpToken) 484*cdf0e10cSrcweir { 485*cdf0e10cSrcweir switch (mpToken->GetType()) 486*cdf0e10cSrcweir { 487*cdf0e10cSrcweir case formula::svHybridCell: 488*cdf0e10cSrcweir return mpToken->GetDouble(); 489*cdf0e10cSrcweir case formula::svMatrixCell: 490*cdf0e10cSrcweir { 491*cdf0e10cSrcweir const ScMatrixCellResultToken* p = 492*cdf0e10cSrcweir static_cast<const ScMatrixCellResultToken*>(mpToken); 493*cdf0e10cSrcweir if (p->GetUpperLeftType() == formula::svDouble) 494*cdf0e10cSrcweir return p->GetUpperLeftToken()->GetDouble(); 495*cdf0e10cSrcweir } 496*cdf0e10cSrcweir break; 497*cdf0e10cSrcweir default: 498*cdf0e10cSrcweir ; // nothing 499*cdf0e10cSrcweir } 500*cdf0e10cSrcweir } 501*cdf0e10cSrcweir return 0.0; 502*cdf0e10cSrcweir } 503*cdf0e10cSrcweir if (mbEmpty) 504*cdf0e10cSrcweir return 0.0; 505*cdf0e10cSrcweir return mfValue; 506*cdf0e10cSrcweir } 507*cdf0e10cSrcweir 508*cdf0e10cSrcweir 509*cdf0e10cSrcweir inline const String & ScFormulaResult::GetString() const 510*cdf0e10cSrcweir { 511*cdf0e10cSrcweir if (mbToken && mpToken) 512*cdf0e10cSrcweir { 513*cdf0e10cSrcweir switch (mpToken->GetType()) 514*cdf0e10cSrcweir { 515*cdf0e10cSrcweir case formula::svString: 516*cdf0e10cSrcweir case formula::svHybridCell: 517*cdf0e10cSrcweir return mpToken->GetString(); 518*cdf0e10cSrcweir case formula::svMatrixCell: 519*cdf0e10cSrcweir { 520*cdf0e10cSrcweir const ScMatrixCellResultToken* p = 521*cdf0e10cSrcweir static_cast<const ScMatrixCellResultToken*>(mpToken); 522*cdf0e10cSrcweir if (p->GetUpperLeftType() == formula::svString) 523*cdf0e10cSrcweir return p->GetUpperLeftToken()->GetString(); 524*cdf0e10cSrcweir } 525*cdf0e10cSrcweir break; 526*cdf0e10cSrcweir default: 527*cdf0e10cSrcweir ; // nothing 528*cdf0e10cSrcweir } 529*cdf0e10cSrcweir } 530*cdf0e10cSrcweir return EMPTY_STRING; 531*cdf0e10cSrcweir } 532*cdf0e10cSrcweir 533*cdf0e10cSrcweir 534*cdf0e10cSrcweir inline ScConstMatrixRef ScFormulaResult::GetMatrix() const 535*cdf0e10cSrcweir { 536*cdf0e10cSrcweir if (GetType() == formula::svMatrixCell) 537*cdf0e10cSrcweir return static_cast<const ScToken*>(mpToken)->GetMatrix(); 538*cdf0e10cSrcweir return NULL; 539*cdf0e10cSrcweir } 540*cdf0e10cSrcweir 541*cdf0e10cSrcweir 542*cdf0e10cSrcweir inline const String & ScFormulaResult::GetHybridFormula() const 543*cdf0e10cSrcweir { 544*cdf0e10cSrcweir if (GetType() == formula::svHybridCell) 545*cdf0e10cSrcweir { 546*cdf0e10cSrcweir const ScHybridCellToken* p = dynamic_cast<const ScHybridCellToken*>(mpToken); 547*cdf0e10cSrcweir if (p) 548*cdf0e10cSrcweir return p->GetFormula(); 549*cdf0e10cSrcweir } 550*cdf0e10cSrcweir return EMPTY_STRING; 551*cdf0e10cSrcweir } 552*cdf0e10cSrcweir 553*cdf0e10cSrcweir 554*cdf0e10cSrcweir inline void ScFormulaResult::SetHybridDouble( double f ) 555*cdf0e10cSrcweir { 556*cdf0e10cSrcweir ResetToDefaults(); 557*cdf0e10cSrcweir if (mbToken && mpToken) 558*cdf0e10cSrcweir { 559*cdf0e10cSrcweir String aString( GetString()); 560*cdf0e10cSrcweir String aFormula( GetHybridFormula()); 561*cdf0e10cSrcweir mpToken->DecRef(); 562*cdf0e10cSrcweir mpToken = new ScHybridCellToken( f, aString, aFormula); 563*cdf0e10cSrcweir mpToken->IncRef(); 564*cdf0e10cSrcweir } 565*cdf0e10cSrcweir else 566*cdf0e10cSrcweir { 567*cdf0e10cSrcweir mfValue = f; 568*cdf0e10cSrcweir mbToken = false; 569*cdf0e10cSrcweir meMultiline = MULTILINE_FALSE; 570*cdf0e10cSrcweir } 571*cdf0e10cSrcweir } 572*cdf0e10cSrcweir 573*cdf0e10cSrcweir 574*cdf0e10cSrcweir inline void ScFormulaResult::SetHybridString( const String & rStr ) 575*cdf0e10cSrcweir { 576*cdf0e10cSrcweir // Obtain values before changing anything. 577*cdf0e10cSrcweir double f = GetDouble(); 578*cdf0e10cSrcweir String aFormula( GetHybridFormula()); 579*cdf0e10cSrcweir ResetToDefaults(); 580*cdf0e10cSrcweir if (mbToken && mpToken) 581*cdf0e10cSrcweir mpToken->DecRef(); 582*cdf0e10cSrcweir mpToken = new ScHybridCellToken( f, rStr, aFormula); 583*cdf0e10cSrcweir mpToken->IncRef(); 584*cdf0e10cSrcweir mbToken = true; 585*cdf0e10cSrcweir } 586*cdf0e10cSrcweir 587*cdf0e10cSrcweir 588*cdf0e10cSrcweir inline void ScFormulaResult::SetHybridFormula( const String & rFormula ) 589*cdf0e10cSrcweir { 590*cdf0e10cSrcweir // Obtain values before changing anything. 591*cdf0e10cSrcweir double f = GetDouble(); 592*cdf0e10cSrcweir String aStr( GetString()); 593*cdf0e10cSrcweir ResetToDefaults(); 594*cdf0e10cSrcweir if (mbToken && mpToken) 595*cdf0e10cSrcweir mpToken->DecRef(); 596*cdf0e10cSrcweir mpToken = new ScHybridCellToken( f, aStr, rFormula); 597*cdf0e10cSrcweir mpToken->IncRef(); 598*cdf0e10cSrcweir mbToken = true; 599*cdf0e10cSrcweir } 600*cdf0e10cSrcweir 601*cdf0e10cSrcweir 602*cdf0e10cSrcweir inline const ScMatrixFormulaCellToken* ScFormulaResult::GetMatrixFormulaCellToken() const 603*cdf0e10cSrcweir { 604*cdf0e10cSrcweir return (GetType() == formula::svMatrixCell ? 605*cdf0e10cSrcweir dynamic_cast<const ScMatrixFormulaCellToken*>(mpToken) : NULL); 606*cdf0e10cSrcweir } 607*cdf0e10cSrcweir 608*cdf0e10cSrcweir 609*cdf0e10cSrcweir inline ScMatrixFormulaCellToken* ScFormulaResult::GetMatrixFormulaCellTokenNonConst() 610*cdf0e10cSrcweir { 611*cdf0e10cSrcweir return const_cast<ScMatrixFormulaCellToken*>( GetMatrixFormulaCellToken()); 612*cdf0e10cSrcweir } 613*cdf0e10cSrcweir 614*cdf0e10cSrcweir 615*cdf0e10cSrcweir #endif // SC_FORMULARESULT_HXX 616