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