Collect all empty broadcasters and remove them in one go later.
This is to avoid repeated calls to set_empty() on the broadcaster array which causes array reallocation on each call. Instead, we can store the segments of broadcasters to be deleted later, and call set_empty() on those segments to reduce the number of calls to set_empty(). The meat of this is not implemented yet, as EndListeningContext is still empty. Change-Id: I914bc2881acee3902c4fec0f6c21aaf4d2489df8
This commit is contained in:
parent
180c2fe743
commit
410154e76c
13 changed files with 188 additions and 1 deletions
|
@ -139,6 +139,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
|
|||
sc/source/core/data/global \
|
||||
sc/source/core/data/global2 \
|
||||
sc/source/core/data/globalx \
|
||||
sc/source/core/data/listenercontext \
|
||||
sc/source/core/data/markarr \
|
||||
sc/source/core/data/markdata \
|
||||
sc/source/core/data/mtvelements \
|
||||
|
|
|
@ -48,6 +48,7 @@ namespace editeng { class SvxBorderLine; }
|
|||
|
||||
namespace sc {
|
||||
struct FormulaGroupContext;
|
||||
class EndListeningContext;
|
||||
}
|
||||
|
||||
class Fraction;
|
||||
|
@ -439,6 +440,7 @@ public:
|
|||
|
||||
void StartListening( SvtListener& rLst, SCROW nRow );
|
||||
void EndListening( SvtListener& rLst, SCROW nRow );
|
||||
void EndListening( sc::EndListeningContext& rCxt, SCROW nRow, SvtListener& rListener );
|
||||
void MoveListeners( SvtBroadcaster& rSource, SCROW nDestRow );
|
||||
void StartAllListeners();
|
||||
void StartNeededListeners(); // only for cells where NeedsListening()==true
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
namespace editeng { class SvxBorderLine; }
|
||||
namespace sc {
|
||||
struct FormulaGroupContext;
|
||||
class EndListeningContext;
|
||||
}
|
||||
class SvxFontItem;
|
||||
|
||||
|
@ -1754,6 +1755,8 @@ public:
|
|||
void EndListeningCell( const ScAddress& rAddress,
|
||||
SvtListener* pListener );
|
||||
|
||||
void EndListeningCell( sc::EndListeningContext& rCxt, const ScAddress& rPos, SvtListener& rListener );
|
||||
|
||||
void EndListeningFormulaCells( std::vector<ScFormulaCell*>& rCells );
|
||||
|
||||
void PutInFormulaTree( ScFormulaCell* pCell );
|
||||
|
|
|
@ -28,6 +28,12 @@
|
|||
|
||||
#include <set>
|
||||
|
||||
namespace sc {
|
||||
|
||||
class EndListeningContext;
|
||||
|
||||
}
|
||||
|
||||
class ScTokenArray;
|
||||
struct ScSimilarFormulaDelta;
|
||||
|
||||
|
@ -309,6 +315,7 @@ public:
|
|||
void StartListeningTo( ScDocument* pDoc );
|
||||
void EndListeningTo(
|
||||
ScDocument* pDoc, ScTokenArray* pArr = NULL, ScAddress aPos = ScAddress() );
|
||||
void EndListeningTo( sc::EndListeningContext& rCxt );
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
34
sc/inc/listenercontext.hxx
Normal file
34
sc/inc/listenercontext.hxx
Normal file
|
@ -0,0 +1,34 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef SC_LISTENERCONTEXT_HXX
|
||||
#define SC_LISTENERCONTEXT_HXX
|
||||
|
||||
#include "address.hxx"
|
||||
|
||||
class ScDocument;
|
||||
|
||||
namespace sc {
|
||||
|
||||
class EndListeningContext
|
||||
{
|
||||
ScDocument& mrDoc;
|
||||
public:
|
||||
EndListeningContext(ScDocument& rDoc);
|
||||
ScDocument& getDoc();
|
||||
|
||||
void addEmptyBroadcasterPosition(SCCOL nCol, SCROW nRow, SCTAB nTab);
|
||||
void purgeEmptyBroadcasters();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
|
@ -91,6 +91,8 @@ struct SC_DLLPUBLIC ScSingleRefData // Single reference (one address) int
|
|||
/// In external references nTab is -1
|
||||
inline bool ValidExternal() const;
|
||||
|
||||
ScAddress toAbs( const ScAddress& rPos ) const;
|
||||
|
||||
void SmartRelAbs( const ScAddress& rPos );
|
||||
void CalcRelFromAbs( const ScAddress& rPos );
|
||||
void CalcAbsIfRel( const ScAddress& rPos );
|
||||
|
|
|
@ -49,6 +49,7 @@ namespace com { namespace sun { namespace star {
|
|||
|
||||
namespace sc {
|
||||
struct FormulaGroupContext;
|
||||
class EndListeningContext;
|
||||
}
|
||||
|
||||
class SfxItemSet;
|
||||
|
@ -932,6 +933,7 @@ private:
|
|||
|
||||
void StartListening( const ScAddress& rAddress, SvtListener* pListener );
|
||||
void EndListening( const ScAddress& rAddress, SvtListener* pListener );
|
||||
void EndListening( sc::EndListeningContext& rCxt, SCCOL nCol, SCROW nRow, SvtListener& rListener );
|
||||
void StartAllListeners();
|
||||
void StartNeededListeners(); // only for cells where NeedsListening()==TRUE
|
||||
void SetRelNameDirty();
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#include "tokenarray.hxx"
|
||||
#include "globalnames.hxx"
|
||||
#include "formulagroup.hxx"
|
||||
#include "listenercontext.hxx"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
|
@ -1902,6 +1903,18 @@ void ScColumn::EndListening( SvtListener& rLst, SCROW nRow )
|
|||
maBroadcasters.set_empty(nRow, nRow);
|
||||
}
|
||||
|
||||
void ScColumn::EndListening( sc::EndListeningContext& rCxt, SCROW nRow, SvtListener& rListener )
|
||||
{
|
||||
SvtBroadcaster* pBC = GetBroadcaster(nRow);
|
||||
if (!pBC)
|
||||
return;
|
||||
|
||||
rListener.EndListening(*pBC);
|
||||
if (!pBC->HasListeners())
|
||||
// There is no more listeners for this cell. Add it to the purge list for later purging.
|
||||
rCxt.addEmptyBroadcasterPosition(nCol, nRow, nTab);
|
||||
}
|
||||
|
||||
void ScColumn::CompileDBFormula()
|
||||
{
|
||||
if ( !maItems.empty() )
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "colorscale.hxx"
|
||||
#include "sheetevents.hxx"
|
||||
#include "tokenarray.hxx"
|
||||
#include "listenercontext.hxx"
|
||||
|
||||
#include <tools/shl.hxx>
|
||||
|
||||
|
@ -200,14 +201,26 @@ void ScDocument::EndListeningCell( const ScAddress& rAddress,
|
|||
maTabs[nTab]->EndListening( rAddress, pListener );
|
||||
}
|
||||
|
||||
void ScDocument::EndListeningCell(
|
||||
sc::EndListeningContext& rCxt, const ScAddress& rPos, SvtListener& rListener )
|
||||
{
|
||||
if (!TableExists(rPos.Tab()))
|
||||
return;
|
||||
|
||||
maTabs[rPos.Tab()]->EndListening(rCxt, rPos.Col(), rPos.Row(), rListener);
|
||||
}
|
||||
|
||||
void ScDocument::EndListeningFormulaCells( std::vector<ScFormulaCell*>& rCells )
|
||||
{
|
||||
if (rCells.empty())
|
||||
return;
|
||||
|
||||
sc::EndListeningContext aCxt(*this);
|
||||
std::vector<ScFormulaCell*>::iterator it = rCells.begin(), itEnd = rCells.end();
|
||||
for (; it != itEnd; ++it)
|
||||
(*it)->EndListeningTo(this);
|
||||
(*it)->EndListeningTo(aCxt);
|
||||
|
||||
aCxt.purgeEmptyBroadcasters();
|
||||
}
|
||||
|
||||
void ScDocument::PutInFormulaTree( ScFormulaCell* pCell )
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "svl/intitem.hxx"
|
||||
#include "rtl/strbuf.hxx"
|
||||
#include "formulagroup.hxx"
|
||||
#include "listenercontext.hxx"
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
|
@ -3329,4 +3330,62 @@ void ScFormulaCell::EndListeningTo( ScDocument* pDoc, ScTokenArray* pArr,
|
|||
}
|
||||
}
|
||||
|
||||
void ScFormulaCell::EndListeningTo( sc::EndListeningContext& rCxt )
|
||||
{
|
||||
if (rCxt.getDoc().IsClipOrUndo() || IsInChangeTrack())
|
||||
return;
|
||||
|
||||
ScDocument& rDoc = rCxt.getDoc();
|
||||
rDoc.SetDetectiveDirty(true); // It has changed something
|
||||
|
||||
if (pCode->IsRecalcModeAlways())
|
||||
{
|
||||
rDoc.EndListeningArea(BCA_LISTEN_ALWAYS, this);
|
||||
return;
|
||||
}
|
||||
|
||||
pCode->Reset();
|
||||
ScToken* t;
|
||||
while ( ( t = static_cast<ScToken*>(pCode->GetNextReferenceRPN()) ) != NULL )
|
||||
{
|
||||
StackVar eType = t->GetType();
|
||||
ScSingleRefData& rRef1 = t->GetSingleRef();
|
||||
ScSingleRefData& rRef2 = (eType == svDoubleRef ? t->GetDoubleRef().Ref2 : rRef1);
|
||||
switch (eType)
|
||||
{
|
||||
case svSingleRef:
|
||||
{
|
||||
ScAddress aCell = rRef1.toAbs(aPos);
|
||||
if (aCell.IsValid())
|
||||
rDoc.EndListeningCell(rCxt, aCell, *this);
|
||||
}
|
||||
break;
|
||||
case svDoubleRef:
|
||||
{
|
||||
ScAddress aCell1 = rRef1.toAbs(aPos);
|
||||
ScAddress aCell2 = rRef2.toAbs(aPos);
|
||||
if (aCell1.IsValid() && aCell2.IsValid())
|
||||
{
|
||||
if (t->GetOpCode() == ocColRowNameAuto)
|
||||
{ // automagically
|
||||
if ( rRef1.IsColRel() )
|
||||
{ // ColName
|
||||
aCell2.SetRow(MAXROW);
|
||||
}
|
||||
else
|
||||
{ // RowName
|
||||
aCell2.SetCol(MAXCOL);
|
||||
}
|
||||
}
|
||||
|
||||
rDoc.EndListeningArea(ScRange(aCell1, aCell2), this);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
; // nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
|
32
sc/source/core/data/listenercontext.cxx
Normal file
32
sc/source/core/data/listenercontext.cxx
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "listenercontext.hxx"
|
||||
#include "document.hxx"
|
||||
|
||||
namespace sc {
|
||||
|
||||
EndListeningContext::EndListeningContext(ScDocument& rDoc) : mrDoc(rDoc) {}
|
||||
|
||||
ScDocument& EndListeningContext::getDoc()
|
||||
{
|
||||
return mrDoc;
|
||||
}
|
||||
|
||||
void EndListeningContext::addEmptyBroadcasterPosition(SCCOL nCol, SCROW nRow, SCTAB nTab)
|
||||
{
|
||||
}
|
||||
|
||||
void EndListeningContext::purgeEmptyBroadcasters()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
|
@ -1097,6 +1097,14 @@ void ScTable::EndListening( const ScAddress& rAddress, SvtListener* pListener )
|
|||
aCol[rAddress.Col()].EndListening( *pListener, rAddress.Row() );
|
||||
}
|
||||
|
||||
void ScTable::EndListening( sc::EndListeningContext& rCxt, SCCOL nCol, SCROW nRow, SvtListener& rListener )
|
||||
{
|
||||
if (!ValidCol(nCol))
|
||||
return;
|
||||
|
||||
aCol[nCol].EndListening(rCxt, nRow, rListener);
|
||||
}
|
||||
|
||||
void ScTable::SetPageStyle( const OUString& rName )
|
||||
{
|
||||
if ( aPageStyle != rName )
|
||||
|
|
|
@ -27,6 +27,17 @@ void ScSingleRefData::CalcRelFromAbs( const ScAddress& rPos )
|
|||
nRelTab = nTab - rPos.Tab();
|
||||
}
|
||||
|
||||
ScAddress ScSingleRefData::toAbs( const ScAddress& rPos ) const
|
||||
{
|
||||
SCCOL nRetCol = Flags.bColRel ? nRelCol + rPos.Col() : nCol;
|
||||
SCROW nRetRow = Flags.bRowRel ? nRelRow + rPos.Row() : nRow;
|
||||
SCTAB nRetTab = Flags.bTabRel ? nRelTab + rPos.Tab() : nTab;
|
||||
|
||||
if (!ValidCol(nRetCol) || !ValidRow(nRetRow) || !ValidTab(nRetTab))
|
||||
return ScAddress(ScAddress::INITIALIZE_INVALID);
|
||||
|
||||
return ScAddress(nRetCol, nRetRow, nRetTab);
|
||||
}
|
||||
|
||||
void ScSingleRefData::SmartRelAbs( const ScAddress& rPos )
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue