diff options
author | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-09-04 15:14:47 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-09-06 01:38:31 -0400 |
commit | 69047ec117cd2e0885efec1824e9c00555da4800 (patch) | |
tree | 6e5f0c29813a91ac4239e80d97789f43e364515d /sc | |
parent | 2d8a60e517c35276051a82b569515b49896b5be9 (diff) |
Correctly handle implicit intersection in group interpretation.
Change-Id: I2ea6f41ad4036a6f3f5d99097e83fd988aacd105
Diffstat (limited to 'sc')
-rw-r--r-- | sc/Library_sc.mk | 1 | ||||
-rw-r--r-- | sc/inc/token.hxx | 24 | ||||
-rw-r--r-- | sc/inc/types.hxx | 13 | ||||
-rw-r--r-- | sc/source/core/data/formulacell.cxx | 4 | ||||
-rw-r--r-- | sc/source/core/data/types.cxx | 24 | ||||
-rw-r--r-- | sc/source/core/inc/interpre.hxx | 11 | ||||
-rw-r--r-- | sc/source/core/tool/formulagroup.cxx | 6 | ||||
-rw-r--r-- | sc/source/core/tool/interpr1.cxx | 244 | ||||
-rw-r--r-- | sc/source/core/tool/interpr4.cxx | 39 | ||||
-rw-r--r-- | sc/source/core/tool/interpr5.cxx | 14 | ||||
-rw-r--r-- | sc/source/core/tool/token.cxx | 41 |
11 files changed, 355 insertions, 66 deletions
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk index 3c06eafaeffd..bd1a9a3b2805 100644 --- a/sc/Library_sc.mk +++ b/sc/Library_sc.mk @@ -181,6 +181,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\ sc/source/core/data/table5 \ sc/source/core/data/table6 \ sc/source/core/data/tabprotection \ + sc/source/core/data/types \ sc/source/core/data/userdat \ sc/source/core/data/validat \ sc/source/core/tool/addincfg \ diff --git a/sc/inc/token.hxx b/sc/inc/token.hxx index 9603a8729e9b..32cdf5ad1869 100644 --- a/sc/inc/token.hxx +++ b/sc/inc/token.hxx @@ -33,6 +33,9 @@ #include "scmatrix.hxx" #include "calcmacros.hxx" +// Matrix token constants. +#define MATRIX_TOKEN_HAS_RANGE 1 + class ScJumpMatrix; typedef ::std::vector< ScComplexRefData > ScRefList; @@ -176,6 +179,27 @@ public: virtual FormulaToken* Clone() const { return new ScMatrixToken(*this); } }; +/** + * Token storing matrix that represents values in sheet range. It stores + * both the values in matrix form, and the range address the matrix + * represents. + */ +class ScMatrixRangeToken : public ScToken +{ + ScMatrixRef mpMatrix; + ScComplexRefData maRef; +public: + ScMatrixRangeToken( const ScMatrixRef& p, const ScComplexRefData& rRef ); + ScMatrixRangeToken( const ScMatrixRangeToken& r ); + + virtual sal_uInt8 GetByte() const; + virtual const ScMatrix* GetMatrix() const; + virtual ScMatrix* GetMatrix(); + virtual const ScComplexRefData& GetDoubleRef() const; + virtual ScComplexRefData& GetDoubleRef(); + virtual bool operator==( const formula::FormulaToken& rToken ) const; + virtual FormulaToken* Clone() const; +}; class ScExternalSingleRefToken : public ScToken { diff --git a/sc/inc/types.hxx b/sc/inc/types.hxx index 5c11da518976..f03ccc0149ec 100644 --- a/sc/inc/types.hxx +++ b/sc/inc/types.hxx @@ -63,6 +63,19 @@ enum GroupCalcState GroupCalcDisabled }; +struct RangeMatrix +{ + ScMatrixRef mpMat; + sal_Int32 mnCol1; + sal_Int32 mnRow1; + sal_Int32 mnCol2; + sal_Int32 mnRow2; + + RangeMatrix(); + + bool isRangeValid() const; +}; + } #endif diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx index da2f75bbb617..4f0b90e03139 100644 --- a/sc/source/core/data/formulacell.cxx +++ b/sc/source/core/data/formulacell.cxx @@ -3520,7 +3520,9 @@ bool ScFormulaCell::InterpretFormulaGroup() return false; } - if (mxGroup->mbInvariant) + // TODO : Disable invariant formula group interpretation for now in order + // to get implicit intersection to work. + if (mxGroup->mbInvariant && false) return InterpretInvariantFormulaGroup(); sc::FormulaGroupContext aCxt; diff --git a/sc/source/core/data/types.cxx b/sc/source/core/data/types.cxx new file mode 100644 index 000000000000..566d088ffe29 --- /dev/null +++ b/sc/source/core/data/types.cxx @@ -0,0 +1,24 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "types.hxx" +#include "scmatrix.hxx" + +namespace sc { + +RangeMatrix::RangeMatrix() : mpMat(NULL), mnCol1(-1), mnRow1(-1), mnCol2(-1), mnRow2(-1) {} + +bool RangeMatrix::isRangeValid() const +{ + return mnCol1 >= 0 && mnRow1 >= 0 && mnCol2 >= 0 && mnRow2 >= 0 && mnCol1 <= mnCol2 && mnRow1 <= mnRow2; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx index 8cf87b0bf9f6..bb9f9194aafb 100644 --- a/sc/source/core/inc/interpre.hxx +++ b/sc/source/core/inc/interpre.hxx @@ -51,6 +51,12 @@ class ScToken; class ScJumpMatrix; struct ScRefCellValue; +namespace sc { + +struct RangeMatrix; + +} + #define MAXSTACK (4096 / sizeof(formula::FormulaToken*)) class ScTokenStack @@ -298,6 +304,7 @@ inline void MatrixDoubleRefToMatrix(); // if MatrixFormula: PopDoubleRefPus // If MatrixFormula or ForceArray: ConvertMatrixParameters() inline bool MatrixParameterConversion(); ScMatrixRef PopMatrix(); +sc::RangeMatrix PopRangeMatrix(); void QueryMatrixType(ScMatrixRef& xMat, short& rRetTypeExpr, sal_uLong& rRetIndexExpr); void PushDouble(double nVal); @@ -338,6 +345,8 @@ ScMatrixRef CreateMatrixFromDoubleRef( const formula::FormulaToken* pToken, inline ScTokenMatrixMap& GetTokenMatrixMap(); ScTokenMatrixMap* CreateTokenMatrixMap(); ScMatrixRef GetMatrix(); +sc::RangeMatrix GetRangeMatrix(); + void ScTableOp(); // repeated operations void ScErrCell(); // special handling for // error cell @@ -373,7 +382,7 @@ double Compare(); /** @param pOptions NULL means case sensitivity document option is to be used! */ -ScMatrixRef CompareMat( ScCompareOptions* pOptions = NULL ); +sc::RangeMatrix CompareMat( ScCompareOptions* pOptions = NULL ); ScMatrixRef QueryMat( const ScMatrixRef& pMat, ScCompareOptions& rOptions ); void ScEqual(); void ScNotEqual(); diff --git a/sc/source/core/tool/formulagroup.cxx b/sc/source/core/tool/formulagroup.cxx index 4ac4b6be8112..40f4befe32d7 100644 --- a/sc/source/core/tool/formulagroup.cxx +++ b/sc/source/core/tool/formulagroup.cxx @@ -93,7 +93,11 @@ bool FormulaGroupInterpreterSoftware::interpret(ScDocument& rDoc, const ScAddres if (p2->IsStartFixed() && p2->IsEndFixed()) { // Cached the converted token for absolute range referene. - formula::FormulaTokenRef xTok(new ScMatrixToken(pMat)); + ScComplexRefData aRef; + ScRange aRefRange = rTopPos; + aRefRange.aEnd.SetRow(rTopPos.Row() + nRowEnd); + aRef.InitRange(aRefRange); + formula::FormulaTokenRef xTok(new ScMatrixRangeToken(pMat, aRef)); aCachedTokens.insert(CachedTokensType::value_type(p, xTok)); aCode2.AddToken(*xTok); } diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx index a4d0d55ad2cb..fb7b7dd2e99e 100644 --- a/sc/source/core/tool/interpr1.cxx +++ b/sc/source/core/tool/interpr1.cxx @@ -1081,11 +1081,11 @@ double ScInterpreter::Compare() } -ScMatrixRef ScInterpreter::CompareMat( ScCompareOptions* pOptions ) +sc::RangeMatrix ScInterpreter::CompareMat( ScCompareOptions* pOptions ) { String aVal1, aVal2; ScCompare aComp( &aVal1, &aVal2 ); - ScMatrixRef pMat[2]; + sc::RangeMatrix aMat[2]; ScAddress aAdr; for( short i = 1; i >= 0; i-- ) { @@ -1127,11 +1127,11 @@ ScMatrixRef ScInterpreter::CompareMat( ScCompareOptions* pOptions ) break; case svDoubleRef: case svMatrix: - pMat[ i ] = GetMatrix(); - if ( !pMat[ i ] ) + aMat[i] = GetRangeMatrix(); + if (!aMat[i].mpMat) SetError( errIllegalParameter); else - pMat[i]->SetErrorInterpreter( NULL); + aMat[i].mpMat->SetErrorInterpreter(NULL); // errors are transported as DoubleError inside matrix break; default: @@ -1139,82 +1139,88 @@ ScMatrixRef ScInterpreter::CompareMat( ScCompareOptions* pOptions ) break; } } - ScMatrixRef pResMat = NULL; + + sc::RangeMatrix aRes; if( !nGlobalError ) { - if ( pMat[0] && pMat[1] ) + if (aMat[0].mpMat && aMat[1].mpMat) { SCSIZE nC0, nC1; SCSIZE nR0, nR1; - pMat[0]->GetDimensions( nC0, nR0 ); - pMat[1]->GetDimensions( nC1, nR1 ); + aMat[0].mpMat->GetDimensions(nC0, nR0); + aMat[1].mpMat->GetDimensions(nC1, nR1); SCSIZE nC = std::max( nC0, nC1 ); SCSIZE nR = std::max( nR0, nR1 ); - pResMat = GetNewMat( nC, nR); - if ( !pResMat ) - return NULL; + aRes.mpMat = GetNewMat( nC, nR); + if (!aRes.mpMat) + return aRes; for ( SCSIZE j=0; j<nC; j++ ) { for ( SCSIZE k=0; k<nR; k++ ) { SCSIZE nCol = j, nRow = k; - if ( pMat[0]->ValidColRowOrReplicated( nCol, nRow ) && - pMat[1]->ValidColRowOrReplicated( nCol, nRow )) + if (aMat[0].mpMat->ValidColRowOrReplicated(nCol, nRow) && + aMat[1].mpMat->ValidColRowOrReplicated(nCol, nRow)) { for ( short i=1; i>=0; i-- ) { - if ( pMat[i]->IsString(j,k) ) + if (aMat[i].mpMat->IsString(j, k)) { aComp.bVal[i] = false; - *aComp.pVal[i] = pMat[i]->GetString(j,k); - aComp.bEmpty[i] = pMat[i]->IsEmpty(j,k); + *aComp.pVal[i] = aMat[i].mpMat->GetString(j, k); + aComp.bEmpty[i] = aMat[i].mpMat->IsEmpty(j, k); } else { aComp.bVal[i] = true; - aComp.nVal[i] = pMat[i]->GetDouble(j,k); + aComp.nVal[i] = aMat[i].mpMat->GetDouble(j, k); aComp.bEmpty[i] = false; } } - pResMat->PutDouble( CompareFunc( aComp, pOptions ), j,k ); + aRes.mpMat->PutDouble(CompareFunc(aComp, pOptions), j, k); } else - pResMat->PutString( ScGlobal::GetRscString(STR_NO_VALUE), j,k ); + aRes.mpMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), j, k); } } } - else if ( pMat[0] || pMat[1] ) + else if (aMat[0].mpMat || aMat[1].mpMat) { - short i = ( pMat[0] ? 0 : 1); + short i = ( aMat[0].mpMat ? 0 : 1); SCSIZE nC, nR; - pMat[i]->GetDimensions( nC, nR ); - pResMat = GetNewMat( nC, nR); - if ( !pResMat ) - return NULL; + aMat[i].mpMat->GetDimensions(nC, nR); + aRes.mpMat = GetNewMat( nC, nR); + if (!aRes.mpMat) + return aRes; + + aRes.mnCol1 = aMat[i].mnCol1; + aRes.mnRow1 = aMat[i].mnRow1; + aRes.mnCol2 = aMat[i].mnCol2; + aRes.mnRow2 = aMat[i].mnRow2; for (SCSIZE j = 0; j < nC; ++j) { for (SCSIZE k = 0; k < nR; ++k) { - if ( pMat[i]->IsValue(j,k) ) + if (aMat[i].mpMat->IsValue(j, k)) { aComp.bVal[i] = true; - aComp.nVal[i] = pMat[i]->GetDouble(j,k); + aComp.nVal[i] = aMat[i].mpMat->GetDouble(j, k); aComp.bEmpty[i] = false; } else { aComp.bVal[i] = false; - *aComp.pVal[i] = pMat[i]->GetString(j,k); - aComp.bEmpty[i] = pMat[i]->IsEmpty(j,k); + *aComp.pVal[i] = aMat[i].mpMat->GetString(j, k); + aComp.bEmpty[i] = aMat[i].mpMat->IsEmpty(j, k); } - pResMat->PutDouble( CompareFunc(aComp, pOptions), j, k); + aRes.mpMat->PutDouble(CompareFunc(aComp, pOptions), j, k); } } } } nCurFmtType = nFuncFmtType = NUMBERFORMAT_LOGICAL; - return pResMat; + return aRes; } @@ -1228,7 +1234,7 @@ ScMatrixRef ScInterpreter::QueryMat( const ScMatrixRef& pMat, ScCompareOptions& PushString(rItem.maString); else PushDouble(rItem.mfVal); - ScMatrixRef pResultMatrix = CompareMat( &rOptions); + ScMatrixRef pResultMatrix = CompareMat( &rOptions).mpMat; nCurFmtType = nSaveCurFmtType; nFuncFmtType = nSaveFuncFmtType; if (nGlobalError || !pResultMatrix) @@ -1264,19 +1270,56 @@ ScMatrixRef ScInterpreter::QueryMat( const ScMatrixRef& pMat, ScCompareOptions& return pResultMatrix; } +namespace { + +double applyImplicitIntersection(const sc::RangeMatrix& rMat, const ScAddress& rPos) +{ + if (rMat.mnRow1 <= rPos.Row() && rPos.Row() <= rMat.mnRow2 && rMat.mnCol1 == rMat.mnCol2) + { + SCROW nOffset = rPos.Row() - rMat.mnRow1; + return rMat.mpMat->GetDouble(0, nOffset); + } + + if (rMat.mnCol1 <= rPos.Col() && rPos.Col() <= rMat.mnCol2 && rMat.mnRow1 == rMat.mnRow2) + { + SCROW nOffset = rPos.Col() - rMat.mnCol1; + return rMat.mpMat->GetDouble(nOffset, 0); + } + + double fVal; + rtl::math::setNan(&fVal); + return fVal; +} + +} void ScInterpreter::ScEqual() { if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix ) { - ScMatrixRef pMat = CompareMat(); - if ( !pMat ) + sc::RangeMatrix aMat = CompareMat(); + if (!aMat.mpMat) + { PushIllegalParameter(); - else + return; + } + + if (aMat.isRangeValid()) { - pMat->CompareEqual(); - PushMatrix( pMat ); + // This matrix represents a range reference. Apply implicit intersection. + double fVal = applyImplicitIntersection(aMat, aPos); + if (rtl::math::isNan(fVal)) + { + PushError(errCellNoValue); + return; + } + + PushInt(fVal == 0.0); + return; } + + aMat.mpMat->CompareEqual(); + PushMatrix(aMat.mpMat); } else PushInt( Compare() == 0 ); @@ -1287,14 +1330,29 @@ void ScInterpreter::ScNotEqual() { if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix ) { - ScMatrixRef pMat = CompareMat(); - if ( !pMat ) + sc::RangeMatrix aMat = CompareMat(); + if (!aMat.mpMat) + { PushIllegalParameter(); - else + return; + } + + if (aMat.isRangeValid()) { - pMat->CompareNotEqual(); - PushMatrix( pMat ); + // This matrix represents a range reference. Apply implicit intersection. + double fVal = applyImplicitIntersection(aMat, aPos); + if (rtl::math::isNan(fVal)) + { + PushError(errCellNoValue); + return; + } + + PushInt(fVal != 0.0); + return; } + + aMat.mpMat->CompareNotEqual(); + PushMatrix(aMat.mpMat); } else PushInt( Compare() != 0 ); @@ -1305,14 +1363,29 @@ void ScInterpreter::ScLess() { if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix ) { - ScMatrixRef pMat = CompareMat(); - if ( !pMat ) + sc::RangeMatrix aMat = CompareMat(); + if (!aMat.mpMat) + { PushIllegalParameter(); - else + return; + } + + if (aMat.isRangeValid()) { - pMat->CompareLess(); - PushMatrix( pMat ); + // This matrix represents a range reference. Apply implicit intersection. + double fVal = applyImplicitIntersection(aMat, aPos); + if (rtl::math::isNan(fVal)) + { + PushError(errCellNoValue); + return; + } + + PushInt(fVal < 0.0); + return; } + + aMat.mpMat->CompareLess(); + PushMatrix(aMat.mpMat); } else PushInt( Compare() < 0 ); @@ -1323,14 +1396,29 @@ void ScInterpreter::ScGreater() { if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix ) { - ScMatrixRef pMat = CompareMat(); - if ( !pMat ) + sc::RangeMatrix aMat = CompareMat(); + if (!aMat.mpMat) + { PushIllegalParameter(); - else + return; + } + + if (aMat.isRangeValid()) { - pMat->CompareGreater(); - PushMatrix( pMat ); + // This matrix represents a range reference. Apply implicit intersection. + double fVal = applyImplicitIntersection(aMat, aPos); + if (rtl::math::isNan(fVal)) + { + PushError(errCellNoValue); + return; + } + + PushInt(fVal > 0.0); + return; } + + aMat.mpMat->CompareGreater(); + PushMatrix(aMat.mpMat); } else PushInt( Compare() > 0 ); @@ -1341,14 +1429,29 @@ void ScInterpreter::ScLessEqual() { if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix ) { - ScMatrixRef pMat = CompareMat(); - if ( !pMat ) + sc::RangeMatrix aMat = CompareMat(); + if (!aMat.mpMat) + { PushIllegalParameter(); - else + return; + } + + if (aMat.isRangeValid()) { - pMat->CompareLessEqual(); - PushMatrix( pMat ); + // This matrix represents a range reference. Apply implicit intersection. + double fVal = applyImplicitIntersection(aMat, aPos); + if (rtl::math::isNan(fVal)) + { + PushError(errCellNoValue); + return; + } + + PushInt(fVal <= 0.0); + return; } + + aMat.mpMat->CompareLessEqual(); + PushMatrix(aMat.mpMat); } else PushInt( Compare() <= 0 ); @@ -1359,14 +1462,29 @@ void ScInterpreter::ScGreaterEqual() { if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix ) { - ScMatrixRef pMat = CompareMat(); - if ( !pMat ) + sc::RangeMatrix aMat = CompareMat(); + if (!aMat.mpMat) + { PushIllegalParameter(); - else + return; + } + + if (aMat.isRangeValid()) { - pMat->CompareGreaterEqual(); - PushMatrix( pMat ); + // This matrix represents a range reference. Apply implicit intersection. + double fVal = applyImplicitIntersection(aMat, aPos); + if (rtl::math::isNan(fVal)) + { + PushError(errCellNoValue); + return; + } + + PushInt(fVal >= 0.0); + return; } + + aMat.mpMat->CompareGreaterEqual(); + PushMatrix(aMat.mpMat); } else PushInt( Compare() >= 0 ); diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index c6025d4bde7d..7beb5804575a 100644 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -1794,6 +1794,45 @@ ScMatrixRef ScInterpreter::PopMatrix() return NULL; } +sc::RangeMatrix ScInterpreter::PopRangeMatrix() +{ + sc::RangeMatrix aRet; + if (sp) + { + switch (pStack[sp-1]->GetType()) + { + case svMatrix: + { + --sp; + FormulaToken* p = pStack[sp]; + ScToken* p2 = static_cast<ScToken*>(p); + aRet.mpMat = p2->GetMatrix(); + if (aRet.mpMat) + { + aRet.mpMat->SetErrorInterpreter(this); + if (p2->GetByte() == MATRIX_TOKEN_HAS_RANGE) + { + const ScComplexRefData& rRef = p2->GetDoubleRef(); + if (!rRef.Ref1.IsColRel() && !rRef.Ref1.IsRowRel() && !rRef.Ref2.IsColRel() && !rRef.Ref2.IsRowRel()) + { + aRet.mnCol1 = rRef.Ref1.Col(); + aRet.mnRow1 = rRef.Ref1.Row(); + aRet.mnCol2 = rRef.Ref2.Col(); + aRet.mnRow2 = rRef.Ref2.Row(); + } + } + } + else + SetError( errUnknownVariable); + } + break; + default: + aRet.mpMat = PopMatrix(); + } + } + return aRet; +} + void ScInterpreter::QueryMatrixType(ScMatrixRef& xMat, short& rRetTypeExpr, sal_uLong& rRetIndexExpr) { if (xMat) diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx index ad7d799cd075..a033693d5c9c 100644 --- a/sc/source/core/tool/interpr5.cxx +++ b/sc/source/core/tool/interpr5.cxx @@ -494,6 +494,20 @@ ScMatrixRef ScInterpreter::GetMatrix() return pMat; } +sc::RangeMatrix ScInterpreter::GetRangeMatrix() +{ + sc::RangeMatrix aRet; + switch (GetRawStackType()) + { + case svMatrix: + aRet = PopRangeMatrix(); + break; + default: + aRet.mpMat = GetMatrix(); + } + return aRet; +} + void ScInterpreter::ScMatValue() { if ( MustHaveParamCount( GetByte(), 3 ) ) diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index e5627ff5a0d6..9f5a7e6bf752 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -804,6 +804,47 @@ bool ScMatrixToken::operator==( const FormulaToken& r ) const return FormulaToken::operator==( r ) && pMatrix == static_cast<const ScToken&>(r).GetMatrix(); } +ScMatrixRangeToken::ScMatrixRangeToken( const ScMatrixRef& p, const ScComplexRefData& rRef ) : + ScToken(formula::svMatrix), mpMatrix(p), maRef(rRef) {} + +ScMatrixRangeToken::ScMatrixRangeToken( const ScMatrixRangeToken& r ) : + ScToken(r), mpMatrix(r.mpMatrix), maRef(r.maRef) {} + +sal_uInt8 ScMatrixRangeToken::GetByte() const +{ + return MATRIX_TOKEN_HAS_RANGE; +} + +const ScMatrix* ScMatrixRangeToken::GetMatrix() const +{ + return mpMatrix.get(); +} + +ScMatrix* ScMatrixRangeToken::GetMatrix() +{ + return mpMatrix.get(); +} + +const ScComplexRefData& ScMatrixRangeToken::GetDoubleRef() const +{ + return maRef; +} + +ScComplexRefData& ScMatrixRangeToken::GetDoubleRef() +{ + return maRef; +} + +bool ScMatrixRangeToken::operator==( const FormulaToken& r ) const +{ + return FormulaToken::operator==(r) && mpMatrix == static_cast<const ScToken&>(r).GetMatrix(); +} + +FormulaToken* ScMatrixRangeToken::Clone() const +{ + return new ScMatrixRangeToken(*this); +} + // ============================================================================ ScExternalSingleRefToken::ScExternalSingleRefToken( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& r ) : |