[Libreoffice-commits] core.git: Branch 'libreoffice-4-4' - sc/inc sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Thu Nov 20 19:23:34 PST 2014


 sc/inc/column.hxx                  |    5 ++
 sc/inc/document.hxx                |    5 ++
 sc/inc/table.hxx                   |    6 +++
 sc/source/core/data/column4.cxx    |   70 +++++++++++++++++++++++++++++++++++++
 sc/source/core/data/document.cxx   |   26 +++++++++++--
 sc/source/core/data/document10.cxx |   29 +++++++++++++++
 sc/source/core/data/table7.cxx     |   19 ++++++++++
 7 files changed, 156 insertions(+), 4 deletions(-)

New commits:
commit c0e74352b1a1c7bdcfd15acdd8780df9f4d18200
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Thu Nov 20 21:43:25 2014 -0500

    Adjust InsertRow() for group area listeners.
    
    Change-Id: I813b45d015eb1ae8dc7bd1242152ef734b5fe08c
    (cherry picked from commit 01e14bd403e749116844b6ab0b0a7afc66347e90)

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index da94024..7c6b2cd 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -665,6 +665,11 @@ private:
      * column.
      */
     std::vector<sc::FormulaGroupEntry> GetFormulaGroupEntries();
+
+    void EndListeningIntersectedGroups(
+        sc::EndListeningContext& rCxt, SCROW nRow1, SCROW nRow2, std::vector<ScAddress>* pGroupPos = NULL );
+
+    void SetNeedsListeningGroup( SCROW nRow );
 };
 
 #endif
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index ee43f2c..fcb92dc 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -2178,6 +2178,11 @@ private:
     bool   ReservePatternCount( SCTAB nTab, SCCOL nCol, SCSIZE nReserve );
 
     void SharePooledResources( ScDocument* pSrcDoc );
+
+    void EndListeningIntersectedGroups(
+        sc::EndListeningContext& rCxt, const ScRange& rRange, std::vector<ScAddress>* pGroupPos = NULL );
+
+    void SetNeedsListeningGroups( const std::vector<ScAddress>& rPosArray );
 };
 
 #endif
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 04ebaa9..56af841 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -1109,6 +1109,12 @@ private:
     ScColumn* FetchColumn( SCCOL nCol );
     const ScColumn* FetchColumn( SCCOL nCol ) const;
 
+    void EndListeningIntersectedGroups(
+        sc::EndListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+        std::vector<ScAddress>* pGroupPos = NULL );
+
+    void SetNeedsListeningGroup( SCCOL nCol, SCROW nRow );
+
     /**
      * Use this to iterate through non-empty visible cells in a single column.
      */
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index ba6d015..43946e5 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -1357,4 +1357,74 @@ void ScColumn::EndListeningFormulaCells(
         *pEndRow = aFunc.getEndRow();
 }
 
+void ScColumn::EndListeningIntersectedGroups(
+    sc::EndListeningContext& rCxt, SCROW nRow1, SCROW nRow2, std::vector<ScAddress>* pGroupPos )
+{
+    // Only end the intersected group.
+    sc::CellStoreType::position_type aPos = maCells.position(nRow1);
+    sc::CellStoreType::iterator it = aPos.first;
+    if (it->type == sc::element_type_formula)
+    {
+        ScFormulaCell* pFC = sc::formula_block::at(*it->data, aPos.second);
+        ScFormulaCellGroupRef xGroup = pFC->GetCellGroup();
+        if (xGroup && !pFC->IsSharedTop())
+        {
+            // End listening.
+            pFC->EndListeningTo(rCxt);
+            if (pGroupPos)
+                // Record the position of the top cell of the group.
+                pGroupPos->push_back(xGroup->mpTopCell->aPos);
+        }
+    }
+
+    aPos = maCells.position(it, nRow2);
+    it = aPos.first;
+    if (it->type == sc::element_type_formula)
+    {
+        ScFormulaCell* pFC = sc::formula_block::at(*it->data, aPos.second);
+        ScFormulaCellGroupRef xGroup = pFC->GetCellGroup();
+        if (xGroup && !pFC->IsSharedTop())
+        {
+            // End listening.
+            pFC->EndListeningTo(rCxt);
+            if (pGroupPos)
+            {
+                // Record the position of the bottom cell of the group.
+                ScAddress aPosLast = xGroup->mpTopCell->aPos;
+                aPosLast.IncRow(xGroup->mnLength-1);
+                pGroupPos->push_back(aPosLast);
+            }
+        }
+    }
+}
+
+void ScColumn::SetNeedsListeningGroup( SCROW nRow )
+{
+    sc::CellStoreType::position_type aPos = maCells.position(nRow);
+    if (aPos.first->type != sc::element_type_formula)
+        // not a formula cell.
+        return;
+
+    ScFormulaCell** pp = &sc::formula_block::at(*aPos.first->data, aPos.second);
+
+    ScFormulaCellGroupRef xGroup = (*pp)->GetCellGroup();
+    if (!xGroup)
+    {
+        // not a formula group.
+        (*pp)->SetNeedsListening(true);
+        return;
+    }
+
+    // Move back to the top cell.
+    SCROW nTopDelta = (*pp)->aPos.Row() - xGroup->mpTopCell->aPos.Row();
+    for (SCROW i = 0; i < nTopDelta; ++i)
+        --pp;
+
+    // Set the needs listening flag to all cells in the group.
+    assert(*pp == xGroup->mpTopCell);
+    ScFormulaCell** ppEnd = pp + xGroup->mnLength;
+    for (; pp != ppEnd; ++pp)
+        (*pp)->SetNeedsListening(true);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 9f9e45e..a413388 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -1218,11 +1218,22 @@ bool ScDocument::InsertRow( SCCOL nStartCol, SCTAB nStartTab,
         SCTAB nTabRangeStart = nStartTab;
         SCTAB nTabRangeEnd = nEndTab;
         lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) );
+        ScRange aShiftedRange(nStartCol, nStartRow, nTabRangeStart, nEndCol, MAXROW, nTabRangeEnd);
+        sc::EndListeningContext aEndListenCxt(*this);
+
+        std::vector<ScAddress> aGroupPos;
         do
         {
-            UpdateBroadcastAreas( URM_INSDEL, ScRange(
-                ScAddress( nStartCol, nStartRow, nTabRangeStart ),
-                ScAddress( nEndCol, MAXROW, nTabRangeEnd )), 0, static_cast<SCsROW>(nSize), 0 );
+            aShiftedRange.aStart.SetTab(nTabRangeStart);
+            aShiftedRange.aEnd.SetTab(nTabRangeEnd);
+
+            // Collect all formula groups that will get split by the shifting,
+            // and end all their listening.  Record the position of the top
+            // cell of the topmost group, and the postion of the bottom cell
+            // of the bottommost group.
+            EndListeningIntersectedGroups(aEndListenCxt, aShiftedRange, &aGroupPos);
+
+            UpdateBroadcastAreas(URM_INSDEL, aShiftedRange, 0, static_cast<SCsROW>(nSize), 0);
         }
         while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) ) );
 
@@ -1230,14 +1241,21 @@ bool ScDocument::InsertRow( SCCOL nStartCol, SCTAB nStartTab,
 
         sc::RefUpdateContext aCxt(*this);
         aCxt.meMode = URM_INSDEL;
-        aCxt.maRange = ScRange(nStartCol, nStartRow, nTabRangeStart, nEndCol, MAXROW, nTabRangeEnd);
+        aCxt.maRange = aShiftedRange;
         aCxt.mnRowDelta = nSize;
         do
         {
+            aCxt.maRange.aStart.SetTab(nTabRangeStart);
+            aCxt.maRange.aEnd.SetTab(nTabRangeEnd);
             UpdateReference(aCxt, pRefUndoDoc, false);        // without drawing objects
         }
         while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) ) );
 
+        // UpdateReference should have set "needs listening" flags to those
+        // whose references have been modified.  We also need to set this flag
+        // to those that were in the groups that got split by shifting.
+        SetNeedsListeningGroups(aGroupPos);
+
         for (i=nStartTab; i<=nEndTab && i < static_cast<SCTAB>(maTabs.size()); i++)
             if (maTabs[i] && (!pTabMark || pTabMark->GetTableSelect(i)))
                 maTabs[i]->InsertRow( nStartCol, nEndCol, nStartRow, nSize );
diff --git a/sc/source/core/data/document10.cxx b/sc/source/core/data/document10.cxx
index 1f14d5d..c426a19 100644
--- a/sc/source/core/data/document10.cxx
+++ b/sc/source/core/data/document10.cxx
@@ -355,4 +355,33 @@ bool ScDocument::HasFormulaCell( const ScRange& rRange ) const
     return false;
 }
 
+void ScDocument::EndListeningIntersectedGroups(
+    sc::EndListeningContext& rCxt, const ScRange& rRange, std::vector<ScAddress>* pGroupPos )
+{
+    for (SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab)
+    {
+        ScTable* pTab = FetchTable(nTab);
+        if (!pTab)
+            continue;
+
+        pTab->EndListeningIntersectedGroups(
+            rCxt, rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row(),
+            pGroupPos);
+    }
+}
+
+void ScDocument::SetNeedsListeningGroups( const std::vector<ScAddress>& rPosArray )
+{
+    std::vector<ScAddress>::const_iterator it = rPosArray.begin(), itEnd = rPosArray.end();
+    for (; it != itEnd; ++it)
+    {
+        const ScAddress& rPos = *it;
+        ScTable* pTab = FetchTable(rPos.Tab());
+        if (!pTab)
+            return;
+
+        pTab->SetNeedsListeningGroup(rPos.Col(), rPos.Row());
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/table7.cxx b/sc/source/core/data/table7.cxx
index 79a645c..f9e429a 100644
--- a/sc/source/core/data/table7.cxx
+++ b/sc/source/core/data/table7.cxx
@@ -199,4 +199,23 @@ bool ScTable::HasFormulaCell( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2
     return false;
 }
 
+void ScTable::EndListeningIntersectedGroups(
+    sc::EndListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+    std::vector<ScAddress>* pGroupPos )
+{
+    if (nCol2 < nCol1 || !ValidCol(nCol1) || !ValidCol(nCol2))
+        return;
+
+    for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
+        aCol[nCol].EndListeningIntersectedGroups(rCxt, nRow1, nRow2, pGroupPos);
+}
+
+void ScTable::SetNeedsListeningGroup( SCCOL nCol, SCROW nRow )
+{
+    if (!ValidCol(nCol))
+        return;
+
+    aCol[nCol].SetNeedsListeningGroup(nRow);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list