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

Eike Rathke erack at redhat.com
Thu Feb 5 02:53:28 PST 2015


 sc/inc/column.hxx                         |    1 
 sc/inc/document.hxx                       |    2 +
 sc/inc/grouparealistener.hxx              |   10 ++++--
 sc/inc/table.hxx                          |    1 
 sc/source/core/data/column2.cxx           |   10 +++++-
 sc/source/core/data/formulacell.cxx       |    2 -
 sc/source/core/tool/grouparealistener.cxx |   44 +++++++++++++++++++++---------
 7 files changed, 52 insertions(+), 18 deletions(-)

New commits:
commit 47230a036fe35b9a7a7c0609232849fcbb51efcc
Author: Eike Rathke <erack at redhat.com>
Date:   Thu Feb 5 11:32:13 2015 +0100

    Resolves: tdf#88792 do not hold a ScFormulaCell** in group area listener
    
    ... as the mdds storage segment may change when a formula cell is
    inserted at a position such that two segments are merged into a new one.
    
    Change-Id: I449a89005418aff7ea12099ea931b786959dbc3b

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 1911a95..b5b9f0c 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -361,6 +361,7 @@ public:
     void        GetFormula( SCROW nRow, OUString& rFormula ) const;
     const ScFormulaCell* GetFormulaCell( SCROW nRow ) const;
     ScFormulaCell* GetFormulaCell( SCROW nRow );
+    ScFormulaCell * const * GetFormulaCellBlockAddress( SCROW nRow ) const;
     CellType    GetCellType( SCROW nRow ) const;
     SCSIZE      GetCellCount() const;
     sal_uInt32 GetWeightedCount() const;
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index d3fe564..4c8aea4 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -79,6 +79,7 @@ struct SetFormulaDirtyContext;
 class RefMovedHint;
 struct SortUndoParam;
 struct ReorderParam;
+class FormulaGroupAreaListener;
 
 }
 
@@ -266,6 +267,7 @@ friend class ScDocumentImport;
 friend class sc::DocumentStreamAccess;
 friend class sc::ColumnSpanSet;
 friend class sc::EditTextIterator;
+friend class sc::FormulaGroupAreaListener;
 
     typedef ::std::vector<ScTable*> TableContainer;
 private:
diff --git a/sc/inc/grouparealistener.hxx b/sc/inc/grouparealistener.hxx
index 9fa4e3d..71de7ee 100644
--- a/sc/inc/grouparealistener.hxx
+++ b/sc/inc/grouparealistener.hxx
@@ -16,6 +16,8 @@
 #include <svl/listener.hxx>
 
 class ScFormulaCell;
+class ScDocument;
+class ScColumn;
 
 namespace sc {
 
@@ -24,7 +26,8 @@ class BulkDataHint;
 class FormulaGroupAreaListener : public SvtListener
 {
     ScRange maRange;
-    ScFormulaCell** mppTopCell;
+    const ScColumn* mpColumn;
+    SCROW mnTopCellRow;
     SCROW mnGroupLen;
     bool mbStartFixed;
     bool mbEndFixed;
@@ -33,8 +36,8 @@ class FormulaGroupAreaListener : public SvtListener
 
 public:
 
-    FormulaGroupAreaListener(
-        const ScRange& rRange, ScFormulaCell** ppTopCell, SCROW nGroupLen, bool bStartFixed, bool bEndFixed );
+    FormulaGroupAreaListener( const ScRange& rRange, const ScDocument& rDocument,
+            const ScAddress& rTopCellPos, SCROW nGroupLen, bool bStartFixed, bool bEndFixed );
 
     virtual ~FormulaGroupAreaListener();
 
@@ -64,6 +67,7 @@ public:
 private:
     void notifyCellChange( const SfxHint& rHint, const ScAddress& rPos );
     void notifyBulkChange( const BulkDataHint& rHint );
+    const ScFormulaCell* getTopCell() const;
 };
 
 }
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index a05f5da..e6857f2 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -220,6 +220,7 @@ friend class ScDocumentImport;
 friend class sc::DocumentStreamAccess;
 friend class sc::ColumnSpanSet;
 friend class sc::EditTextIterator;
+friend class sc::FormulaGroupAreaListener;
 
 public:
                 ScTable( ScDocument* pDoc, SCTAB nNewTab, const OUString& rNewName,
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 779ed16..6afb0d5 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -2708,7 +2708,7 @@ void ScColumn::SetNumberFormat( SCROW nRow, sal_uInt32 nNumberFormat )
     ApplyAttr(nRow, SfxUInt32Item(ATTR_VALUE_FORMAT, nNumberFormat));
 }
 
-const ScFormulaCell* ScColumn::FetchFormulaCell( SCROW nRow ) const
+ScFormulaCell * const * ScColumn::GetFormulaCellBlockAddress( SCROW nRow ) const
 {
     if (!ValidRow(nRow))
         return NULL;
@@ -2722,7 +2722,13 @@ const ScFormulaCell* ScColumn::FetchFormulaCell( SCROW nRow ) const
         // Not a formula cell.
         return NULL;
 
-    return sc::formula_block::at(*it->data, aPos.second);
+    return &sc::formula_block::at(*it->data, aPos.second);
+}
+
+const ScFormulaCell* ScColumn::FetchFormulaCell( SCROW nRow ) const
+{
+    ScFormulaCell const * const * pp = GetFormulaCellBlockAddress( nRow );
+    return pp ? *pp : NULL;
 }
 
 void ScColumn::FindDataAreaPos(SCROW& rRow, bool bDown) const
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index d591870..938fd4d 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -565,7 +565,7 @@ sc::FormulaGroupAreaListener* ScFormulaCellGroup::getAreaListener(
         // Insert a new one.
         it = mpImpl->maAreaListeners.insert(
             it, aKey, new sc::FormulaGroupAreaListener(
-                rRange, ppTopCell, mnLength, bStartFixed, bEndFixed));
+                rRange, *(*ppTopCell)->GetDocument(), (*ppTopCell)->aPos, mnLength, bStartFixed, bEndFixed));
     }
 
     return it->second;
diff --git a/sc/source/core/tool/grouparealistener.cxx b/sc/source/core/tool/grouparealistener.cxx
index 7f4dad6..656c931 100644
--- a/sc/source/core/tool/grouparealistener.cxx
+++ b/sc/source/core/tool/grouparealistener.cxx
@@ -15,6 +15,8 @@
 #include <column.hxx>
 #include <listenerquery.hxx>
 #include <listenerqueryids.hxx>
+#include <document.hxx>
+#include <table.hxx>
 
 namespace sc {
 
@@ -69,25 +71,31 @@ public:
 
 }
 
-FormulaGroupAreaListener::FormulaGroupAreaListener(
-    const ScRange& rRange, ScFormulaCell** ppTopCell, SCROW nGroupLen, bool bStartFixed, bool bEndFixed ) :
+FormulaGroupAreaListener::FormulaGroupAreaListener( const ScRange& rRange, const ScDocument& rDocument,
+        const ScAddress& rTopCellPos, SCROW nGroupLen, bool bStartFixed, bool bEndFixed ) :
     maRange(rRange),
-    mppTopCell(ppTopCell),
+    mpColumn(NULL),
+    mnTopCellRow(rTopCellPos.Row()),
     mnGroupLen(nGroupLen),
     mbStartFixed(bStartFixed),
     mbEndFixed(bEndFixed)
 {
-    assert(mppTopCell); // This can't be NULL.
+    const ScTable* pTab = rDocument.FetchTable( rTopCellPos.Tab());
+    assert(pTab);
+    mpColumn = pTab->FetchColumn( rTopCellPos.Col());
+    assert(mpColumn);
     SAL_INFO( "sc.core.grouparealistener",
             "FormulaGroupAreaListener ctor this " << this <<
-            " range " << maRange.Format(SCA_VALID) << " *mppTopCell " << *mppTopCell << " length " << mnGroupLen);
+            " range " << maRange.Format(SCA_VALID) <<
+            " mnTopCellRow " << mnTopCellRow << " length " << mnGroupLen);
 }
 
 FormulaGroupAreaListener::~FormulaGroupAreaListener()
 {
     SAL_INFO( "sc.core.grouparealistener",
             "FormulaGroupAreaListener dtor this " << this <<
-            " range " << maRange.Format(SCA_VALID) << " *mppTopCell " << *mppTopCell << " length " << mnGroupLen);
+            " range " << maRange.Format(SCA_VALID) <<
+            " mnTopCellRow " << mnTopCellRow << " length " << mnGroupLen);
 }
 
 ScRange FormulaGroupAreaListener::getListeningRange() const
@@ -126,7 +134,7 @@ void FormulaGroupAreaListener::Query( QueryBase& rQuery ) const
     {
         case SC_LISTENER_QUERY_FORMULA_GROUP_RANGE:
         {
-            ScFormulaCell* pTop = *mppTopCell;
+            const ScFormulaCell* pTop = getTopCell();
             ScRange aRange(pTop->aPos);
             aRange.aEnd.IncRow(mnGroupLen-1);
             QueryRange& rQR = static_cast<QueryRange&>(rQuery);
@@ -176,10 +184,15 @@ void FormulaGroupAreaListener::collectFormulaCells(
 {
     SAL_INFO( "sc.core.grouparealistener",
             "FormulaGroupAreaListener::collectFormulaCells() this " << this <<
-            " range " << maRange.Format(SCA_VALID) << " *mppTopCell " << *mppTopCell << " length " << mnGroupLen);
+            " range " << maRange.Format(SCA_VALID) <<
+            " mnTopCellRow " << mnTopCellRow << " length " << mnGroupLen);
 
-    ScFormulaCell** pp = mppTopCell;
-    ScFormulaCell** ppEnd = pp + mnGroupLen;
+    ScFormulaCell* const * pp = mpColumn->GetFormulaCellBlockAddress( mnTopCellRow);
+    assert(pp);
+    if (!pp)
+        return;
+
+    ScFormulaCell* const * ppEnd = pp + mnGroupLen;
 
     if (mbStartFixed)
     {
@@ -261,8 +274,15 @@ void FormulaGroupAreaListener::collectFormulaCells(
 
 ScAddress FormulaGroupAreaListener::getTopCellPos() const
 {
-    const ScFormulaCell& rFC = **mppTopCell;
-    return rFC.aPos;
+    const ScFormulaCell* p = getTopCell();
+    return p ? p->aPos : ScAddress();
+}
+
+const ScFormulaCell* FormulaGroupAreaListener::getTopCell() const
+{
+    const ScFormulaCell* const * pp = mpColumn->GetFormulaCellBlockAddress( mnTopCellRow);
+    assert(pp);
+    return pp ? *pp : NULL;
 }
 
 const ScRange& FormulaGroupAreaListener::getRange() const


More information about the Libreoffice-commits mailing list