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

Kohei Yoshida kohei.yoshida at collabora.com
Fri Jan 16 10:13:48 PST 2015


 sc/inc/column.hxx                  |    3 ++
 sc/inc/document.hxx                |    3 ++
 sc/inc/table.hxx                   |    3 ++
 sc/source/core/data/column4.cxx    |   34 ++++++++++++++++++++++++++++++
 sc/source/core/data/document.cxx   |   41 +++++++++++++++++++++++++++++--------
 sc/source/core/data/document10.cxx |   10 +++++++++
 sc/source/core/data/table7.cxx     |    9 ++++++++
 7 files changed, 95 insertions(+), 8 deletions(-)

New commits:
commit 6240e598f29ee5e95c56e5885f539ce470d9afd6
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Thu Jan 15 20:49:36 2015 -0500

    fdo#88398: Handle group listeners correctly when splitting formula group.
    
    It's basically the same thing we do in ScDocument::DeleteArea(), implemented
    in ScDocument::SetValue() and SetString().
    
    Change-Id: Ifcae31aaef0e00ed8659aa5e2b9b8e206dc1a099
    (cherry picked from commit 4c93c341be1425401112eed3581e8b8a6308880d)
    Reviewed-on: https://gerrit.libreoffice.org/13946
    Reviewed-by: Eike Rathke <erack at redhat.com>
    Tested-by: Eike Rathke <erack at redhat.com>

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 2644bf3..0cc342c 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -687,6 +687,9 @@ private:
      */
     std::vector<sc::FormulaGroupEntry> GetFormulaGroupEntries();
 
+    void EndListeningIntersectedGroup(
+        sc::EndListeningContext& rCxt, SCROW nRow, std::vector<ScAddress>* pGroupPos = NULL );
+
     void EndListeningIntersectedGroups(
         sc::EndListeningContext& rCxt, SCROW nRow1, SCROW nRow2, std::vector<ScAddress>* pGroupPos = NULL );
 
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index c135508..f46ec56 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -2186,6 +2186,9 @@ private:
 
     void SharePooledResources( ScDocument* pSrcDoc );
 
+    void EndListeningIntersectedGroup(
+        sc::EndListeningContext& rCxt, const ScAddress& rPos, std::vector<ScAddress>* pGroupPos = NULL );
+
     void EndListeningIntersectedGroups(
         sc::EndListeningContext& rCxt, const ScRange& rRange, std::vector<ScAddress>* pGroupPos = NULL );
 
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 1053ea7..7066254 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -1119,6 +1119,9 @@ private:
     ScColumn* FetchColumn( SCCOL nCol );
     const ScColumn* FetchColumn( SCCOL nCol ) const;
 
+    void EndListeningIntersectedGroup(
+        sc::EndListeningContext& rCxt, SCCOL nCol, SCROW nRow, std::vector<ScAddress>* pGroupPos = NULL );
+
     void EndListeningIntersectedGroups(
         sc::EndListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
         std::vector<ScAddress>* pGroupPos = NULL );
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index 2386296..19e3b14 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -1382,6 +1382,40 @@ void ScColumn::EndListeningFormulaCells(
         *pEndRow = aFunc.getEndRow();
 }
 
