diff options
author | Kohei Yoshida <kyoshida@novell.com> | 2011-05-06 01:12:37 -0400 |
---|---|---|
committer | Kohei Yoshida <kyoshida@novell.com> | 2011-05-06 01:12:37 -0400 |
commit | 0ae3f088e40f9c2cb8a207db920b447555a9d14b (patch) | |
tree | 42954f1bc7c4ad94f257c77b6270d600b9229a35 | |
parent | d27a9990830d5742aa71c241723e2e5a0c050ed4 (diff) |
Wrong approach. You can't use remove_if with set.
std::remove_if is only for sequence containers, not for associative
containers. Sure enough, using that caused crash on closing the
document. This fixes it.
-rw-r--r-- | sc/source/ui/docshell/externalrefmgr.cxx | 65 |
1 files changed, 43 insertions, 22 deletions
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx index 59365c103763..d1cc63656cc9 100644 --- a/sc/source/ui/docshell/externalrefmgr.cxx +++ b/sc/source/ui/docshell/externalrefmgr.cxx @@ -203,34 +203,55 @@ private: }; /** - * Predicate used to determine whether a named range contains an external - * reference to a particular document. + * Check whether a named range contains an external reference to a + * particular document. */ -class RangeNameWithExtRef : unary_function<ScRangeData, bool> +bool hasRefsToSrcDoc(ScRangeData& rData, sal_uInt16 nFileId) { - sal_uInt16 mnFileId; -public: - RangeNameWithExtRef(sal_uInt16 nFileId) : mnFileId(nFileId) {} - bool operator() (ScRangeData& rData) const + ScTokenArray* pArray = rData.GetCode(); + if (!pArray) + return false; + + pArray->Reset(); + ScToken* p = static_cast<ScToken*>(pArray->GetNextReference()); + for (; p; p = static_cast<ScToken*>(pArray->GetNextReference())) { - ScTokenArray* pArray = rData.GetCode(); - if (!pArray) - return false; + if (!p->IsExternalRef()) + continue; - pArray->Reset(); - ScToken* p = static_cast<ScToken*>(pArray->GetNextReference()); - for (; p; p = static_cast<ScToken*>(pArray->GetNextReference())) - { - if (!p->IsExternalRef()) - continue; + if (p->GetIndex() == nFileId) + return true; + } + return false; +} - if (p->GetIndex() == mnFileId) - return true; - } - return false; +class EraseRangeByIterator : unary_function<ScRangeName::iterator, void> +{ + ScRangeName& mrRanges; +public: + EraseRangeByIterator(ScRangeName& rRanges) : mrRanges(rRanges) {} + void operator() (const ScRangeName::iterator& itr) + { + mrRanges.erase(itr); } }; +/** + * Remove all named ranges that contain references to specified source + * document. + */ +void removeRangeNamesBySrcDoc(ScRangeName& rRanges, sal_uInt16 nFileId) +{ + ScRangeName::iterator itr = rRanges.begin(), itrEnd = rRanges.end(); + vector<ScRangeName::iterator> v; + for (; itr != itrEnd; ++itr) + { + if (hasRefsToSrcDoc(*itr, nFileId)) + v.push_back(itr); + } + for_each(v.begin(), v.end(), EraseRangeByIterator(rRanges)); +} + } // ============================================================================ @@ -2427,14 +2448,14 @@ void ScExternalRefManager::breakLink(sal_uInt16 nFileId) // Global named ranges. ScRangeName* pRanges = mpDoc->GetRangeName(); if (pRanges) - remove_if(pRanges->begin(), pRanges->end(), RangeNameWithExtRef(nFileId)); + removeRangeNamesBySrcDoc(*pRanges, nFileId); // Sheet-local named ranges. for (SCTAB i = 0, n = mpDoc->GetTableCount(); i < n; ++i) { pRanges = mpDoc->GetRangeName(i); if (pRanges) - remove_if(pRanges->begin(), pRanges->end(), RangeNameWithExtRef(nFileId)); + removeRangeNamesBySrcDoc(*pRanges, nFileId); } maRefCells.erase(nFileId); |