[Libreoffice-commits] core.git: 2 commits - sc/inc sc/qa sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Tue May 13 09:37:04 PDT 2014


 sc/inc/document.hxx              |    4 -
 sc/qa/unit/ucalc.cxx             |    7 ++
 sc/qa/unit/ucalc.hxx             |    4 +
 sc/qa/unit/ucalc_formula.cxx     |  127 +++++++++++++++++++++++++++++++++++++++
 sc/source/core/data/conditio.cxx |   29 ++++++++
 sc/source/core/data/document.cxx |    9 ++
 sc/source/core/tool/interpr4.cxx |    8 +-
 sc/source/ui/undo/undoblk.cxx    |   15 ++++
 8 files changed, 196 insertions(+), 7 deletions(-)

New commits:
commit a93bb27aa46c84410c8848a6118d5d63d47be92c
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue May 13 12:35:24 2014 -0400

    fdo#78402: Adjust references of validity entries as appropriate.
    
    Change-Id: I7fd62153c7267a3d606b86d74bebecf6b8d75250

diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx
index 43dc94e..49f2fea 100644
--- a/sc/source/core/data/conditio.cxx
+++ b/sc/source/core/data/conditio.cxx
@@ -513,13 +513,38 @@ void ScConditionEntry::UpdateReference( sc::RefUpdateContext& rCxt )
 
     if (pFormula1)
     {
-        sc::RefUpdateResult aRes = pFormula1->AdjustReferenceInName(rCxt, aOldSrcPos);
+        sc::RefUpdateResult aRes;
+        switch (rCxt.meMode)
+        {
+            case URM_INSDEL:
+                aRes = pFormula1->AdjustReferenceOnShift(rCxt, aOldSrcPos);
+            break;
+            case URM_MOVE:
+                aRes = pFormula1->AdjustReferenceOnMove(rCxt, aOldSrcPos, aSrcPos);
+            break;
+            default:
+                ;
+        }
+
         if (aRes.mbReferenceModified || bChangedPos)
             DELETEZ(pFCell1);       // is created again in IsValid
     }
+
     if (pFormula2)
     {
-        sc::RefUpdateResult aRes = pFormula2->AdjustReferenceInName(rCxt, aOldSrcPos);
+        sc::RefUpdateResult aRes;
+        switch (rCxt.meMode)
+        {
+            case URM_INSDEL:
+                aRes = pFormula2->AdjustReferenceOnShift(rCxt, aOldSrcPos);
+            break;
+            case URM_MOVE:
+                aRes = pFormula2->AdjustReferenceOnMove(rCxt, aOldSrcPos, aSrcPos);
+            break;
+            default:
+                ;
+        }
+
         if (aRes.mbReferenceModified || bChangedPos)
             DELETEZ(pFCell2);       // is created again in IsValid
     }
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index e414337..e4fb73f 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -1867,6 +1867,8 @@ void ScInterpreter::QueryMatrixType(ScMatrixRef& xMat, short& rRetTypeExpr, sal_
 {
     if (xMat)
     {
+        SCSIZE nCols, nRows;
+        xMat->GetDimensions(nCols, nRows);
         ScMatrixValue nMatVal = xMat->Get(0, 0);
         ScMatValType nMatValType = nMatVal.nType;
         if (ScMatrix::IsNonValueType( nMatValType))
@@ -1874,14 +1876,14 @@ void ScInterpreter::QueryMatrixType(ScMatrixRef& xMat, short& rRetTypeExpr, sal_
             if ( xMat->IsEmptyPath( 0, 0))
             {   // result of empty FALSE jump path
                 FormulaTokenRef xRes = new FormulaDoubleToken( 0.0);
-                PushTempToken( new ScMatrixCellResultToken( xMat, xRes.get()));
+                PushTempToken( new ScMatrixFormulaCellToken(nCols, nRows, xMat, xRes.get()));
                 rRetTypeExpr = NUMBERFORMAT_LOGICAL;
             }
             else
             {
                 svl::SharedString aStr( nMatVal.GetString());
                 FormulaTokenRef xRes = new FormulaStringToken( aStr);
-                PushTempToken( new ScMatrixCellResultToken( xMat, xRes.get()));
+                PushTempToken( new ScMatrixFormulaCellToken(nCols, nRows, xMat, xRes.get()));
                 rRetTypeExpr = NUMBERFORMAT_TEXT;
             }
         }
@@ -1893,7 +1895,7 @@ void ScInterpreter::QueryMatrixType(ScMatrixRef& xMat, short& rRetTypeExpr, sal_
                 xRes = new FormulaErrorToken( nErr);
             else
                 xRes = new FormulaDoubleToken( nMatVal.fVal);
-            PushTempToken( new ScMatrixCellResultToken( xMat, xRes.get()));
+            PushTempToken( new ScMatrixFormulaCellToken(nCols, nRows, xMat, xRes.get()));
             if ( rRetTypeExpr != NUMBERFORMAT_LOGICAL )
                 rRetTypeExpr = NUMBERFORMAT_NUMBER;
         }
diff --git a/sc/source/ui/undo/undoblk.cxx b/sc/source/ui/undo/undoblk.cxx
index fefa95f..dd0577e 100644
--- a/sc/source/ui/undo/undoblk.cxx
+++ b/sc/source/ui/undo/undoblk.cxx
@@ -49,6 +49,8 @@
 #include "sc.hrc"
 #include <rowheightcontext.hxx>
 #include <refhint.hxx>
+#include <refupdatecontext.hxx>
+#include <validat.hxx>
 
 #include <set>
 #include <boost/scoped_ptr.hpp>
@@ -1264,6 +1266,19 @@ void ScUndoDragDrop::Undo()
         SCTAB nTabDelta = aSrcRange.aStart.Tab() - aDestRange.aStart.Tab();
         sc::RefMovedHint aHint(aDestRange, ScAddress(nColDelta, nRowDelta, nTabDelta));
         pDoc->BroadcastRefMoved(aHint);
+
+        ScValidationDataList* pValidList = pDoc->GetValidationList();
+        if (pValidList)
+        {
+            // Update the references of validation entries.
+            sc::RefUpdateContext aCxt(*pDoc);
+            aCxt.meMode = URM_MOVE;
+            aCxt.maRange = aSrcRange;
+            aCxt.mnColDelta = nColDelta;
+            aCxt.mnRowDelta = nRowDelta;
+            aCxt.mnTabDelta = nTabDelta;
+            pValidList->UpdateReference(aCxt);
+        }
     }
 
     DoUndo(aDestRange);
commit 49bf3a1f5f38cdf259101b15a19d546b32151463
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue May 13 12:27:59 2014 -0400

    fdo#78402: Write test for this.
    
    Also discovered that when the "precision as shown" option is set, the validity
    list would only show the first item from the list.  Turn that option on in the
    test.
    
    Change-Id: I9aaeeb3358709d965f51e406668c72cb94541cdb

diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 8793ab7..ad080ae 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1408,8 +1408,8 @@ public:
 
     SC_DLLPUBLIC ScConditionalFormatList* GetCondFormList( SCTAB nTab ) const;
 
-    ScValidationDataList* GetValidationList() const
-                    { return pValidationList; }
+    const ScValidationDataList* GetValidationList() const;
+    ScValidationDataList* GetValidationList();
 
     SC_DLLPUBLIC void           ApplyAttr( SCCOL nCol, SCROW nRow, SCTAB nTab,
                                 const SfxPoolItem& rAttr );
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index e433454..2a2f706 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -6245,6 +6245,13 @@ void Test::setExpandRefs(bool bExpand)
     pMod->SetInputOptions(aOpt);
 }
 
+void Test::setCalcAsShown(ScDocument* pDoc, bool bCalcAsShown)
+{
+    ScDocOptions aOpt = pDoc->GetDocOptions();
+    aOpt.SetCalcAsShown(bCalcAsShown);
+    pDoc->SetDocOptions(aOpt);
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx
index 76c74cc..f69da1b 100644
--- a/sc/qa/unit/ucalc.hxx
+++ b/sc/qa/unit/ucalc.hxx
@@ -53,6 +53,8 @@ public:
      */
     static void setExpandRefs(bool bExpand);
 
+    static void setCalcAsShown(ScDocument* pDoc, bool bCalcAsShown);
+
     template<size_t _Size>
     static ScRange insertRangeData(ScDocument* pDoc, const ScAddress& rPos, const char* aData[][_Size], size_t nRowCount)
     {
@@ -131,6 +133,7 @@ public:
     void testFormulaRefUpdateNamedExpression();
     void testFormulaRefUpdateNamedExpressionMove();
     void testFormulaRefUpdateNamedExpressionExpandRef();
+    void testFormulaRefUpdateValidity();
     void testMultipleOperations();
     void testFuncCOLUMN();
     void testFuncCOUNT();
@@ -389,6 +392,7 @@ public:
     CPPUNIT_TEST(testFormulaRefUpdateNamedExpression);
     CPPUNIT_TEST(testFormulaRefUpdateNamedExpressionMove);
     CPPUNIT_TEST(testFormulaRefUpdateNamedExpressionExpandRef);
+    CPPUNIT_TEST(testFormulaRefUpdateValidity);
     CPPUNIT_TEST(testMultipleOperations);
     CPPUNIT_TEST(testFuncCOLUMN);
     CPPUNIT_TEST(testFuncCOUNT);
diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx
index ce508af..4d4d0c2 100644
--- a/sc/qa/unit/ucalc_formula.cxx
+++ b/sc/qa/unit/ucalc_formula.cxx
@@ -23,6 +23,10 @@
 #include "paramisc.hxx"
 #include "tokenstringcontext.hxx"
 #include "dbdata.hxx"
+#include <validat.hxx>
+#include <scitems.hxx>
+#include <patattr.hxx>
+#include <docpool.hxx>
 
 #include <formula/vectortoken.hxx>
 
@@ -2111,6 +2115,129 @@ void Test::testFormulaRefUpdateNamedExpressionExpandRef()
     m_pDoc->DeleteTab(0);
 }
 
+void Test::testFormulaRefUpdateValidity()
+{
+    struct {
+
+        bool checkList( std::vector<ScTypedStrData>& rList )
+        {
+            double aExpected[] = { 1.0, 2.0, 3.0 }; // must be sorted.
+            size_t nCheckSize = SAL_N_ELEMENTS(aExpected);
+
+            if (rList.size() != nCheckSize)
+            {
+                cerr << "List size is not what is expected." << endl;
+                return false;
+            }
+
+            std::sort(rList.begin(), rList.end(), ScTypedStrData::LessCaseSensitive());
+
+            for (size_t i = 0; i < nCheckSize; ++i)
+            {
+                if (aExpected[i] != rList[i].GetValue())
+                {
+                    cerr << "Incorrect value at position " << i
+                        << ": expected=" << aExpected[i] << ", actual=" << rList[i].GetValue() << endl;
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+    } aCheck;
+
+    setExpandRefs(false);
+    setCalcAsShown(m_pDoc, true);
+
+    m_pDoc->InsertTab(0, "Formula");
+
+    // Set values in C2:C4.
+    m_pDoc->SetValue(ScAddress(2,1,0), 1.0);
+    m_pDoc->SetValue(ScAddress(2,2,0), 2.0);
+    m_pDoc->SetValue(ScAddress(2,3,0), 3.0);
+
+    // Set validity in A2.
+    ScValidationData aData(
+        SC_VALID_LIST, SC_COND_EQUAL, "C2:C4", "", m_pDoc, ScAddress(0,1,0), "", "",
+        m_pDoc->GetGrammar(), m_pDoc->GetGrammar());
+
+    sal_uLong nIndex = m_pDoc->AddValidationEntry(aData);
+    SfxUInt32Item aItem(ATTR_VALIDDATA, nIndex);
+
+    ScPatternAttr aNewAttrs(
+        new SfxItemSet(*m_pDoc->GetPool(), ATTR_PATTERN_START, ATTR_PATTERN_END));
+    aNewAttrs.GetItemSet().Put(aItem);
+
+    m_pDoc->ApplyPattern(0, 1, 0, aNewAttrs);
+
+    const ScValidationData* pData = m_pDoc->GetValidationEntry(nIndex);
+    CPPUNIT_ASSERT(pData);
+
+    // Make sure the list is correct.
+    std::vector<ScTypedStrData> aList;
+    pData->FillSelectionList(aList, ScAddress(0,1,0));
+    bool bGood = aCheck.checkList(aList);
+    CPPUNIT_ASSERT_MESSAGE("Initial list is incorrect.", bGood);
+
+    ScDocFunc& rFunc = getDocShell().GetDocFunc();
+    ScMarkData aMark;
+    aMark.SelectOneTable(0);
+
+    // Insert a new column at Column B, to move the list from C2:C4 to D2:D4.
+    bool bInserted = rFunc.InsertCells(ScRange(1,0,0,1,MAXROW,0), &aMark, INS_INSCOLS, true, true, false);
+    CPPUNIT_ASSERT_MESSAGE("Column insertion failed.", bInserted);
+    CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(ScAddress(3,1,0)));
+    CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(3,2,0)));
+    CPPUNIT_ASSERT_EQUAL(3.0, m_pDoc->GetValue(ScAddress(3,3,0)));
+
+    // Check the list values again.
+    aList.clear();
+    pData->FillSelectionList(aList, ScAddress(0,1,0));
+    bGood = aCheck.checkList(aList);
+    CPPUNIT_ASSERT_MESSAGE("List content is incorrect after column insertion.", bGood);
+
+    SfxUndoManager* pUndoMgr = m_pDoc->GetUndoManager();
+    CPPUNIT_ASSERT(pUndoMgr);
+
+    // Undo and check the list content again.  The list moves back to C2:C4 after the undo.
+    pUndoMgr->Undo();
+    CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(ScAddress(2,1,0)));
+    CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(2,2,0)));
+    CPPUNIT_ASSERT_EQUAL(3.0, m_pDoc->GetValue(ScAddress(2,3,0)));
+
+    aList.clear();
+    pData->FillSelectionList(aList, ScAddress(0,1,0));
+    bGood = aCheck.checkList(aList);
+    CPPUNIT_ASSERT_MESSAGE("List content is incorrect after undo of column insertion.", bGood);
+
+    // Move C2:C4 to E5:E7.
+    bool bMoved = rFunc.MoveBlock(ScRange(2,1,0,2,3,0), ScAddress(4,4,0), false, true, false, true);
+    CPPUNIT_ASSERT(bMoved);
+    CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(ScAddress(4,4,0)));
+    CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(4,5,0)));
+    CPPUNIT_ASSERT_EQUAL(3.0, m_pDoc->GetValue(ScAddress(4,6,0)));
+
+    // Check the list again after the move.
+    aList.clear();
+    pData->FillSelectionList(aList, ScAddress(0,1,0));
+    bGood = aCheck.checkList(aList);
+    CPPUNIT_ASSERT_MESSAGE("List content is incorrect after moving C2:C4 to E5:E7.", bGood);
+
+    // Undo the move and check.  The list should be back to C2:C4.
+    pUndoMgr->Undo();
+    CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(ScAddress(2,1,0)));
+    CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(2,2,0)));
+    CPPUNIT_ASSERT_EQUAL(3.0, m_pDoc->GetValue(ScAddress(2,3,0)));
+
+    aList.clear();
+    pData->FillSelectionList(aList, ScAddress(0,1,0));
+    bGood = aCheck.checkList(aList);
+    CPPUNIT_ASSERT_MESSAGE("List content is incorrect after undo of the move.", bGood);
+
+    m_pDoc->DeleteTab(0);
+}
+
 void Test::testMultipleOperations()
 {
     m_pDoc->InsertTab(0, "MultiOp");
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 57c82d0..d72e7db 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -4489,6 +4489,15 @@ const ScPatternAttr* ScDocument::GetMostUsedPattern( SCCOL nCol, SCROW nStartRow
     return NULL;
 }
 
+const ScValidationDataList* ScDocument::GetValidationList() const
+{
+    return pValidationList;
+}
+
+ScValidationDataList* ScDocument::GetValidationList()
+{
+    return pValidationList;
+}
 
 void ScDocument::ApplyAttr( SCCOL nCol, SCROW nRow, SCTAB nTab, const SfxPoolItem& rAttr )
 {


More information about the Libreoffice-commits mailing list