+void ScColumn::EndListeningIntersectedGroup(
+    sc::EndListeningContext& rCxt, SCROW nRow, std::vector<ScAddress>* pGroupPos )
+{
+    if (!ValidRow(nRow))
+        return;
+
+    sc::CellStoreType::position_type aPos = maCells.position(nRow);
+    sc::CellStoreType::iterator it = aPos.first;
+    if (it->type != sc::element_type_formula)
+        // Only interested in a formula block.
+        return;
+
+    ScFormulaCell* pFC = sc::formula_block::at(*it->data, aPos.second);
+    ScFormulaCellGroupRef xGroup = pFC->GetCellGroup();
+    if (!xGroup)
+        // Not a formula group.
+        return;
+
+    // End listening.
+    pFC->EndListeningTo(rCxt);
+
+    if (pGroupPos)
+    {
+        if (!pFC->IsSharedTop())
+            // Record the position of the top cell of the group.
+            pGroupPos->push_back(xGroup->mpTopCell->aPos);
+
+        SCROW nGrpLastRow = pFC->GetSharedTopRow() + pFC->GetSharedLength() - 1;
+        if (nRow < nGrpLastRow)
+            // Record the last position of the group.
+            pGroupPos->push_back(ScAddress(nCol, nGrpLastRow, nTab));
+    }
+}
+
 void ScColumn::EndListeningIntersectedGroups(
     sc::EndListeningContext& rCxt, SCROW nRow1, SCROW nRow2, std::vector<ScAddress>* pGroupPos )
 {
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 58ade9c..b9307c1 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -3200,10 +3200,25 @@ void ScDocument::FillTabMarked( SCTAB nSrcTab, const ScMarkData& rMark,
 bool ScDocument::SetString( SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString& rString,
                             ScSetStringParam* pParam )
 {
-    if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
-        return maTabs[nTab]->SetString( nCol, nRow, nTab, rString, pParam );
-    else
+    ScTable* pTab = FetchTable(nTab);
+    if (!pTab)
         return false;
+
+    // In case setting this string affects an existing formula group, record
+    // its above and below position for later listening.
+
+    std::vector<ScAddress> aGroupPos;
+    sc::EndListeningContext aCxt(*this);
+    ScAddress aPos(nCol, nRow, nTab);
+    EndListeningIntersectedGroup(aCxt, aPos, &aGroupPos);
+    aCxt.purgeEmptyBroadcasters();
+
+    bool bNumFmtSet = pTab->SetString(nCol, nRow, nTab, rString, pParam);
+
+    SetNeedsListeningGroups(aGroupPos);
+    StartNeededListeners();
+
+    return bNumFmtSet;
 }
 
 bool ScDocument::SetString(
@@ -3279,17 +3294,27 @@ void ScDocument::SetEmptyCell( const ScAddress& rPos )
 
 void ScDocument::SetValue( SCCOL nCol, SCROW nRow, SCTAB nTab, const double& rVal )
 {
-    if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()))
-        if (maTabs[nTab])
-            maTabs[nTab]->SetValue( nCol, nRow, rVal );
+    SetValue(ScAddress(nCol, nRow, nTab), rVal);
 }
 
 void ScDocument::SetValue( const ScAddress& rPos, double fVal )
 {
-    if (!TableExists(rPos.Tab()))
+    ScTable* pTab = FetchTable(rPos.Tab());
+    if (!pTab)
         return;
 
-    maTabs[rPos.Tab()]->SetValue(rPos.Col(), rPos.Row(), fVal);
+    // In case setting this string affects an existing formula group, record
+    // its above and below position for later listening.
+
+    std::vector<ScAddress> aGroupPos;
+    sc::EndListeningContext aCxt(*this);
+    EndListeningIntersectedGroup(aCxt, rPos, &aGroupPos);
+    aCxt.purgeEmptyBroadcasters();
+
+    pTab->SetValue(rPos.Col(), rPos.Row(), fVal);
+
+    SetNeedsListeningGroups(aGroupPos);
+    StartNeededListeners();
 }
 
 OUString ScDocument::GetString( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
diff --git a/sc/source/core/data/document10.cxx b/sc/source/core/data/document10.cxx
index 06ab0b9..0a2e3cb 100644
--- a/sc/source/core/data/document10.cxx
+++ b/sc/source/core/data/document10.cxx
@@ -361,6 +361,16 @@ bool ScDocument::HasFormulaCell( const ScRange& rRange ) const
     return false;
 }
 
+void ScDocument::EndListeningIntersectedGroup(
+    sc::EndListeningContext& rCxt, const ScAddress& rPos, std::vector<ScAddress>* pGroupPos )
+{
+    ScTable* pTab = FetchTable(rPos.Tab());
+    if (!pTab)
+        return;
+
+    pTab->EndListeningIntersectedGroup(rCxt, rPos.Col(), rPos.Row(), pGroupPos);
+}
+
 void ScDocument::EndListeningIntersectedGroups(
     sc::EndListeningContext& rCxt, const ScRange& rRange, std::vector<ScAddress>* pGroupPos )
 {
diff --git a/sc/source/core/data/table7.cxx b/sc/source/core/data/table7.cxx
index 2740735..f940ee5 100644
--- a/sc/source/core/data/table7.cxx
+++ b/sc/source/core/data/table7.cxx
@@ -199,6 +199,15 @@ bool ScTable::HasFormulaCell( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2
     return false;
 }
 
+void ScTable::EndListeningIntersectedGroup(
+    sc::EndListeningContext& rCxt, SCCOL nCol, SCROW nRow, std::vector<ScAddress>* pGroupPos )
+{
+    if (!ValidCol(nCol))
+        return;
+
+    aCol[nCol].EndListeningIntersectedGroup(rCxt, nRow, pGroupPos);
+}
+
 void ScTable::EndListeningIntersectedGroups(
     sc::EndListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
     std::vector<ScAddress>* pGroupPos )


More information about the Libreoffice-commits mailing list