[Libreoffice-commits] .: Branch 'libreoffice-3-4' - sc/source

Kohei Yoshida kohei at kemper.freedesktop.org
Thu May 5 22:14:44 PDT 2011


 sc/source/ui/docshell/externalrefmgr.cxx |   65 ++++++++++++++++++++-----------
 1 file changed, 43 insertions(+), 22 deletions(-)

New commits:
commit 3d28f8b19427588df949d613791350f5e17baab0
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Fri May 6 01:12:37 2011 -0400

    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.

diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index 59365c1..d1cc636 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);


More information about the Libreoffice-commits mailing list