diff options
Diffstat (limited to 'sc/source/core/data/formulacell.cxx')
-rw-r--r-- | sc/source/core/data/formulacell.cxx | 59 |
1 files changed, 53 insertions, 6 deletions
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx index dfeda726016f..a34d3fb139f4 100644 --- a/sc/source/core/data/formulacell.cxx +++ b/sc/source/core/data/formulacell.cxx @@ -61,6 +61,7 @@ #include <grouparealistener.hxx> #include <boost/scoped_ptr.hpp> +#include <boost/ptr_container/ptr_map.hpp> using namespace formula; @@ -382,6 +383,40 @@ void adjustDBRange(formula::FormulaToken* pToken, ScDocument& rNewDoc, const ScD pToken->SetIndex(pNewDBData->GetIndex()); } +struct AreaListenerKey +{ + ScRange maRange; + bool mbStartFixed; + bool mbEndFixed; + + AreaListenerKey( const ScRange& rRange, bool bStartFixed, bool bEndFixed ) : + maRange(rRange), mbStartFixed(bStartFixed), mbEndFixed(bEndFixed) {} + + bool operator < ( const AreaListenerKey& r ) const + { + if (maRange.aStart.Tab() != r.maRange.aStart.Tab()) + return maRange.aStart.Tab() < r.maRange.aStart.Tab(); + if (maRange.aStart.Col() != r.maRange.aStart.Col()) + return maRange.aStart.Col() < r.maRange.aStart.Col(); + if (maRange.aStart.Row() != r.maRange.aStart.Row()) + return maRange.aStart.Row() < r.maRange.aStart.Row(); + if (maRange.aEnd.Tab() != r.maRange.aEnd.Tab()) + return maRange.aEnd.Tab() < r.maRange.aEnd.Tab(); + if (maRange.aEnd.Col() != r.maRange.aEnd.Col()) + return maRange.aEnd.Col() < r.maRange.aEnd.Col(); + if (maRange.aEnd.Row() != r.maRange.aEnd.Row()) + return maRange.aEnd.Row() < r.maRange.aEnd.Row(); + if (mbStartFixed != r.mbStartFixed) + return r.mbStartFixed; + if (mbEndFixed != r.mbEndFixed) + return r.mbEndFixed; + + return false; + } +}; + +typedef boost::ptr_map<AreaListenerKey, sc::FormulaGroupAreaListener> AreaListenersType; + } #if ENABLE_THREADED_OPENCL_KERNEL_COMPILATION @@ -406,7 +441,13 @@ int ScFormulaCellGroup::snCount = 0; rtl::Reference<sc::CLBuildKernelThread> ScFormulaCellGroup::sxCompilationThread; #endif +struct ScFormulaCellGroup::Impl +{ + AreaListenersType maAreaListeners; +}; + ScFormulaCellGroup::ScFormulaCellGroup() : + mpImpl(new Impl), mnRefCount(0), mpCode(NULL), mpCompiledFormula(NULL), @@ -450,6 +491,7 @@ ScFormulaCellGroup::~ScFormulaCellGroup() #endif delete mpCode; delete mpCompiledFormula; + delete mpImpl; } void ScFormulaCellGroup::scheduleCompilation() @@ -512,24 +554,29 @@ void ScFormulaCellGroup::compileOpenCLKernel() sc::FormulaGroupAreaListener* ScFormulaCellGroup::getAreaListener( ScFormulaCell** ppTopCell, const ScRange& rRange, bool bStartFixed, bool bEndFixed ) { - // TODO : Find existing one with the same criteria. - maAreaListeners.push_back(new sc::FormulaGroupAreaListener(rRange, ppTopCell, mnLength, bStartFixed, bEndFixed)); - return &maAreaListeners.back(); + AreaListenerKey aKey(rRange, bStartFixed, bEndFixed); + + std::pair<AreaListenersType::iterator, bool> r = + mpImpl->maAreaListeners.insert( + aKey, new sc::FormulaGroupAreaListener( + rRange, ppTopCell, mnLength, bStartFixed, bEndFixed)); + + return r.first->second; } void ScFormulaCellGroup::endAllGroupListening( ScDocument& rDoc ) { - AreaListenersType::iterator it = maAreaListeners.begin(), itEnd = maAreaListeners.end(); + AreaListenersType::iterator it = mpImpl->maAreaListeners.begin(), itEnd = mpImpl->maAreaListeners.end(); for (; it != itEnd; ++it) { - sc::FormulaGroupAreaListener* pListener = &(*it); + sc::FormulaGroupAreaListener* pListener = it->second; ScRange aListenRange = pListener->getListeningRange(); // This "always listen" special range is never grouped. bool bGroupListening = (aListenRange != BCA_LISTEN_ALWAYS); rDoc.EndListeningArea(aListenRange, bGroupListening, pListener); } - maAreaListeners.clear(); + mpImpl->maAreaListeners.clear(); } ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos ) : |