summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2015-04-14 23:09:46 +0200
committerCaolán McNamara <caolanm@redhat.com>2015-04-21 13:07:49 +0000
commit5c6f7f0920a91c974e9639f2c751582c8f140b2b (patch)
tree67ba4ce68067e3cac55aeaae88532253327a9abd
parentc93eaee6af54f4786af16c602ddb3dc21331a5a6 (diff)
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@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r--sc/inc/column.hxx2
-rw-r--r--sc/source/core/data/column2.cxx15
-rw-r--r--sc/source/core/tool/grouparealistener.cxx43
3 files changed, 47 insertions, 13 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 1c79f1125294..bacafa5f0962 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 943dcd6a5aa9..0f22f7974a03 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 be4b0f01e533..86be4f736d92 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;
}