Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
core
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
LibreOffice
core
Commits
967a3deb
Kaydet (Commit)
967a3deb
authored
Nis 10, 2012
tarafından
Kohei Yoshida
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Non inline methods of ScFormulaResult.
üst
53a40d5e
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
486 additions
and
468 deletions
+486
-468
Library_sc.mk
sc/Library_sc.mk
+1
-0
formularesult.hxx
sc/inc/formularesult.hxx
+33
-468
formularesult.cxx
sc/source/core/tool/formularesult.cxx
+452
-0
No files found.
sc/Library_sc.mk
Dosyayı görüntüle @
967a3deb
...
@@ -178,6 +178,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
...
@@ -178,6 +178,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
sc/source/core/tool/editutil \
sc/source/core/tool/editutil \
sc/source/core/tool/filtopt \
sc/source/core/tool/filtopt \
sc/source/core/tool/formulaparserpool \
sc/source/core/tool/formulaparserpool \
sc/source/core/tool/formularesult \
sc/source/core/tool/hints \
sc/source/core/tool/hints \
sc/source/core/tool/inputopt \
sc/source/core/tool/inputopt \
sc/source/core/tool/interpr1 \
sc/source/core/tool/interpr1 \
...
...
sc/inc/formularesult.hxx
Dosyayı görüntüle @
967a3deb
...
@@ -30,6 +30,8 @@
...
@@ -30,6 +30,8 @@
#define SC_FORMULARESULT_HXX
#define SC_FORMULARESULT_HXX
#include "token.hxx"
#include "token.hxx"
#include "scdllapi.h"
#include <sal/log.hxx>
#include <sal/log.hxx>
/** Store a variable formula cell result, balancing between runtime performance
/** Store a variable formula cell result, balancing between runtime performance
...
@@ -68,7 +70,7 @@ class ScFormulaResult
...
@@ -68,7 +70,7 @@ class ScFormulaResult
/** Reset mnError, mbEmpty and mbEmptyDisplayedAsString to their defaults
/** Reset mnError, mbEmpty and mbEmptyDisplayedAsString to their defaults
prior to assigning other types */
prior to assigning other types */
inline
void
ResetToDefaults
();
void
ResetToDefaults
();
/** If token is of formula::svError set error code and decrement RefCount.
/** If token is of formula::svError set error code and decrement RefCount.
If token is of formula::svEmptyCell set mbEmpty and mbEmptyAsString and
If token is of formula::svEmptyCell set mbEmpty and mbEmptyAsString and
...
@@ -81,65 +83,24 @@ class ScFormulaResult
...
@@ -81,65 +83,24 @@ class ScFormulaResult
DecRef'ed prior to this call, p will be assigned to mpToken if not
DecRef'ed prior to this call, p will be assigned to mpToken if not
resolved.
resolved.
ATTENTION! Token may get deleted in this call! */
ATTENTION! Token may get deleted in this call! */
inline
void
ResolveToken
(
const
formula
::
FormulaToken
*
p
);
void
ResolveToken
(
const
formula
::
FormulaToken
*
p
);
public
:
public
:
/** Effectively type svUnknown. */
/** Effectively type svUnknown. */
ScFormulaResult
()
ScFormulaResult
();
:
mpToken
(
NULL
),
mnError
(
0
),
mbToken
(
true
),
mbEmpty
(
false
),
mbEmptyDisplayedAsString
(
false
),
ScFormulaResult
(
const
ScFormulaResult
&
r
);
meMultiline
(
MULTILINE_UNKNOWN
)
{}
ScFormulaResult
(
const
ScFormulaResult
&
r
)
:
mnError
(
r
.
mnError
),
mbToken
(
r
.
mbToken
),
mbEmpty
(
r
.
mbEmpty
),
mbEmptyDisplayedAsString
(
r
.
mbEmptyDisplayedAsString
),
meMultiline
(
r
.
meMultiline
)
{
if
(
mbToken
)
{
mpToken
=
r
.
mpToken
;
if
(
mpToken
)
{
// Since matrix dimension and
// results are assigned to a matrix
// cell formula token we have to
// clone that instead of sharing it.
const
ScMatrixFormulaCellToken
*
pMatFormula
=
r
.
GetMatrixFormulaCellToken
();
if
(
pMatFormula
)
{
mpToken
=
new
ScMatrixFormulaCellToken
(
*
pMatFormula
);
mpToken
->
IncRef
();
}
else
IncrementTokenRef
(
mpToken
);
}
}
else
mfValue
=
r
.
mfValue
;
}
/** Same comments as for SetToken() apply! */
/** Same comments as for SetToken() apply! */
explicit
ScFormulaResult
(
const
formula
::
FormulaToken
*
p
)
explicit
ScFormulaResult
(
const
formula
::
FormulaToken
*
p
);
:
mnError
(
0
),
mbToken
(
false
),
mbEmpty
(
false
),
mbEmptyDisplayedAsString
(
false
),
~
ScFormulaResult
();
meMultiline
(
MULTILINE_UNKNOWN
)
{
SetToken
(
p
);
}
~
ScFormulaResult
()
{
if
(
mbToken
&&
mpToken
)
mpToken
->
DecRef
();
}
/** Well, guess what ... */
/** Well, guess what ... */
inline
ScFormulaResult
&
operator
=
(
const
ScFormulaResult
&
r
);
ScFormulaResult
&
operator
=
(
const
ScFormulaResult
&
r
);
/** Assignment as in operator=() but without return */
/** Assignment as in operator=() but without return */
inline
void
Assign
(
const
ScFormulaResult
&
r
);
void
Assign
(
const
ScFormulaResult
&
r
);
/** Sets a direct double if token type is formula::svDouble, or mbEmpty if
/** Sets a direct double if token type is formula::svDouble, or mbEmpty if
formula::svEmptyCell, else token. If p is NULL, that is set as well, effectively
formula::svEmptyCell, else token. If p is NULL, that is set as well, effectively
...
@@ -149,26 +110,26 @@ public:
...
@@ -149,26 +110,26 @@ public:
ATTENTION! formula::FormulaToken had to be allocated using 'new' and if of type
ATTENTION! formula::FormulaToken had to be allocated using 'new' and if of type
formula::svDouble and no RefCount was set may not be used after this call
formula::svDouble and no RefCount was set may not be used after this call
because it was deleted after decrement! */
because it was deleted after decrement! */
inline
void
SetToken
(
const
formula
::
FormulaToken
*
p
);
void
SetToken
(
const
formula
::
FormulaToken
*
p
);
/** May be NULL if SetToken() did so, also if type formula::svDouble or formula::svError! */
/** May be NULL if SetToken() did so, also if type formula::svDouble or formula::svError! */
inline
formula
::
FormulaConstTokenRef
GetToken
()
const
;
formula
::
FormulaConstTokenRef
GetToken
()
const
;
/** Return upper left token if formula::svMatrixCell, else return GetToken().
/** Return upper left token if formula::svMatrixCell, else return GetToken().
May be NULL if SetToken() did so, also if type formula::svDouble or formula::svError! */
May be NULL if SetToken() did so, also if type formula::svDouble or formula::svError! */
inline
formula
::
FormulaConstTokenRef
GetCellResultToken
()
const
;
formula
::
FormulaConstTokenRef
GetCellResultToken
()
const
;
/** Return type of result, including formula::svError, formula::svEmptyCell, formula::svDouble and
/** Return type of result, including formula::svError, formula::svEmptyCell, formula::svDouble and
formula::svMatrixCell. */
formula::svMatrixCell. */
inline
formula
::
StackVar
GetType
()
const
;
formula
::
StackVar
GetType
()
const
;
/** If type is formula::svMatrixCell return the type of upper left element, else
/** If type is formula::svMatrixCell return the type of upper left element, else
GetType() */
GetType() */
inline
formula
::
StackVar
GetCellResultType
()
const
;
formula
::
StackVar
GetCellResultType
()
const
;
/** If type is formula::svEmptyCell (including matrix upper left) and should be
/** If type is formula::svEmptyCell (including matrix upper left) and should be
displayed as empty string */
displayed as empty string */
inline
bool
IsEmptyDisplayedAsString
()
const
;
bool
IsEmptyDisplayedAsString
()
const
;
/** Test for cell result type formula::svDouble, including upper left if
/** Test for cell result type formula::svDouble, including upper left if
formula::svMatrixCell. Also included is formula::svError for legacy, because previously
formula::svMatrixCell. Also included is formula::svError for legacy, because previously
...
@@ -176,460 +137,64 @@ public:
...
@@ -176,460 +137,64 @@ public:
ScFormulaCell. Also included is formula::svEmptyCell as a reference to an empty
ScFormulaCell. Also included is formula::svEmptyCell as a reference to an empty
cell usually is treated as numeric 0. Use GetCellResultType() for
cell usually is treated as numeric 0. Use GetCellResultType() for
details instead. */
details instead. */
inline
bool
IsValue
()
const
;
bool
IsValue
()
const
;
/** Determines whether or not the result is a string containing more than
/** Determines whether or not the result is a string containing more than
one paragraph */
one paragraph */
inline
bool
IsMultiline
()
const
;
bool
IsMultiline
()
const
;
/** Get error code if set or GetCellResultType() is formula::svError or svUnknown,
/** Get error code if set or GetCellResultType() is formula::svError or svUnknown,
else 0. */
else 0. */
inline
sal_uInt16
GetResultError
()
const
;
sal_uInt16
GetResultError
()
const
;
/** Set error code, don't touch token or double. */
/** Set error code, don't touch token or double. */
inline
void
SetResultError
(
sal_uInt16
nErr
);
void
SetResultError
(
sal_uInt16
nErr
);
/** Set direct double. Shouldn't be used externally except in
/** Set direct double. Shouldn't be used externally except in
ScFormulaCell for rounded CalcAsShown or SetErrCode(). If
ScFormulaCell for rounded CalcAsShown or SetErrCode(). If
ScMatrixFormulaCellToken the token isn't replaced but upper left result
ScMatrixFormulaCellToken the token isn't replaced but upper left result
is modified instead, but only if it was of type formula::svDouble before or not
is modified instead, but only if it was of type formula::svDouble before or not
set at all. */
set at all. */
inline
void
SetDouble
(
double
f
);
void
SetDouble
(
double
f
);
/** Return value if type formula::svDouble or formula::svHybridCell or formula::svMatrixCell and upper
/** Return value if type formula::svDouble or formula::svHybridCell or formula::svMatrixCell and upper
left formula::svDouble, else 0.0 */
left formula::svDouble, else 0.0 */
inline
double
GetDouble
()
const
;
double
GetDouble
()
const
;
/** Return string if type formula::svString or formula::svHybridCell or formula::svMatrixCell and
/** Return string if type formula::svString or formula::svHybridCell or formula::svMatrixCell and
upper left formula::svString, else empty string. */
upper left formula::svString, else empty string. */
inline
const
String
&
GetString
()
const
;
const
String
&
GetString
()
const
;
/** Return matrix if type formula::svMatrixCell and ScMatrix present, else NULL. */
/** Return matrix if type formula::svMatrixCell and ScMatrix present, else NULL. */
inline
ScConstMatrixRef
GetMatrix
()
const
;
ScConstMatrixRef
GetMatrix
()
const
;
/** Return formula string if type formula::svHybridCell, else empty string. */
/** Return formula string if type formula::svHybridCell, else empty string. */
inline
const
String
&
GetHybridFormula
()
const
;
const
String
&
GetHybridFormula
()
const
;
/** Should only be used by import filters, best in the order
/** Should only be used by import filters, best in the order
SetHybridDouble(), SetHybridString(), or only SetHybridString() for
SetHybridDouble(), SetHybridString(), or only SetHybridString() for
formula string to be compiled later. */
formula string to be compiled later. */
inline
void
SetHybridDouble
(
double
f
);
SC_DLLPUBLIC
void
SetHybridDouble
(
double
f
);
/** Should only be used by import filters, best in the order
/** Should only be used by import filters, best in the order
SetHybridDouble(), SetHybridString()/SetHybridFormula(), or only
SetHybridDouble(), SetHybridString()/SetHybridFormula(), or only
SetHybridFormula() for formula string to be compiled later. */
SetHybridFormula() for formula string to be compiled later. */
inline
void
SetHybridString
(
const
rtl
::
OUString
&
rStr
);
SC_DLLPUBLIC
void
SetHybridString
(
const
rtl
::
OUString
&
rStr
);
/** Should only be used by import filters, best in the order
/** Should only be used by import filters, best in the order
SetHybridDouble(), SetHybridString()/SetHybridFormula(), or only
SetHybridDouble(), SetHybridString()/SetHybridFormula(), or only
SetHybridFormula() for formula string to be compiled later. */
SetHybridFormula() for formula string to be compiled later. */
inline
void
SetHybridFormula
(
const
String
&
rFormula
);
SC_DLLPUBLIC
void
SetHybridFormula
(
const
String
&
rFormula
);
/** Get the const ScMatrixFormulaCellToken* if token is of that type, else
/** Get the const ScMatrixFormulaCellToken* if token is of that type, else
NULL. */
NULL. */
inline
const
ScMatrixFormulaCellToken
*
GetMatrixFormulaCellToken
()
const
;
const
ScMatrixFormulaCellToken
*
GetMatrixFormulaCellToken
()
const
;
/** Get the ScMatrixFormulaCellToken* if token is of that type, else NULL.
/** Get the ScMatrixFormulaCellToken* if token is of that type, else NULL.
Shouldn't be used externally except by ScFormulaCell::SetMatColsRows(). */
Shouldn't be used externally except by ScFormulaCell::SetMatColsRows(). */
inline
ScMatrixFormulaCellToken
*
GetMatrixFormulaCellTokenNonConst
();
ScMatrixFormulaCellToken
*
GetMatrixFormulaCellTokenNonConst
();
};
};
inline
void
ScFormulaResult
::
ResetToDefaults
()
{
mnError
=
0
;
mbEmpty
=
false
;
mbEmptyDisplayedAsString
=
false
;
meMultiline
=
MULTILINE_UNKNOWN
;
}
inline
void
ScFormulaResult
::
ResolveToken
(
const
formula
::
FormulaToken
*
p
)
{
ResetToDefaults
();
if
(
!
p
)
{
mpToken
=
p
;
mbToken
=
true
;
}
else
{
switch
(
p
->
GetType
())
{
case
formula
:
:
svError
:
mnError
=
p
->
GetError
();
p
->
DecRef
();
mbToken
=
false
;
// set in case mnError is 0 now, which shouldn't happen but ...
mfValue
=
0.0
;
meMultiline
=
MULTILINE_FALSE
;
break
;
case
formula
:
:
svEmptyCell
:
mbEmpty
=
true
;
mbEmptyDisplayedAsString
=
static_cast
<
const
ScEmptyCellToken
*>
(
p
)
->
IsDisplayedAsString
();
p
->
DecRef
();
mbToken
=
false
;
meMultiline
=
MULTILINE_FALSE
;
break
;
case
formula
:
:
svDouble
:
mfValue
=
p
->
GetDouble
();
p
->
DecRef
();
mbToken
=
false
;
meMultiline
=
MULTILINE_FALSE
;
break
;
default
:
mpToken
=
p
;
mbToken
=
true
;
}
}
}
inline
ScFormulaResult
&
ScFormulaResult
::
operator
=
(
const
ScFormulaResult
&
r
)
{
Assign
(
r
);
return
*
this
;
}
inline
void
ScFormulaResult
::
Assign
(
const
ScFormulaResult
&
r
)
{
if
(
this
==
&
r
)
return
;
if
(
r
.
mbEmpty
)
{
if
(
mbToken
&&
mpToken
)
mpToken
->
DecRef
();
mbToken
=
false
;
mbEmpty
=
true
;
mbEmptyDisplayedAsString
=
r
.
mbEmptyDisplayedAsString
;
meMultiline
=
r
.
meMultiline
;
}
else
if
(
r
.
mbToken
)
{
// Matrix formula cell token must be cloned, see copy-ctor.
const
ScMatrixFormulaCellToken
*
pMatFormula
=
r
.
GetMatrixFormulaCellToken
();
if
(
pMatFormula
)
SetToken
(
new
ScMatrixFormulaCellToken
(
*
pMatFormula
));
else
SetToken
(
r
.
mpToken
);
}
else
SetDouble
(
r
.
mfValue
);
// If there was an error there will be an error, no matter what Set...()
// methods did.
mnError
=
r
.
mnError
;
}
inline
void
ScFormulaResult
::
SetToken
(
const
formula
::
FormulaToken
*
p
)
{
ResetToDefaults
();
IncrementTokenRef
(
p
);
// Handle a result obtained from the interpreter to be assigned to a matrix
// formula cell's ScMatrixFormulaCellToken.
ScMatrixFormulaCellToken
*
pMatFormula
=
GetMatrixFormulaCellTokenNonConst
();
if
(
pMatFormula
)
{
const
ScMatrixCellResultToken
*
pMatResult
=
(
p
&&
p
->
GetType
()
==
formula
::
svMatrixCell
?
dynamic_cast
<
const
ScMatrixCellResultToken
*>
(
p
)
:
NULL
);
if
(
pMatResult
)
{
const
ScMatrixFormulaCellToken
*
pNewMatFormula
=
dynamic_cast
<
const
ScMatrixFormulaCellToken
*>
(
pMatResult
);
if
(
pNewMatFormula
)
{
SAL_WARN
(
"sc"
,
"ScFormulaResult::SetToken: pNewMatFormula and pMatFormula, overriding matrix formula dimension; intended?"
);
pMatFormula
->
SetMatColsRows
(
pNewMatFormula
->
GetMatCols
(),
pNewMatFormula
->
GetMatRows
());
}
pMatFormula
->
Assign
(
*
pMatResult
);
p
->
DecRef
();
}
else
if
(
p
)
{
// This may be the result of some constant expression like
// {="string"} that doesn't result in a matrix but still would
// display the result in all cells of this matrix formula.
pMatFormula
->
Assign
(
*
p
);
p
->
DecRef
();
}
else
{
// NULL result? Well, if you say so ...
pMatFormula
->
ResetResult
();
}
}
else
{
if
(
mbToken
&&
mpToken
)
mpToken
->
DecRef
();
ResolveToken
(
p
);
}
}
inline
void
ScFormulaResult
::
SetDouble
(
double
f
)
{
ResetToDefaults
();
// Handle a result obtained from the interpreter to be assigned to a matrix
// formula cell's ScMatrixFormulaCellToken.
ScMatrixFormulaCellToken
*
pMatFormula
=
GetMatrixFormulaCellTokenNonConst
();
if
(
pMatFormula
)
pMatFormula
->
SetUpperLeftDouble
(
f
);
else
{
if
(
mbToken
&&
mpToken
)
mpToken
->
DecRef
();
mfValue
=
f
;
mbToken
=
false
;
meMultiline
=
MULTILINE_FALSE
;
}
}
inline
formula
::
StackVar
ScFormulaResult
::
GetType
()
const
{
// Order is significant.
if
(
mnError
)
return
formula
::
svError
;
if
(
mbEmpty
)
return
formula
::
svEmptyCell
;
if
(
!
mbToken
)
return
formula
::
svDouble
;
if
(
mpToken
)
return
mpToken
->
GetType
();
return
formula
::
svUnknown
;
}
inline
formula
::
StackVar
ScFormulaResult
::
GetCellResultType
()
const
{
formula
::
StackVar
sv
=
GetType
();
if
(
sv
==
formula
::
svMatrixCell
)
// don't need to test for mpToken here, GetType() already did it
sv
=
static_cast
<
const
ScMatrixCellResultToken
*>
(
mpToken
)
->
GetUpperLeftType
();
return
sv
;
}
inline
bool
ScFormulaResult
::
IsEmptyDisplayedAsString
()
const
{
if
(
mbEmpty
)
return
mbEmptyDisplayedAsString
;
if
(
GetType
()
==
formula
::
svMatrixCell
)
{
// don't need to test for mpToken here, GetType() already did it
const
ScEmptyCellToken
*
p
=
dynamic_cast
<
const
ScEmptyCellToken
*>
(
static_cast
<
const
ScMatrixCellResultToken
*>
(
mpToken
)
->
GetUpperLeftToken
().
get
());
if
(
p
)
return
p
->
IsDisplayedAsString
();
}
return
false
;
}
inline
bool
ScFormulaResult
::
IsValue
()
const
{
formula
::
StackVar
sv
=
GetCellResultType
();
return
sv
==
formula
::
svDouble
||
sv
==
formula
::
svError
||
sv
==
formula
::
svEmptyCell
;
}
inline
bool
ScFormulaResult
::
IsMultiline
()
const
{
if
(
meMultiline
==
MULTILINE_UNKNOWN
)
{
const
String
&
rStr
=
GetString
();
if
(
rStr
.
Len
()
&&
rStr
.
Search
(
_LF
)
!=
STRING_NOTFOUND
)
const_cast
<
ScFormulaResult
*>
(
this
)
->
meMultiline
=
MULTILINE_TRUE
;
else
const_cast
<
ScFormulaResult
*>
(
this
)
->
meMultiline
=
MULTILINE_FALSE
;
}
return
meMultiline
==
MULTILINE_TRUE
;
}
inline
sal_uInt16
ScFormulaResult
::
GetResultError
()
const
{
if
(
mnError
)
return
mnError
;
formula
::
StackVar
sv
=
GetCellResultType
();
if
(
sv
==
formula
::
svError
)
{
if
(
GetType
()
==
formula
::
svMatrixCell
)
// don't need to test for mpToken here, GetType() already did it
return
static_cast
<
const
ScMatrixCellResultToken
*>
(
mpToken
)
->
GetUpperLeftToken
()
->
GetError
();
if
(
mpToken
)
return
mpToken
->
GetError
();
}
return
0
;
}
inline
void
ScFormulaResult
::
SetResultError
(
sal_uInt16
nErr
)
{
mnError
=
nErr
;
}
inline
formula
::
FormulaConstTokenRef
ScFormulaResult
::
GetToken
()
const
{
if
(
mbToken
)
return
mpToken
;
return
NULL
;
}
inline
formula
::
FormulaConstTokenRef
ScFormulaResult
::
GetCellResultToken
()
const
{
if
(
GetType
()
==
formula
::
svMatrixCell
)
// don't need to test for mpToken here, GetType() already did it
return
static_cast
<
const
ScMatrixCellResultToken
*>
(
mpToken
)
->
GetUpperLeftToken
();
return
GetToken
();
}
inline
double
ScFormulaResult
::
GetDouble
()
const
{
if
(
mbToken
)
{
// Should really not be of type formula::svDouble here.
if
(
mpToken
)
{
switch
(
mpToken
->
GetType
())
{
case
formula
:
:
svHybridCell
:
return
mpToken
->
GetDouble
();
case
formula
:
:
svMatrixCell
:
{
const
ScMatrixCellResultToken
*
p
=
static_cast
<
const
ScMatrixCellResultToken
*>
(
mpToken
);
if
(
p
->
GetUpperLeftType
()
==
formula
::
svDouble
)
return
p
->
GetUpperLeftToken
()
->
GetDouble
();
}
break
;
default
:
;
// nothing
}
}
return
0.0
;
}
if
(
mbEmpty
)
return
0.0
;
return
mfValue
;
}
inline
const
String
&
ScFormulaResult
::
GetString
()
const
{
if
(
mbToken
&&
mpToken
)
{
switch
(
mpToken
->
GetType
())
{
case
formula
:
:
svString
:
case
formula
:
:
svHybridCell
:
return
mpToken
->
GetString
();
case
formula
:
:
svMatrixCell
:
{
const
ScMatrixCellResultToken
*
p
=
static_cast
<
const
ScMatrixCellResultToken
*>
(
mpToken
);
if
(
p
->
GetUpperLeftType
()
==
formula
::
svString
)
return
p
->
GetUpperLeftToken
()
->
GetString
();
}
break
;
default
:
;
// nothing
}
}
return
EMPTY_STRING
;
}
inline
ScConstMatrixRef
ScFormulaResult
::
GetMatrix
()
const
{
if
(
GetType
()
==
formula
::
svMatrixCell
)
return
static_cast
<
const
ScToken
*>
(
mpToken
)
->
GetMatrix
();
return
NULL
;
}
inline
const
String
&
ScFormulaResult
::
GetHybridFormula
()
const
{
if
(
GetType
()
==
formula
::
svHybridCell
)
{
const
ScHybridCellToken
*
p
=
dynamic_cast
<
const
ScHybridCellToken
*>
(
mpToken
);
if
(
p
)
return
p
->
GetFormula
();
}
return
EMPTY_STRING
;
}
inline
void
ScFormulaResult
::
SetHybridDouble
(
double
f
)
{
ResetToDefaults
();
if
(
mbToken
&&
mpToken
)
{
String
aString
(
GetString
());
String
aFormula
(
GetHybridFormula
());
mpToken
->
DecRef
();
mpToken
=
new
ScHybridCellToken
(
f
,
aString
,
aFormula
);
mpToken
->
IncRef
();
}
else
{
mfValue
=
f
;
mbToken
=
false
;
meMultiline
=
MULTILINE_FALSE
;
}
}
inline
void
ScFormulaResult
::
SetHybridString
(
const
rtl
::
OUString
&
rStr
)
{
// Obtain values before changing anything.
double
f
=
GetDouble
();
String
aFormula
(
GetHybridFormula
());
ResetToDefaults
();
if
(
mbToken
&&
mpToken
)
mpToken
->
DecRef
();
mpToken
=
new
ScHybridCellToken
(
f
,
rStr
,
aFormula
);
mpToken
->
IncRef
();
mbToken
=
true
;
}
inline
void
ScFormulaResult
::
SetHybridFormula
(
const
String
&
rFormula
)
{
// Obtain values before changing anything.
double
f
=
GetDouble
();
String
aStr
(
GetString
());
ResetToDefaults
();
if
(
mbToken
&&
mpToken
)
mpToken
->
DecRef
();
mpToken
=
new
ScHybridCellToken
(
f
,
aStr
,
rFormula
);
mpToken
->
IncRef
();
mbToken
=
true
;
}
inline
const
ScMatrixFormulaCellToken
*
ScFormulaResult
::
GetMatrixFormulaCellToken
()
const
{
return
(
GetType
()
==
formula
::
svMatrixCell
?
dynamic_cast
<
const
ScMatrixFormulaCellToken
*>
(
mpToken
)
:
NULL
);
}
inline
ScMatrixFormulaCellToken
*
ScFormulaResult
::
GetMatrixFormulaCellTokenNonConst
()
{
return
const_cast
<
ScMatrixFormulaCellToken
*>
(
GetMatrixFormulaCellToken
());
}
#endif // SC_FORMULARESULT_HXX
#endif // SC_FORMULARESULT_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sc/source/core/tool/formularesult.cxx
0 → 100644
Dosyayı görüntüle @
967a3deb
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* Version: MPL 1.1 / GPLv3+ / LGPLv3+
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License or as specified alternatively below. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* Major Contributor(s):
* Copyright (C) 2012 Kohei Yoshida <kohei.yoshida@suse.com>
*
* All Rights Reserved.
*
* For minor contributions see the git repository.
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 3 or later (the "GPLv3+"), or
* the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
* in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
* instead of those above.
*/
#include "formularesult.hxx"
ScFormulaResult
::
ScFormulaResult
()
:
mpToken
(
NULL
),
mnError
(
0
),
mbToken
(
true
),
mbEmpty
(
false
),
mbEmptyDisplayedAsString
(
false
),
meMultiline
(
MULTILINE_UNKNOWN
)
{}
ScFormulaResult
::
ScFormulaResult
(
const
ScFormulaResult
&
r
)
:
mnError
(
r
.
mnError
),
mbToken
(
r
.
mbToken
),
mbEmpty
(
r
.
mbEmpty
),
mbEmptyDisplayedAsString
(
r
.
mbEmptyDisplayedAsString
),
meMultiline
(
r
.
meMultiline
)
{
if
(
mbToken
)
{
mpToken
=
r
.
mpToken
;
if
(
mpToken
)
{
// Since matrix dimension and
// results are assigned to a matrix
// cell formula token we have to
// clone that instead of sharing it.
const
ScMatrixFormulaCellToken
*
pMatFormula
=
r
.
GetMatrixFormulaCellToken
();
if
(
pMatFormula
)
{
mpToken
=
new
ScMatrixFormulaCellToken
(
*
pMatFormula
);
mpToken
->
IncRef
();
}
else
IncrementTokenRef
(
mpToken
);
}
}
else
mfValue
=
r
.
mfValue
;
}
ScFormulaResult
::
ScFormulaResult
(
const
formula
::
FormulaToken
*
p
)
:
mnError
(
0
),
mbToken
(
false
),
mbEmpty
(
false
),
mbEmptyDisplayedAsString
(
false
),
meMultiline
(
MULTILINE_UNKNOWN
)
{
SetToken
(
p
);
}
ScFormulaResult
::~
ScFormulaResult
()
{
if
(
mbToken
&&
mpToken
)
mpToken
->
DecRef
();
}
void
ScFormulaResult
::
ResetToDefaults
()
{
mnError
=
0
;
mbEmpty
=
false
;
mbEmptyDisplayedAsString
=
false
;
meMultiline
=
MULTILINE_UNKNOWN
;
}
void
ScFormulaResult
::
ResolveToken
(
const
formula
::
FormulaToken
*
p
)
{
ResetToDefaults
();
if
(
!
p
)
{
mpToken
=
p
;
mbToken
=
true
;
}
else
{
switch
(
p
->
GetType
())
{
case
formula
:
:
svError
:
mnError
=
p
->
GetError
();
p
->
DecRef
();
mbToken
=
false
;
// set in case mnError is 0 now, which shouldn't happen but ...
mfValue
=
0.0
;
meMultiline
=
MULTILINE_FALSE
;
break
;
case
formula
:
:
svEmptyCell
:
mbEmpty
=
true
;
mbEmptyDisplayedAsString
=
static_cast
<
const
ScEmptyCellToken
*>
(
p
)
->
IsDisplayedAsString
();
p
->
DecRef
();
mbToken
=
false
;
meMultiline
=
MULTILINE_FALSE
;
break
;
case
formula
:
:
svDouble
:
mfValue
=
p
->
GetDouble
();
p
->
DecRef
();
mbToken
=
false
;
meMultiline
=
MULTILINE_FALSE
;
break
;
default
:
mpToken
=
p
;
mbToken
=
true
;
}
}
}
ScFormulaResult
&
ScFormulaResult
::
operator
=
(
const
ScFormulaResult
&
r
)
{
Assign
(
r
);
return
*
this
;
}
void
ScFormulaResult
::
Assign
(
const
ScFormulaResult
&
r
)
{
if
(
this
==
&
r
)
return
;
if
(
r
.
mbEmpty
)
{
if
(
mbToken
&&
mpToken
)
mpToken
->
DecRef
();
mbToken
=
false
;
mbEmpty
=
true
;
mbEmptyDisplayedAsString
=
r
.
mbEmptyDisplayedAsString
;
meMultiline
=
r
.
meMultiline
;
}
else
if
(
r
.
mbToken
)
{
// Matrix formula cell token must be cloned, see copy-ctor.
const
ScMatrixFormulaCellToken
*
pMatFormula
=
r
.
GetMatrixFormulaCellToken
();
if
(
pMatFormula
)
SetToken
(
new
ScMatrixFormulaCellToken
(
*
pMatFormula
));
else
SetToken
(
r
.
mpToken
);
}
else
SetDouble
(
r
.
mfValue
);
// If there was an error there will be an error, no matter what Set...()
// methods did.
mnError
=
r
.
mnError
;
}
void
ScFormulaResult
::
SetToken
(
const
formula
::
FormulaToken
*
p
)
{
ResetToDefaults
();
IncrementTokenRef
(
p
);
// Handle a result obtained from the interpreter to be assigned to a matrix
// formula cell's ScMatrixFormulaCellToken.
ScMatrixFormulaCellToken
*
pMatFormula
=
GetMatrixFormulaCellTokenNonConst
();
if
(
pMatFormula
)
{
const
ScMatrixCellResultToken
*
pMatResult
=
(
p
&&
p
->
GetType
()
==
formula
::
svMatrixCell
?
dynamic_cast
<
const
ScMatrixCellResultToken
*>
(
p
)
:
NULL
);
if
(
pMatResult
)
{
const
ScMatrixFormulaCellToken
*
pNewMatFormula
=
dynamic_cast
<
const
ScMatrixFormulaCellToken
*>
(
pMatResult
);
if
(
pNewMatFormula
)
{
SAL_WARN
(
"sc"
,
"ScFormulaResult::SetToken: pNewMatFormula and pMatFormula, overriding matrix formula dimension; intended?"
);
pMatFormula
->
SetMatColsRows
(
pNewMatFormula
->
GetMatCols
(),
pNewMatFormula
->
GetMatRows
());
}
pMatFormula
->
Assign
(
*
pMatResult
);
p
->
DecRef
();
}
else
if
(
p
)
{
// This may be the result of some constant expression like
// {="string"} that doesn't result in a matrix but still would
// display the result in all cells of this matrix formula.
pMatFormula
->
Assign
(
*
p
);
p
->
DecRef
();
}
else
{
// NULL result? Well, if you say so ...
pMatFormula
->
ResetResult
();
}
}
else
{
if
(
mbToken
&&
mpToken
)
mpToken
->
DecRef
();
ResolveToken
(
p
);
}
}
void
ScFormulaResult
::
SetDouble
(
double
f
)
{
ResetToDefaults
();
// Handle a result obtained from the interpreter to be assigned to a matrix
// formula cell's ScMatrixFormulaCellToken.
ScMatrixFormulaCellToken
*
pMatFormula
=
GetMatrixFormulaCellTokenNonConst
();
if
(
pMatFormula
)
pMatFormula
->
SetUpperLeftDouble
(
f
);
else
{
if
(
mbToken
&&
mpToken
)
mpToken
->
DecRef
();
mfValue
=
f
;
mbToken
=
false
;
meMultiline
=
MULTILINE_FALSE
;
}
}
formula
::
StackVar
ScFormulaResult
::
GetType
()
const
{
// Order is significant.
if
(
mnError
)
return
formula
::
svError
;
if
(
mbEmpty
)
return
formula
::
svEmptyCell
;
if
(
!
mbToken
)
return
formula
::
svDouble
;
if
(
mpToken
)
return
mpToken
->
GetType
();
return
formula
::
svUnknown
;
}
formula
::
StackVar
ScFormulaResult
::
GetCellResultType
()
const
{
formula
::
StackVar
sv
=
GetType
();
if
(
sv
==
formula
::
svMatrixCell
)
// don't need to test for mpToken here, GetType() already did it
sv
=
static_cast
<
const
ScMatrixCellResultToken
*>
(
mpToken
)
->
GetUpperLeftType
();
return
sv
;
}
bool
ScFormulaResult
::
IsEmptyDisplayedAsString
()
const
{
if
(
mbEmpty
)
return
mbEmptyDisplayedAsString
;
if
(
GetType
()
==
formula
::
svMatrixCell
)
{
// don't need to test for mpToken here, GetType() already did it
const
ScEmptyCellToken
*
p
=
dynamic_cast
<
const
ScEmptyCellToken
*>
(
static_cast
<
const
ScMatrixCellResultToken
*>
(
mpToken
)
->
GetUpperLeftToken
().
get
());
if
(
p
)
return
p
->
IsDisplayedAsString
();
}
return
false
;
}
bool
ScFormulaResult
::
IsValue
()
const
{
formula
::
StackVar
sv
=
GetCellResultType
();
return
sv
==
formula
::
svDouble
||
sv
==
formula
::
svError
||
sv
==
formula
::
svEmptyCell
;
}
bool
ScFormulaResult
::
IsMultiline
()
const
{
if
(
meMultiline
==
MULTILINE_UNKNOWN
)
{
const
String
&
rStr
=
GetString
();
if
(
rStr
.
Len
()
&&
rStr
.
Search
(
_LF
)
!=
STRING_NOTFOUND
)
const_cast
<
ScFormulaResult
*>
(
this
)
->
meMultiline
=
MULTILINE_TRUE
;
else
const_cast
<
ScFormulaResult
*>
(
this
)
->
meMultiline
=
MULTILINE_FALSE
;
}
return
meMultiline
==
MULTILINE_TRUE
;
}
sal_uInt16
ScFormulaResult
::
GetResultError
()
const
{
if
(
mnError
)
return
mnError
;
formula
::
StackVar
sv
=
GetCellResultType
();
if
(
sv
==
formula
::
svError
)
{
if
(
GetType
()
==
formula
::
svMatrixCell
)
// don't need to test for mpToken here, GetType() already did it
return
static_cast
<
const
ScMatrixCellResultToken
*>
(
mpToken
)
->
GetUpperLeftToken
()
->
GetError
();
if
(
mpToken
)
return
mpToken
->
GetError
();
}
return
0
;
}
void
ScFormulaResult
::
SetResultError
(
sal_uInt16
nErr
)
{
mnError
=
nErr
;
}
formula
::
FormulaConstTokenRef
ScFormulaResult
::
GetToken
()
const
{
if
(
mbToken
)
return
mpToken
;
return
NULL
;
}
formula
::
FormulaConstTokenRef
ScFormulaResult
::
GetCellResultToken
()
const
{
if
(
GetType
()
==
formula
::
svMatrixCell
)
// don't need to test for mpToken here, GetType() already did it
return
static_cast
<
const
ScMatrixCellResultToken
*>
(
mpToken
)
->
GetUpperLeftToken
();
return
GetToken
();
}
double
ScFormulaResult
::
GetDouble
()
const
{
if
(
mbToken
)
{
// Should really not be of type formula::svDouble here.
if
(
mpToken
)
{
switch
(
mpToken
->
GetType
())
{
case
formula
:
:
svHybridCell
:
return
mpToken
->
GetDouble
();
case
formula
:
:
svMatrixCell
:
{
const
ScMatrixCellResultToken
*
p
=
static_cast
<
const
ScMatrixCellResultToken
*>
(
mpToken
);
if
(
p
->
GetUpperLeftType
()
==
formula
::
svDouble
)
return
p
->
GetUpperLeftToken
()
->
GetDouble
();
}
break
;
default
:
;
// nothing
}
}
return
0.0
;
}
if
(
mbEmpty
)
return
0.0
;
return
mfValue
;
}
const
String
&
ScFormulaResult
::
GetString
()
const
{
if
(
mbToken
&&
mpToken
)
{
switch
(
mpToken
->
GetType
())
{
case
formula
:
:
svString
:
case
formula
:
:
svHybridCell
:
return
mpToken
->
GetString
();
case
formula
:
:
svMatrixCell
:
{
const
ScMatrixCellResultToken
*
p
=
static_cast
<
const
ScMatrixCellResultToken
*>
(
mpToken
);
if
(
p
->
GetUpperLeftType
()
==
formula
::
svString
)
return
p
->
GetUpperLeftToken
()
->
GetString
();
}
break
;
default
:
;
// nothing
}
}
return
EMPTY_STRING
;
}
ScConstMatrixRef
ScFormulaResult
::
GetMatrix
()
const
{
if
(
GetType
()
==
formula
::
svMatrixCell
)
return
static_cast
<
const
ScToken
*>
(
mpToken
)
->
GetMatrix
();
return
NULL
;
}
const
String
&
ScFormulaResult
::
GetHybridFormula
()
const
{
if
(
GetType
()
==
formula
::
svHybridCell
)
{
const
ScHybridCellToken
*
p
=
dynamic_cast
<
const
ScHybridCellToken
*>
(
mpToken
);
if
(
p
)
return
p
->
GetFormula
();
}
return
EMPTY_STRING
;
}
void
ScFormulaResult
::
SetHybridDouble
(
double
f
)
{
ResetToDefaults
();
if
(
mbToken
&&
mpToken
)
{
String
aString
(
GetString
());
String
aFormula
(
GetHybridFormula
());
mpToken
->
DecRef
();
mpToken
=
new
ScHybridCellToken
(
f
,
aString
,
aFormula
);
mpToken
->
IncRef
();
}
else
{
mfValue
=
f
;
mbToken
=
false
;
meMultiline
=
MULTILINE_FALSE
;
}
}
void
ScFormulaResult
::
SetHybridString
(
const
rtl
::
OUString
&
rStr
)
{
// Obtain values before changing anything.
double
f
=
GetDouble
();
String
aFormula
(
GetHybridFormula
());
ResetToDefaults
();
if
(
mbToken
&&
mpToken
)
mpToken
->
DecRef
();
mpToken
=
new
ScHybridCellToken
(
f
,
rStr
,
aFormula
);
mpToken
->
IncRef
();
mbToken
=
true
;
}
void
ScFormulaResult
::
SetHybridFormula
(
const
String
&
rFormula
)
{
// Obtain values before changing anything.
double
f
=
GetDouble
();
String
aStr
(
GetString
());
ResetToDefaults
();
if
(
mbToken
&&
mpToken
)
mpToken
->
DecRef
();
mpToken
=
new
ScHybridCellToken
(
f
,
aStr
,
rFormula
);
mpToken
->
IncRef
();
mbToken
=
true
;
}
const
ScMatrixFormulaCellToken
*
ScFormulaResult
::
GetMatrixFormulaCellToken
()
const
{
return
(
GetType
()
==
formula
::
svMatrixCell
?
dynamic_cast
<
const
ScMatrixFormulaCellToken
*>
(
mpToken
)
:
NULL
);
}
ScMatrixFormulaCellToken
*
ScFormulaResult
::
GetMatrixFormulaCellTokenNonConst
()
{
return
const_cast
<
ScMatrixFormulaCellToken
*>
(
GetMatrixFormulaCellToken
());
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment