[Libreoffice-commits] core.git: Branch 'libreoffice-5-0' - 7 commits - sc/qa sc/source

Eike Rathke erack at redhat.com
Sun Jun 21 10:23:03 PDT 2015


 sc/qa/unit/ucalc.hxx             |    2 
 sc/qa/unit/ucalc_formula.cxx     |  115 +++++++++++++++++++++++++++++++++++++++
 sc/source/core/tool/compiler.cxx |   35 +++++------
 sc/source/core/tool/token.cxx    |   12 +---
 4 files changed, 136 insertions(+), 28 deletions(-)

New commits:
commit bf73c22c2110c8ca29e7a00e02d293a85e5db70e
Author: Eike Rathke <erack at redhat.com>
Date:   Sun Jun 21 18:23:54 2015 +0200

    unit test for adjustSingleRefInName() during column insertion
    
    Change-Id: Ie406361c3a3497619f4faf3680f389f3bdf76a4b
    (cherry picked from commit 8ade7dce21143cd280935b174f4359d3d6d6d20b)

diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx
index 487981a..08026cb 100644
--- a/sc/qa/unit/ucalc_formula.cxx
+++ b/sc/qa/unit/ucalc_formula.cxx
@@ -1704,6 +1704,11 @@ void Test::testFormulaRefUpdateInsertColumns()
 
     m_pDoc->InsertTab(0, "Formula");
 
+    // Set named range for B2 with absolute column and relative same row.
+    const ScAddress aNamePos(0,1,0);
+    bool bInserted = m_pDoc->InsertNewRangeName("RowRelativeRange", aNamePos, "$Formula.$B2");
+    CPPUNIT_ASSERT(bInserted);
+
     // Set values in B1:B3.
     m_pDoc->SetValue(ScAddress(1,0,0), 1.0);
     m_pDoc->SetValue(ScAddress(1,1,0), 2.0);
@@ -1713,6 +1718,10 @@ void Test::testFormulaRefUpdateInsertColumns()
     m_pDoc->SetString(ScAddress(1,3,0), "=SUM(B1:B3)");
     CPPUNIT_ASSERT_EQUAL(6.0, m_pDoc->GetValue(ScAddress(1,3,0)));
 
+    // Use named range in C2 to reference B2.
+    m_pDoc->SetString(ScAddress(2,1,0), "=RowRelativeRange");
+    CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(2,1,0)));
+
     // Inert columns over A:B.
     ScMarkData aMark;
     aMark.SelectOneTable(0);
@@ -1725,6 +1734,18 @@ void Test::testFormulaRefUpdateInsertColumns()
 
     CPPUNIT_ASSERT_EQUAL(6.0, m_pDoc->GetValue(ScAddress(3,3,0)));
 
+    // Check that the named reference points to the moved cell, now D2.
+    ScRangeData* pName = m_pDoc->GetRangeName()->findByUpperName("ROWRELATIVERANGE");
+    CPPUNIT_ASSERT(pName);
+    OUString aSymbol;
+    pName->GetSymbol(aSymbol, aNamePos, formula::FormulaGrammar::GRAM_ENGLISH);
+    CPPUNIT_ASSERT_EQUAL(OUString("$Formula.$D2"), aSymbol);
+
+    // Check that the formula using the name, now in E2, still has the same result.
+    if (!checkFormula(*m_pDoc, ScAddress(4,1,0), "RowRelativeRange"))
+        CPPUNIT_FAIL("Wrong formula in E2 after column insertion.");
+    CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(4,1,0)));
+
     m_pDoc->DeleteTab(0);
 }
 
commit e6080277c586dbc9f02b9893dd561e98d76027ba
Author: Eike Rathke <erack at redhat.com>
Date:   Sun Jun 21 17:50:10 2015 +0200

    adjustSingleRefInName() handle relative column and row independently
    
    The absolute part needs to be adjusted when the referenced column or row
    is moved, even if the other part is relative.
    
    Change-Id: Ibd6c2f58b7e01ced4d2e521f29295c044d27924a
    (cherry picked from commit f35673a825ecd4c4b331302c0408c65b9906f97f)

diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 07b121c..8be2390 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -3227,18 +3227,12 @@ bool adjustSingleRefInName(
         return false;
     }
 
-    if (rRef.IsColRel() || rRef.IsRowRel())
-    {
-        // Adjust references only when both column and row are absolute.
-        return false;
-    }
-
     if (!rCxt.maRange.In(rRef.toAbs(rPos)))
         return false;
 
     bool bChanged = false;
 
-    if (rCxt.mnColDelta)
+    if (rCxt.mnColDelta && !rRef.IsColRel())
     {
         // Adjust absolute column reference.
         if (rCxt.maRange.aStart.Col() <= rRef.Col() && rRef.Col() <= rCxt.maRange.aEnd.Col())
@@ -3248,7 +3242,7 @@ bool adjustSingleRefInName(
         }
     }
 
