Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #ifndef SC_FORMULARESULT_HXX
30 : : #define SC_FORMULARESULT_HXX
31 : :
32 : : #include "token.hxx"
33 : : #include "scdllapi.h"
34 : :
35 : : #include <sal/log.hxx>
36 : :
37 : : /** Store a variable formula cell result, balancing between runtime performance
38 : : and memory consumption. */
39 : : class ScFormulaResult
40 : : {
41 : : typedef unsigned char Multiline;
42 : : static const Multiline MULTILINE_UNKNOWN = 0;
43 : : static const Multiline MULTILINE_FALSE = 1;
44 : : static const Multiline MULTILINE_TRUE = 2;
45 : :
46 : : // Clone token if the 16-bit only reference counter is nearing it's
47 : : // capacity during fill or copy&paste, leaving 4k for temporary passing
48 : : // around. (That should be enough for all times (TM) ;-)
49 : : static const sal_uInt16 MAX_TOKENREF_COUNT = 0xf000;
50 : 3574 : static void IncrementTokenRef( const formula::FormulaToken* & rp )
51 : : {
52 [ + + ]: 3574 : if (rp)
53 : : {
54 [ - + ]: 3011 : if (rp->GetRef() >= MAX_TOKENREF_COUNT)
55 : 0 : rp = rp->Clone();
56 : 3011 : rp->IncRef();
57 : : }
58 : 3574 : }
59 : :
60 : : union
61 : : {
62 : : double mfValue; // double result direct for performance and memory consumption
63 : : const formula::FormulaToken* mpToken; // if not, result token obtained from interpreter
64 : : };
65 : : sal_uInt16 mnError; // error code
66 : : bool mbToken :1; // whether content of union is a token
67 : : bool mbEmpty :1; // empty cell result
68 : : bool mbEmptyDisplayedAsString :1; // only if mbEmpty
69 : : Multiline meMultiline :2; // result is multiline
70 : :
71 : : /** Reset mnError, mbEmpty and mbEmptyDisplayedAsString to their defaults
72 : : prior to assigning other types */
73 : : void ResetToDefaults();
74 : :
75 : : /** If token is of formula::svError set error code and decrement RefCount.
76 : : If token is of formula::svEmptyCell set mbEmpty and mbEmptyAsString and
77 : : decrement RefCount.
78 : : If token is of formula::svDouble set mfValue and decrement RefCount.
79 : : Else assign token to mpToken. NULL is valid => svUnknown.
80 : : Other member variables are set accordingly.
81 : : @precondition: Token MUST had been IncRef'ed prior to this call!
82 : : @precondition: An already existing different mpToken MUST had been
83 : : DecRef'ed prior to this call, p will be assigned to mpToken if not
84 : : resolved.
85 : : ATTENTION! Token may get deleted in this call! */
86 : : void ResolveToken( const formula::FormulaToken * p );
87 : :
88 : : public:
89 : : /** Effectively type svUnknown. */
90 : : ScFormulaResult();
91 : :
92 : : ScFormulaResult( const ScFormulaResult & r );
93 : :
94 : : /** Same comments as for SetToken() apply! */
95 : : explicit ScFormulaResult( const formula::FormulaToken* p );
96 : :
97 : : ~ScFormulaResult();
98 : :
99 : : /** Well, guess what ... */
100 : : ScFormulaResult& operator=( const ScFormulaResult & r );
101 : :
102 : : /** Assignment as in operator=() but without return */
103 : : void Assign( const ScFormulaResult & r );
104 : :
105 : : /** Sets a direct double if token type is formula::svDouble, or mbEmpty if
106 : : formula::svEmptyCell, else token. If p is NULL, that is set as well, effectively
107 : : resulting in GetType()==svUnknown. If the already existing result is
108 : : ScMatrixFormulaCellToken, the upper left ist set to token.
109 : :
110 : : ATTENTION! formula::FormulaToken had to be allocated using 'new' and if of type
111 : : formula::svDouble and no RefCount was set may not be used after this call
112 : : because it was deleted after decrement! */
113 : : void SetToken( const formula::FormulaToken* p );
114 : :
115 : : /** May be NULL if SetToken() did so, also if type formula::svDouble or formula::svError! */
116 : : formula::FormulaConstTokenRef GetToken() const;
117 : :
118 : : /** Return upper left token if formula::svMatrixCell, else return GetToken().
119 : : May be NULL if SetToken() did so, also if type formula::svDouble or formula::svError! */
120 : : formula::FormulaConstTokenRef GetCellResultToken() const;
121 : :
122 : : /** Return type of result, including formula::svError, formula::svEmptyCell, formula::svDouble and
123 : : formula::svMatrixCell. */
124 : : formula::StackVar GetType() const;
125 : :
126 : : /** If type is formula::svMatrixCell return the type of upper left element, else
127 : : GetType() */
128 : : formula::StackVar GetCellResultType() const;
129 : :
130 : : /** If type is formula::svEmptyCell (including matrix upper left) and should be
131 : : displayed as empty string */
132 : : bool IsEmptyDisplayedAsString() const;
133 : :
134 : : /** Test for cell result type formula::svDouble, including upper left if
135 : : formula::svMatrixCell. Also included is formula::svError for legacy, because previously
136 : : an error result was treated like a numeric value at some places in
137 : : ScFormulaCell. Also included is formula::svEmptyCell as a reference to an empty
138 : : cell usually is treated as numeric 0. Use GetCellResultType() for
139 : : details instead. */
140 : : bool IsValue() const;
141 : :
142 : : /** Determines whether or not the result is a string containing more than
143 : : one paragraph */
144 : : bool IsMultiline() const;
145 : :
146 : : /** Get error code if set or GetCellResultType() is formula::svError or svUnknown,
147 : : else 0. */
148 : : sal_uInt16 GetResultError() const;
149 : :
150 : : /** Set error code, don't touch token or double. */
151 : : void SetResultError( sal_uInt16 nErr );
152 : :
153 : : /** Set direct double. Shouldn't be used externally except in
154 : : ScFormulaCell for rounded CalcAsShown or SetErrCode() or
155 : : SetResultDouble(), see there for condition. If
156 : : ScMatrixFormulaCellToken the token isn't replaced but upper
157 : : left result is modified instead, but only if it was of type
158 : : formula::svDouble before or not set at all.
159 : : */
160 : : SC_DLLPUBLIC void SetDouble( double f );
161 : :
162 : : /** Return value if type formula::svDouble or formula::svHybridCell or formula::svMatrixCell and upper
163 : : left formula::svDouble, else 0.0 */
164 : : double GetDouble() const;
165 : :
166 : : /** Return string if type formula::svString or formula::svHybridCell or formula::svMatrixCell and
167 : : upper left formula::svString, else empty string. */
168 : : const String& GetString() const;
169 : :
170 : : /** Return matrix if type formula::svMatrixCell and ScMatrix present, else NULL. */
171 : : ScConstMatrixRef GetMatrix() const;
172 : :
173 : : /** Return formula string if type formula::svHybridCell, else empty string. */
174 : : const String& GetHybridFormula() const;
175 : :
176 : : /** Should only be used by import filters, best in the order
177 : : SetHybridDouble(), SetHybridString(), or only SetHybridString() for
178 : : formula string to be compiled later. */
179 : : SC_DLLPUBLIC void SetHybridDouble( double f );
180 : :
181 : : /** Should only be used by import filters, best in the order
182 : : SetHybridDouble(), SetHybridString()/SetHybridFormula(), or only
183 : : SetHybridFormula() for formula string to be compiled later. */
184 : : SC_DLLPUBLIC void SetHybridString( const rtl::OUString & rStr );
185 : :
186 : : /** Should only be used by import filters, best in the order
187 : : SetHybridDouble(), SetHybridString()/SetHybridFormula(), or only
188 : : SetHybridFormula() for formula string to be compiled later. */
189 : : SC_DLLPUBLIC void SetHybridFormula( const String & rFormula );
190 : :
191 : : /** Get the const ScMatrixFormulaCellToken* if token is of that type, else
192 : : NULL. */
193 : : const ScMatrixFormulaCellToken* GetMatrixFormulaCellToken() const;
194 : :
195 : : /** Get the ScMatrixFormulaCellToken* if token is of that type, else NULL.
196 : : Shouldn't be used externally except by ScFormulaCell::SetMatColsRows(). */
197 : : ScMatrixFormulaCellToken* GetMatrixFormulaCellTokenNonConst();
198 : : };
199 : :
200 : : #endif // SC_FORMULARESULT_HXX
201 : :
202 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|