diff options
author | Eike Rathke <erack@redhat.com> | 2015-01-28 13:47:39 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2015-02-17 13:34:19 +0000 |
commit | b5d2a648f179e61d6c543c72b4202def0d10495d (patch) | |
tree | cdbd2baef95f9ad28a23efa45a5d85db0659f913 | |
parent | 1706760769018662a50b494b2e4a0ca85c93ca42 (diff) |
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.
(cherry picked from commit 47230a036fe35b9a7a7c0609232849fcbb51efcc)
add some SAL_INFO to group area listener and formula cell ctor/dtor
guess we'll need them more often..
(cherry picked from commit f8d6640afa3c8528d2a66741edc49a48c67902d3)
let have FormulaGroupAreaListener a virtual dtor
(cherry picked from commit 0fafb53d1c860388461f30e613a37c128c90ad79)
0ef149fc5edceee765419764bf0efa571ba9d977
1f5e246d68971124ef21e9c2d0db80499928998b
Change-Id: I449a89005418aff7ea12099ea931b786959dbc3b
Reviewed-on: https://gerrit.libreoffice.org/14332
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r-- | include/sal/log-areas.dox | 2 | ||||
-rw-r--r-- | sc/inc/column.hxx | 1 | ||||
-rw-r--r-- | sc/inc/document.hxx | 2 | ||||
-rw-r--r-- | sc/inc/grouparealistener.hxx | 12 | ||||
-rw-r--r-- | sc/inc/table.hxx | 1 | ||||
-rw-r--r-- | sc/source/core/data/column2.cxx | 10 | ||||
-rw-r--r-- | sc/source/core/data/formulacell.cxx | 16 | ||||
-rw-r--r-- | sc/source/core/tool/grouparealistener.cxx | 52 |
8 files changed, 81 insertions, 15 deletions
diff --git a/include/sal/log-areas.dox b/include/sal/log-areas.dox index 65f0b049f6be..9b55f74f39a8 100644 --- a/include/sal/log-areas.dox +++ b/include/sal/log-areas.dox @@ -113,6 +113,8 @@ certain functionality. @li @c sc.opencl.thread - Background thread to compile OpenCL kernels @li @c sc.qa @li @c sc.core +@li @c sc.core.formulacell - ScFormulaCell and group +@li @c sc.core.grouparealistener - sc::FormulaGroupAreaListener @li @c sc.filter - Calc filter @li @c sc.ui - Calc UI diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 0cc342c7f0d9..1c79f1125294 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -351,6 +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; 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 f46ec567ad2d..8288518c9e17 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; } @@ -262,6 +263,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 feb10df0fb63..ec5c497e3141 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,10 @@ 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(); ScRange getListeningRange() const; @@ -64,6 +69,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 70662549b29d..ae43f33c77bc 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -219,6 +219,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 8cf3178af69f..943dcd6a5aa9 100644 --- a/sc/source/core/data/column2.cxx +++ b/sc/source/core/data/column2.cxx @@ -2712,7 +2712,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; @@ -2726,7 +2726,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 896e5d2cb152..9190a62d4f6a 100644 --- a/sc/source/core/data/formulacell.cxx +++ b/sc/source/core/data/formulacell.cxx @@ -460,6 +460,7 @@ ScFormulaCellGroup::ScFormulaCellGroup() : meCalcState(sc::GroupCalcEnabled), meKernelState(sc::OpenCLKernelNone) { + SAL_INFO( "sc.core.formulacell", "ScFormulaCellGroup ctor this " << this); #if ENABLE_THREADED_OPENCL_KERNEL_COMPILATION if (officecfg::Office::Common::Misc::UseOpenCL::get()) { @@ -476,6 +477,7 @@ ScFormulaCellGroup::ScFormulaCellGroup() : ScFormulaCellGroup::~ScFormulaCellGroup() { + SAL_INFO( "sc.core.formulacell", "ScFormulaCellGroup dtor this " << this); #if ENABLE_THREADED_OPENCL_KERNEL_COMPILATION if (officecfg::Office::Common::Misc::UseOpenCL::get()) { @@ -563,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; @@ -608,6 +610,7 @@ ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos ) : mbPostponedDirty(false), aPos(rPos) { + SAL_INFO( "sc.core.formulacell", "ScFormulaCell ctor this " << this); } ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos, @@ -637,6 +640,8 @@ ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos, mbPostponedDirty(false), aPos( rPos ) { + SAL_INFO( "sc.core.formulacell", "ScFormulaCell ctor this " << this); + Compile( rFormula, true, eGrammar ); // bNoListening, Insert does that if (!pCode) // We need to have a non-NULL token array instance at all times. @@ -669,6 +674,7 @@ ScFormulaCell::ScFormulaCell( mbPostponedDirty(false), aPos( rPos ) { + SAL_INFO( "sc.core.formulacell", "ScFormulaCell ctor this " << this); assert(pArray); // Never pass a NULL pointer here. // Generate RPN token array. @@ -717,6 +723,8 @@ ScFormulaCell::ScFormulaCell( mbPostponedDirty(false), aPos( rPos ) { + SAL_INFO( "sc.core.formulacell", "ScFormulaCell ctor this " << this); + // RPN array generation if( pCode->GetLen() && !pCode->GetCodeError() && !pCode->GetCodeLen() ) { @@ -764,6 +772,8 @@ ScFormulaCell::ScFormulaCell( mbPostponedDirty(false), aPos( rPos ) { + SAL_INFO( "sc.core.formulacell", "ScFormulaCell ctor this " << this); + if (bSubTotal) pDocument->AddSubTotalCell(this); } @@ -793,6 +803,8 @@ ScFormulaCell::ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, cons mbPostponedDirty(false), aPos( rPos ) { + SAL_INFO( "sc.core.formulacell", "ScFormulaCell ctor this " << this); + pCode = rCell.pCode->Clone(); // set back any errors and recompile @@ -889,6 +901,8 @@ ScFormulaCell::ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, cons ScFormulaCell::~ScFormulaCell() { + SAL_INFO( "sc.core.formulacell", "ScFormulaCell dtor this " << this); + pDocument->RemoveFromFormulaTrack( this ); pDocument->RemoveFromFormulaTree( this ); pDocument->RemoveSubTotalCell(this); diff --git a/sc/source/core/tool/grouparealistener.cxx b/sc/source/core/tool/grouparealistener.cxx index 224973238907..be4b0f01e533 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,15 +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) << + " mnTopCellRow " << mnTopCellRow << " length " << mnGroupLen); +} + +FormulaGroupAreaListener::~FormulaGroupAreaListener() +{ + SAL_INFO( "sc.core.grouparealistener", + "FormulaGroupAreaListener dtor this " << this << + " range " << maRange.Format(SCA_VALID) << + " mnTopCellRow " << mnTopCellRow << " length " << mnGroupLen); } ScRange FormulaGroupAreaListener::getListeningRange() const @@ -116,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); @@ -164,8 +182,17 @@ void FormulaGroupAreaListener::collectFormulaCells( void FormulaGroupAreaListener::collectFormulaCells( SCROW nRow1, SCROW nRow2, std::vector<ScFormulaCell*>& rCells ) const { - ScFormulaCell** pp = mppTopCell; - ScFormulaCell** ppEnd = pp + mnGroupLen; + SAL_INFO( "sc.core.grouparealistener", + "FormulaGroupAreaListener::collectFormulaCells() this " << this << + " range " << maRange.Format(SCA_VALID) << + " mnTopCellRow " << mnTopCellRow << " length " << mnGroupLen); + + ScFormulaCell* const * pp = mpColumn->GetFormulaCellBlockAddress( mnTopCellRow); + assert(pp); + if (!pp) + return; + + ScFormulaCell* const * ppEnd = pp + mnGroupLen; if (mbStartFixed) { @@ -247,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 |