formula/source/core/api/token.cxx | 5 + include/formula/tokenarray.hxx | 11 +++ sc/qa/unit/data/ods/shared-formula/column-row-labels.ods |binary sc/qa/unit/subsequent_filters-test.cxx | 50 ++++++++++++--- sc/source/core/data/formulacell.cxx | 5 + sc/source/core/tool/compiler.cxx | 26 ++++++- sc/source/core/tool/token.cxx | 1 7 files changed, 81 insertions(+), 17 deletions(-)
New commits: commit 42062d99f171196778685e655e4edafd33ac159f Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Tue Oct 18 18:16:42 2016 -0400 tdf#93894: Write a new test case for column and row labels combined. Change-Id: I76e1f6f3c3aed9d940e4433026f752f3630f2373 diff --git a/sc/qa/unit/data/ods/shared-formula/column-row-labels.ods b/sc/qa/unit/data/ods/shared-formula/column-row-labels.ods new file mode 100644 index 0000000..02f711b Binary files /dev/null and b/sc/qa/unit/data/ods/shared-formula/column-row-labels.ods differ diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx index bc82fb9..78724f8 100644 --- a/sc/qa/unit/subsequent_filters-test.cxx +++ b/sc/qa/unit/subsequent_filters-test.cxx @@ -221,6 +221,7 @@ public: void testSharedFormulaXLSB(); void testSharedFormulaXLS(); void testSharedFormulaColumnLabelsODS(); + void testSharedFormulaColumnRowLabelsODS(); void testExternalRefCacheXLSX(); void testExternalRefCacheODS(); void testHybridSharedStringODS(); @@ -333,6 +334,7 @@ public: CPPUNIT_TEST(testSharedFormulaXLSB); CPPUNIT_TEST(testSharedFormulaXLS); CPPUNIT_TEST(testSharedFormulaColumnLabelsODS); + CPPUNIT_TEST(testSharedFormulaColumnRowLabelsODS); CPPUNIT_TEST(testExternalRefCacheXLSX); CPPUNIT_TEST(testExternalRefCacheODS); CPPUNIT_TEST(testHybridSharedStringODS); @@ -3470,6 +3472,45 @@ void ScFiltersTest::testSharedFormulaColumnLabelsODS() xDocSh->DoClose(); } +void ScFiltersTest::testSharedFormulaColumnRowLabelsODS() +{ + ScDocShellRef xDocSh = loadDoc("shared-formula/column-row-labels.", FORMAT_ODS); + + CPPUNIT_ASSERT(xDocSh.Is()); + ScDocument& rDoc = xDocSh->GetDocument(); + rDoc.CalcAll(); + + // Expected output in each of the three ranges. + // + // +---+---+---+ + // | 1 | 4 | 7 | + // +---+---+---+ + // | 2 | 5 | 8 | + // +---+---+---+ + // | 3 | 6 | 9 | + // +---+---+---+ + + auto aCheckFunc = [&](SCCOL nStartCol, SCROW nStartRow) + { + double fExpected = 1.0; + for (SCCOL nCol = 0; nCol <= 2; ++nCol) + { + for (SCROW nRow = 0; nRow <= 2; ++nRow) + { + ScAddress aPos(nStartCol+nCol, nStartRow+nRow, 0); + CPPUNIT_ASSERT_EQUAL(fExpected, rDoc.GetValue(aPos)); + fExpected += 1.0; + } + } + }; + + aCheckFunc(5, 1); // F2:H4 + aCheckFunc(9, 1); // J2:L4 + aCheckFunc(1, 6); // B7:D9 + + xDocSh->DoClose(); +} + void ScFiltersTest::testExternalRefCacheXLSX() { ScDocShellRef xDocSh = loadDoc("external-refs.", FORMAT_XLSX); commit 2b32042294a497f9e387348faf20fcdcb0c0fd7a Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Tue Oct 18 17:51:02 2016 -0400 tdf#93894: These assumptions no longer hold. Since we've switched to not grouping formulas with column / row labels. Change-Id: I0097a5103b5dfaa5b021ee76545beb9f24ac7bd3 diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx index 8088e71..bc82fb9 100644 --- a/sc/qa/unit/subsequent_filters-test.cxx +++ b/sc/qa/unit/subsequent_filters-test.cxx @@ -3449,15 +3449,6 @@ void ScFiltersTest::testSharedFormulaColumnLabelsODS() ScDocument& rDoc = xDocSh->GetDocument(); rDoc.CalcAll(); - // Cells C2, D2 and E2 all should contain formula groups of length 5. - for (SCCOL i = 2; i <= 4; ++i) - { - const ScFormulaCell* pCell = rDoc.GetFormulaCell(ScAddress(i,1,0)); - CPPUNIT_ASSERT(pCell); - CPPUNIT_ASSERT(pCell->IsSharedTop()); - CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(5), pCell->GetSharedLength()); - } - CPPUNIT_ASSERT_EQUAL( 5.0, rDoc.GetValue(ScAddress(2,1,0))); CPPUNIT_ASSERT_EQUAL(15.0, rDoc.GetValue(ScAddress(2,2,0))); CPPUNIT_ASSERT_EQUAL(30.0, rDoc.GetValue(ScAddress(2,3,0))); commit e944d9510404d8c67b3867d7cd9f313fd5091004 Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Mon Oct 17 23:19:23 2016 -0400 tdf#93894: Prohibit grouping when certain token types are present. For instance, column / row label tokens don't work correctly in grouped cells with the current implementation. Change-Id: Idf86312ef15fbfd4382aa90ee6d131c671a80683 diff --git a/formula/source/core/api/token.cxx b/formula/source/core/api/token.cxx index a9abdd0..7c85b15 100644 --- a/formula/source/core/api/token.cxx +++ b/formula/source/core/api/token.cxx @@ -723,7 +723,8 @@ FormulaTokenArray::FormulaTokenArray() : nError(FormulaError::NONE), nMode(ScRecalcMode::NORMAL), bHyperLink(false), - mbFromRangeName(false) + mbFromRangeName(false), + mbShareable(true) { } @@ -746,6 +747,7 @@ void FormulaTokenArray::Assign( const FormulaTokenArray& r ) nMode = r.nMode; bHyperLink = r.bHyperLink; mbFromRangeName = r.mbFromRangeName; + mbShareable = r.mbShareable; pCode = nullptr; pRPN = nullptr; FormulaToken** pp; @@ -807,6 +809,7 @@ void FormulaTokenArray::Clear() nLen = nIndex = nRPN = 0; bHyperLink = false; mbFromRangeName = false; + mbShareable = true; ClearRecalcMode(); } diff --git a/include/formula/tokenarray.hxx b/include/formula/tokenarray.hxx index 1c6ed22..cdb4e34 100644 --- a/include/formula/tokenarray.hxx +++ b/include/formula/tokenarray.hxx @@ -127,6 +127,7 @@ protected: ScRecalcMode nMode; // Flags to indicate when to recalc this code bool bHyperLink; // If HYPERLINK() occurs in the formula. bool mbFromRangeName; // If this array originates from a named expression + bool mbShareable; // Whether or not it can be shared with adjacent cells. protected: void Assign( const FormulaTokenArray& ); @@ -190,6 +191,16 @@ public: void SetFromRangeName( bool b ) { mbFromRangeName = b; } bool IsFromRangeName() const { return mbFromRangeName; } + void SetShareable( bool b ) { mbShareable = b; } + + /** + * Check if this token array is shareable between multiple adjacent + * formula cells. Certain tokens may not function correctly when shared. + * + * @return true if the token array is shareable, false otherwise. + */ + bool IsShareable() const { return mbShareable; } + void Clear(); void DelRPN(); FormulaToken* First() { nIndex = 0; return Next(); } diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx index de5fc68..7ca01db 100644 --- a/sc/source/core/data/formulacell.cxx +++ b/sc/source/core/data/formulacell.cxx @@ -1299,7 +1299,7 @@ void ScFormulaCell::CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rPr ScAddress aPreviousCell( aPos ); aPreviousCell.IncRow( -1 ); ScFormulaCell *pPreviousCell = pDocument->GetFormulaCell( aPreviousCell ); - if( pPreviousCell ) + if (pPreviousCell && pPreviousCell->GetCode()->IsShareable()) { // Build formula string using the tokens from the previous cell, // but use the current cell position. @@ -3827,6 +3827,9 @@ ScFormulaCell::CompareState ScFormulaCell::CompareByTokenArray( ScFormulaCell& r if ( GetHash() != rOther.GetHash() ) return NotEqual; + if (!pCode->IsShareable() || !rOther.pCode->IsShareable()) + return NotEqual; + FormulaToken **pThis = pCode->GetCode(); sal_uInt16 nThisLen = pCode->GetCodeLen(); FormulaToken **pOther = rOther.pCode->GetCode(); diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx index fa117a0..2c7ff4d 100644 --- a/sc/source/core/tool/compiler.cxx +++ b/sc/source/core/tool/compiler.cxx @@ -4470,6 +4470,12 @@ ScTokenArray* ScCompiler::CompileString( const OUString& rFormula ) --nFunction; } break; + case ocColRowName: + case ocColRowNameAuto: + // The current implementation of column / row labels doesn't + // function correctly in grouped cells. + aArr.SetShareable(false); + break; default: break; } @@ -5359,8 +5365,10 @@ bool ScCompiler::HandleColRowName() { ScSingleRefData aRefData; aRefData.InitAddress( aRange.aStart ); - aRefData.SetColRel( true ); - aRefData.SetRowRel( true ); + if ( bColName ) + aRefData.SetColRel( true ); + else + aRefData.SetRowRel( true ); aRefData.SetAddress(aRange.aStart, aPos); pNew->AddSingleReference( aRefData ); } @@ -5368,10 +5376,16 @@ bool ScCompiler::HandleColRowName() { ScComplexRefData aRefData; aRefData.InitRange( aRange ); - aRefData.Ref1.SetColRel( true ); - aRefData.Ref2.SetColRel( true ); - aRefData.Ref1.SetRowRel( true ); - aRefData.Ref2.SetRowRel( true ); + if ( bColName ) + { + aRefData.Ref1.SetColRel( true ); + aRefData.Ref2.SetColRel( true ); + } + else + { + aRefData.Ref1.SetRowRel( true ); + aRefData.Ref2.SetRowRel( true ); + } aRefData.SetRange(aRange, aPos); if ( bInList ) pNew->AddDoubleReference( aRefData ); diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index 44dbe38..c5bac8d 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -1796,6 +1796,7 @@ ScTokenArray* ScTokenArray::Clone() const p->mnHashValue = mnHashValue; p->meVectorState = meVectorState; p->mbFromRangeName = mbFromRangeName; + p->mbShareable = mbShareable; FormulaToken** pp; if( nLen ) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits