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
This commit is contained in:
parent
de68bb8514
commit
47230a036f
7 changed files with 52 additions and 18 deletions
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue