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

Eike Rathke erack at redhat.com
Tue Apr 21 06:11:21 PDT 2015


 sc/inc/column.hxx                         |    2 -
 sc/source/core/data/column2.cxx           |   15 +++++++++-
 sc/source/core/tool/grouparealistener.cxx |   43 +++++++++++++++++++++++-------
 3 files changed, 47 insertions(+), 13 deletions(-)

New commits:
commit 5c6f7f0920a91c974e9639f2c751582c8f140b2b
Author: Eike Rathke <erack at redhat.com>
Date:   Tue Apr 14 23:09:46 2015 +0200

    tdf#89957 prevent crash, not really fixed
    
    See source code comment.
    
    (cherry picked from commit cff5ee864b2d87d74079697425d7895dbf1b2ba4)
    
    more SAL_INFO sc.core.grouparealistener
    
    (cherry picked from commit b03563571fb922636635ea72f2dbda18d736ff89)
    
    Conflicts:
    	sc/source/core/tool/grouparealistener.cxx
    
    a3c75e626edee3ad28ad5b7eb80f729ae8aaa83f
    
    Change-Id: I3ab7ab6aec1d782de0733064fea031c895f28965
    Reviewed-on: https://gerrit.libreoffice.org/15331
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 1c79f11..bacafa5 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -351,7 +351,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;
+    ScFormulaCell * const * GetFormulaCellBlockAddress( SCROW nRow, size_t& rBlockSize ) const;
     CellType    GetCellType( SCROW nRow ) const;
     SCSIZE      GetCellCount() const;
     sal_uInt32 GetWeightedCount() const;
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 943dcd6..0f22f79 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -2712,26 +2712,37 @@ void ScColumn::SetNumberFormat( SCROW nRow, sal_uInt32 nNumberFormat )
     ApplyAttr(nRow, SfxUInt32Item(ATTR_VALUE_FORMAT, nNumberFormat));
 }
 
-ScFormulaCell * const * ScColumn::GetFormulaCellBlockAddress( SCROW nRow ) const
+ScFormulaCell * const * ScColumn::GetFormulaCellBlockAddress( SCROW nRow, size_t& rBlockSize ) const
 {
     if (!ValidRow(nRow))
+    {
+        rBlockSize = 0;
         return NULL;
+    }
 
     std::pair<sc::CellStoreType::const_iterator,size_t> aPos = maCells.position(nRow);
     sc::CellStoreType::const_iterator it = aPos.first;
     if (it == maCells.end())
+    {
+        rBlockSize = 0;
         return NULL;
+    }
 
     if (it->type != sc::element_type_formula)
+    {
         // Not a formula cell.
+        rBlockSize = 0;
         return NULL;
+    }
 
+    rBlockSize = it->size;
     return &sc::formula_block::at(*it->data, aPos.second);
 }
 
 const ScFormulaCell* ScColumn::FetchFormulaCell( SCROW nRow ) const
 {
-    ScFormulaCell const * const * pp = GetFormulaCellBlockAddress( nRow );
+    size_t nBlockSize = 0;
+    ScFormulaCell const * const * pp = GetFormulaCellBlockAddress( nRow, nBlockSize );
     return pp ? *pp : NULL;
 }
 
diff --git a/sc/source/core/tool/grouparealistener.cxx b/sc/source/core/tool/grouparealistener.cxx
index be4b0f0..86be4f7 100644
--- a/sc/source/core/tool/grouparealistener.cxx
+++ b/sc/source/core/tool/grouparealistener.cxx
@@ -86,16 +86,18 @@ FormulaGroupAreaListener::FormulaGroupAreaListener( const ScRange& rRange, const
     assert(mpColumn);
     SAL_INFO( "sc.core.grouparealistener",
             "FormulaGroupAreaListener ctor this " << this <<
-            " range " << maRange.Format(SCA_VALID) <<
-            " mnTopCellRow " << mnTopCellRow << " length " << mnGroupLen);
+            " range " << (maRange == BCA_LISTEN_ALWAYS ? "LISTEN-ALWAYS" : maRange.Format(SCA_VALID)) <<
+            " mnTopCellRow " << mnTopCellRow << " length " << mnGroupLen <<
+            ", col/tab " << mpColumn->GetCol() << "/" << mpColumn->GetTab());
 }
 
 FormulaGroupAreaListener::~FormulaGroupAreaListener()
 {
     SAL_INFO( "sc.core.grouparealistener",
             "FormulaGroupAreaListener dtor this " << this <<
-            " range " << maRange.Format(SCA_VALID) <<
-            " mnTopCellRow " << mnTopCellRow << " length " << mnGroupLen);
+            " range " << (maRange == BCA_LISTEN_ALWAYS ? "LISTEN-ALWAYS" : maRange.Format(SCA_VALID)) <<
+            " mnTopCellRow " << mnTopCellRow << " length " << mnGroupLen <<
+            ", col/tab " << mpColumn->GetCol() << "/" << mpColumn->GetTab());
 }
 
 ScRange FormulaGroupAreaListener::getListeningRange() const
@@ -184,13 +186,33 @@ void FormulaGroupAreaListener::collectFormulaCells(
 {
     SAL_INFO( "sc.core.grouparealistener",
             "FormulaGroupAreaListener::collectFormulaCells() this " << this <<
-            " range " << maRange.Format(SCA_VALID) <<
-            " mnTopCellRow " << mnTopCellRow << " length " << mnGroupLen);
+            " range " << (maRange == BCA_LISTEN_ALWAYS ? "LISTEN-ALWAYS" : maRange.Format(SCA_VALID)) <<
+            " mnTopCellRow " << mnTopCellRow << " length " << mnGroupLen <<
+            ", col/tab " << mpColumn->GetCol() << "/" << mpColumn->GetTab());
 
-    ScFormulaCell* const * pp = mpColumn->GetFormulaCellBlockAddress( mnTopCellRow);
-    assert(pp);
+    size_t nBlockSize = 0;
+    ScFormulaCell* const * pp = mpColumn->GetFormulaCellBlockAddress( mnTopCellRow, nBlockSize);
     if (!pp)
+    {
+        SAL_WARN("sc", "GetFormulaCellBlockAddress not found");
         return;
+    }
+
+    /* FIXME: with tdf#89957 it happened that the actual block size in column
+     * AP (shifted from AO) of sheet 'w' was smaller than the remembered group
+     * length and correct. This is just a very ugly workaround, the real cause
+     * is yet unknown, but at least don't crash in such case. The intermediate
+     * cause is that not all affected group area listeners are destroyed and
+     * newly created, so mpColumn still points to the old column that then has
+     * the content of a shifted column. Effectively this workaround has the
+     * consequence that the group area listener is fouled up and not all
+     * formula cells are notified.. */
+    if (nBlockSize < static_cast<size_t>(mnGroupLen))
+    {
+        SAL_WARN("sc.core","FormulaGroupAreaListener::collectFormulaCells() nBlockSize " <<
+                nBlockSize << " < " << mnGroupLen << " mnGroupLen");
+        const_cast<FormulaGroupAreaListener*>(this)->mnGroupLen = static_cast<SCROW>(nBlockSize);
+    }
 
     ScFormulaCell* const * ppEnd = pp + mnGroupLen;
 
@@ -280,8 +302,9 @@ ScAddress FormulaGroupAreaListener::getTopCellPos() const
 
 const ScFormulaCell* FormulaGroupAreaListener::getTopCell() const
 {
-    const ScFormulaCell* const * pp = mpColumn->GetFormulaCellBlockAddress( mnTopCellRow);
-    assert(pp);
+    size_t nBlockSize = 0;
+    const ScFormulaCell* const * pp = mpColumn->GetFormulaCellBlockAddress( mnTopCellRow, nBlockSize);
+    SAL_WARN_IF(!pp, "sc", "GetFormulaCellBlockAddress not found");
     return pp ? *pp : NULL;
 }
 


More information about the Libreoffice-commits mailing list