[Libreoffice-commits] core.git: 3 commits - formula/source include/formula sc/qa sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Wed Oct 19 00:28:48 UTC 2016


 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.yoshida at 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.yoshida at 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.yoshida at 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 )


More information about the Libreoffice-commits mailing list