-    if (rCxt.mnRowDelta)
+    if (rCxt.mnRowDelta && !rRef.IsRowRel())
     {
         // Adjust absolute row reference.
         if (rCxt.maRange.aStart.Row() <= rRef.Row() && rRef.Row() <= rCxt.maRange.aEnd.Row())
commit 17cffd941e34808f311e6ebb4014759ef59308c1
Author: Eike Rathke <erack at redhat.com>
Date:   Sun Jun 21 00:14:41 2015 +0200

    TableRef: clone inner reference token in copy-ctor
    
    Change-Id: I4d195932bf81c105197de64cc592894e2492b801
    (cherry picked from commit 6a3c3673d2d50cc42c1b92a841306232a8cf022f)

diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 00f1d45..07b121c 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -892,7 +892,7 @@ ScTableRefToken::ScTableRefToken( sal_uInt16 nIndex, ScTableRefToken::Item eItem
 
 ScTableRefToken::ScTableRefToken( const ScTableRefToken& r ) :
     FormulaToken(r),
-    mxAreaRefRPN(r.mxAreaRefRPN),
+    mxAreaRefRPN(r.mxAreaRefRPN->Clone()),
     mnIndex(r.mnIndex),
     meItem(r.meItem)
 {
commit 3f2c50d0532746a6cd207e3cb91981ed0ba618e9
Author: Eike Rathke <erack at redhat.com>
Date:   Sat Jun 20 00:37:54 2015 +0200

    TableRef: sheet reference always absolute and 3D
    
    Change-Id: I17a2889c21efe9943b348049a1e9384df167435d
    (cherry picked from commit 9e978e58650c18500aaea6e2e927d5439c65917f)

diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 23b9d9f..64a7d61 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -5203,12 +5203,7 @@ bool ScCompiler::HandleTableRef()
                     {
                         aRefData.SetRowRel( true);
                     }
-                    if (aRange.aStart.Tab() != aPos.Tab())
-                        aRefData.SetFlag3D( true);
-                    else
-                    {
-                        aRefData.SetTabRel( true);
-                    }
+                    aRefData.SetFlag3D( true);
                     aRefData.SetAddress( aRange.aStart, aPos);
                     pTR->SetAreaRefRPN( pNew->AddSingleReference( aRefData ));
                 }
@@ -5223,13 +5218,7 @@ bool ScCompiler::HandleTableRef()
                         aRefData.Ref1.SetRowRel( true);
                         aRefData.Ref2.SetRowRel( true);
                     }
-                    if (aRange.aStart.Tab() != aPos.Tab())
-                        aRefData.Ref1.SetFlag3D( true);
-                    else
-                    {
-                        aRefData.Ref1.SetTabRel( true);
-                        aRefData.Ref2.SetTabRel( true);
-                    }
+                    aRefData.Ref1.SetFlag3D( true);
                     aRefData.SetRange( aRange, aPos);
                     pTR->SetAreaRefRPN( pNew->AddDoubleReference( aRefData ));
                 }
commit d461f601f49abfd47ae398388b70c4e10ffbbc2f
Author: Eike Rathke <erack at redhat.com>
Date:   Fri Jun 19 23:57:43 2015 +0200

    TableRef: generated reference's column relativity follows column specifier
    
    Change-Id: Ie0781bf5ebeb4cec0e3bb96f8c471e469b1b223a
    (cherry picked from commit afa74bb6e8b828bdc08b8b214bce9c9c3797abdb)

diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 662b6fd..23b9d9f 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -5079,6 +5079,8 @@ bool ScCompiler::HandleTableRef()
                 break;
         }
         bool bColumnRange = false;
+        bool bCol1Rel = false;
+        bool bCol2Rel = false;
         int nLevel = 0;
         if (bForwardToClose && GetTokenIfOpCode( ocTableRefOpen))
         {
@@ -5128,6 +5130,7 @@ bool ScCompiler::HandleTableRef()
                             if (eState == sOpen && p->GetType() == svSingleRef)
                             {
                                 bColumnRange = true;
+                                bCol1Rel = p->GetSingleRef()->IsColRel();
                                 eState = sLast;
                             }
                             else
@@ -5173,6 +5176,7 @@ bool ScCompiler::HandleTableRef()
                                 {
                                     aColRange.aEnd = mpToken->GetSingleRef()->toAbs( aPos);
                                     aColRange.Justify();
+                                    bCol2Rel = mpToken->GetSingleRef()->IsColRel();
                                 }
                             }
                         }
@@ -5194,7 +5198,7 @@ bool ScCompiler::HandleTableRef()
                 {
                     ScSingleRefData aRefData;
                     aRefData.InitFlags();
-                    aRefData.SetColRel( true);
+                    aRefData.SetColRel( bCol1Rel);
                     if (eItem == ScTableRefToken::THIS_ROW)
                     {
                         aRefData.SetRowRel( true);
@@ -5212,8 +5216,8 @@ bool ScCompiler::HandleTableRef()
                 {
                     ScComplexRefData aRefData;
                     aRefData.InitFlags();
-                    aRefData.Ref1.SetColRel( true);
-                    aRefData.Ref2.SetColRel( true);
+                    aRefData.Ref1.SetColRel( bCol1Rel);
+                    aRefData.Ref2.SetColRel( bCol2Rel);
                     if (eItem == ScTableRefToken::THIS_ROW)
                     {
                         aRefData.Ref1.SetRowRel( true);
commit 85b7436b2c2060bb1168cc37eee537de417795e0
Author: Eike Rathke <erack at redhat.com>
Date:   Fri Jun 19 22:49:50 2015 +0200

    TableRef: column specifier is an absolute reference
    
    Change-Id: Ia7de5dc101a410aa1c25f36e64627fa3461ee772
    (cherry picked from commit 2a5f48f7f48804d5ac7d67c5a4f3f28315815a7a)

diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 82fd38e..662b6fd 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -3451,10 +3451,14 @@ bool ScCompiler::IsTableRefColumn( const OUString& rName ) const
             OUString aStr = aIter.getString();
             if (ScGlobal::GetpTransliteration()->isEqual( aStr, aName))
             {
+                /* XXX NOTE: we could init the column as relative so copying a
+                 * formula across columns would point to the relative column,
+                 * but do it absolute because:
+                 * a) it makes the reference work in named expressions without
+                 * having to distinguish
+                 * b) Excel does it the same. */
                 ScSingleRefData aRef;
-                aRef.InitFlags();
-                aRef.SetColRel( true );
-                aRef.SetAddress( aIter.GetPos(), aPos);
+                aRef.InitAddress( aIter.GetPos());
                 maRawToken.SetSingleReference( aRef );
                 return true;
             }
commit 0cae2d3719403cf7266f1c5da9c5ee1e3977a7ca
Author: Eike Rathke <erack at redhat.com>
Date:   Fri Jun 19 16:49:29 2015 +0200

    add unit test for ocRangeOp and ScComplexRefData::Extend()
    
    Change-Id: Iae97c409a84f47d591ef8adf8e42fb6f52c104e2
    (cherry picked from commit 72be3521524f1c01842010f26c234f4e6cceb358)

diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx
index afc4d0a..da56b73 100644
--- a/sc/qa/unit/ucalc.hxx
+++ b/sc/qa/unit/ucalc.hxx
@@ -179,6 +179,7 @@ public:
     void testFuncGETPIVOTDATA();
     void testFuncGETPIVOTDATALeafAccess();
     void testMatrixOp();
+    void testFuncRangeOp();
 
     void testExternalRef();
     void testExternalRefFunctions();
@@ -501,6 +502,7 @@ public:
     CPPUNIT_TEST(testFuncGETPIVOTDATA);
     CPPUNIT_TEST(testFuncGETPIVOTDATALeafAccess);
     CPPUNIT_TEST(testMatrixOp);
+    CPPUNIT_TEST(testFuncRangeOp);
     CPPUNIT_TEST(testExternalRef);
     CPPUNIT_TEST(testExternalRefFunctions);
     CPPUNIT_TEST(testCopyToDocument);
diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx
index 09ac70d..487981a 100644
--- a/sc/qa/unit/ucalc_formula.cxx
+++ b/sc/qa/unit/ucalc_formula.cxx
@@ -4972,4 +4972,98 @@ void Test::testMatrixOp()
     m_pDoc->DeleteTab(0);
 }
 
+void Test::testFuncRangeOp()
+{
+    sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn on auto calc.
+
+    m_pDoc->InsertTab(0, "Sheet1");
+    m_pDoc->InsertTab(1, "Sheet2");
+    m_pDoc->InsertTab(2, "Sheet3");
+
+    // Sheet1.B1:B3
+    m_pDoc->SetValue(1,0,0, 1.0);
+    m_pDoc->SetValue(1,1,0, 2.0);
+    m_pDoc->SetValue(1,2,0, 4.0);
+    // Sheet2.B1:B3
+    m_pDoc->SetValue(1,0,1, 8.0);
+    m_pDoc->SetValue(1,1,1, 16.0);
+    m_pDoc->SetValue(1,2,1, 32.0);
+    // Sheet3.B1:B3
+    m_pDoc->SetValue(1,0,2, 64.0);
+    m_pDoc->SetValue(1,1,2, 128.0);
+    m_pDoc->SetValue(1,2,2, 256.0);
+
+    // Range operator should extend concatenated literal references during
+    // parse time already, so with this we can test ScComplexRefData::Extend()
+
+    // Current sheet is Sheet1, so B1:B2 implies relative Sheet1.B1:B2
+
+    ScAddress aPos(0,0,0);
+    m_pDoc->SetString( aPos, "=SUM(B1:B2:B3)");
+    if (!checkFormula( *m_pDoc, aPos, "SUM(B1:B3)"))
+        CPPUNIT_FAIL("Wrong formula.");
+    CPPUNIT_ASSERT_EQUAL( 7.0, m_pDoc->GetValue(aPos));
+
+    aPos.IncRow();
+    m_pDoc->SetString( aPos, "=SUM(B1:B3:B2)");
+    if (!checkFormula( *m_pDoc, aPos, "SUM(B1:B3)"))
+        CPPUNIT_FAIL("Wrong formula.");
+    CPPUNIT_ASSERT_EQUAL( 7.0, m_pDoc->GetValue(aPos));
+
+    aPos.IncRow();
+    m_pDoc->SetString( aPos, "=SUM(B2:B3:B1)");
+    if (!checkFormula( *m_pDoc, aPos, "SUM(B1:B3)"))
+        CPPUNIT_FAIL("Wrong formula.");
+    CPPUNIT_ASSERT_EQUAL( 7.0, m_pDoc->GetValue(aPos));
+
+    aPos.IncRow();
+    m_pDoc->SetString( aPos, "=SUM(Sheet2.B1:B2:B3)");
+    if (!checkFormula( *m_pDoc, aPos, "SUM(Sheet2.B1:B3)"))
+        CPPUNIT_FAIL("Wrong formula.");
+    CPPUNIT_ASSERT_EQUAL( 56.0, m_pDoc->GetValue(aPos));
+
+    aPos.IncRow();
+    m_pDoc->SetString( aPos, "=SUM(B2:B2:Sheet1.B2)");
+    if (!checkFormula( *m_pDoc, aPos, "SUM(Sheet1.B2:B2)"))
+        CPPUNIT_FAIL("Wrong formula.");
+    CPPUNIT_ASSERT_EQUAL( 2.0, m_pDoc->GetValue(aPos));
+
+    aPos.IncRow();
+    m_pDoc->SetString( aPos, "=SUM(B2:B3:Sheet2.B1)");
+    if (!checkFormula( *m_pDoc, aPos, "SUM(Sheet1.B1:Sheet2.B3)"))
+        CPPUNIT_FAIL("Wrong formula.");
+    CPPUNIT_ASSERT_EQUAL( 63.0, m_pDoc->GetValue(aPos));
+
+    aPos.IncRow();
+    m_pDoc->SetString( aPos, "=SUM(Sheet1.B1:Sheet2.B2:Sheet3.B3)");
+    if (!checkFormula( *m_pDoc, aPos, "SUM(Sheet1.B1:Sheet3.B3)"))
+        CPPUNIT_FAIL("Wrong formula.");
+    CPPUNIT_ASSERT_EQUAL( 511.0, m_pDoc->GetValue(aPos));
+
+    // B1:Sheet2.B2 would be ambiguous, Sheet1.B1:Sheet2.B2 or Sheet2.B1:B2
+    // The actual representation of the error case may change, so this test may
+    // have to be adapted.
+    aPos.IncRow();
+    m_pDoc->SetString( aPos, "=SUM(B1:Sheet2.B2:Sheet3.B3)");
+    if (!checkFormula( *m_pDoc, aPos, "SUM(#REF!.B2:#REF!.B3)"))
+        CPPUNIT_FAIL("Wrong formula.");
+    CPPUNIT_ASSERT_EQUAL( OUString("#REF!"), m_pDoc->GetString(aPos));
+
+    aPos.IncRow();
+    m_pDoc->SetString( aPos, "=SUM(Sheet1.B1:Sheet3.B2:Sheet2.B3)");
+    if (!checkFormula( *m_pDoc, aPos, "SUM(Sheet1.B1:Sheet3.B3)"))
+        CPPUNIT_FAIL("Wrong formula.");
+    CPPUNIT_ASSERT_EQUAL( 511.0, m_pDoc->GetValue(aPos));
+
+    aPos.IncRow();
+    m_pDoc->SetString( aPos, "=SUM(B$2:B$2:B2)");
+    if (!checkFormula( *m_pDoc, aPos, "SUM(B$2:B2)"))
+        CPPUNIT_FAIL("Wrong formula.");
+    CPPUNIT_ASSERT_EQUAL( 2.0, m_pDoc->GetValue(aPos));
+
+    m_pDoc->DeleteTab(2);
+    m_pDoc->DeleteTab(1);
+    m_pDoc->DeleteTab(0);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list