[Libreoffice-commits] core.git: Branch 'aoo/trunk' - sw/source

Oliver-Rainer Wittmann orw at apache.org
Mon Aug 19 03:11:00 PDT 2013


 sw/source/core/crsr/bookmrk.cxx  |    2 ++
 sw/source/core/doc/docbm.cxx     |   13 +++++++++++--
 sw/source/core/inc/bookmrk.hxx   |    5 +++++
 sw/source/ui/dochdl/swdtflvr.cxx |   22 ++++++++++++----------
 4 files changed, 30 insertions(+), 12 deletions(-)

New commits:
commit bf1b5979d2ce88265e73ee8fd11599a4374c4136
Author: Oliver-Rainer Wittmann <orw at apache.org>
Date:   Mon Aug 19 08:20:05 2013 +0000

    122902, 122922, 122992: - <MarkManager::deleteMark(..)> - assure that entry is removed from stl container before its deletion is triggered.
    
    - <SwTrnsfrDdeLink::Disconnect(..)> - do not delete DDE bookmark when it is already in its destruction

diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx
index 36f7736..e6d5dce 100644
--- a/sw/source/core/crsr/bookmrk.cxx
+++ b/sw/source/core/crsr/bookmrk.cxx
@@ -187,6 +187,7 @@ namespace sw { namespace mark
     DdeBookmark::DdeBookmark(const SwPaM& aPaM)
         : MarkBase(aPaM, MarkBase::GenerateNewName(our_sNamePrefix))
         , m_aRefObj(NULL)
+        , mbInDestruction( false )
     { }
 
     void DdeBookmark::SetRefObject(SwServerObject* pObj)
@@ -204,6 +205,7 @@ namespace sw { namespace mark
 
     DdeBookmark::~DdeBookmark()
     {
+        mbInDestruction = true;
         if( m_aRefObj.Is() )
         {
             if(m_aRefObj->HasDataLinks())
diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx
index d4dcdcf..ad88fb6 100644
--- a/sw/source/core/doc/docbm.cxx
+++ b/sw/source/core/doc/docbm.cxx
@@ -734,9 +734,18 @@ namespace sw { namespace mark
                 break;
         }
         DdeBookmark* const pDdeBookmark = dynamic_cast<DdeBookmark*>(ppMark->get());
-        if(pDdeBookmark)
+        if ( pDdeBookmark )
+        {
             pDdeBookmark->DeregisterFromDoc(m_pDoc);
-        m_vMarks.erase(m_vMarks.begin() + (ppMark - m_vMarks.begin())); // clumsy const-cast
+        }
+        // keep a temporary instance of the to-be-deleted mark in order to avoid
+        // recursive deletion of the mark triggered via its destructor.
+        // the temporary hold instance assures that the mark is deleted after the
+        // mark container has been updated. Thus, the mark could not be found anymore
+        // in the mark container by other calls trying to recursively delete the mark.
+        iterator_t aToBeDeletedMarkIter = m_vMarks.begin() + (ppMark - m_vMarks.begin());
+        pMark_t pToBeDeletedMark = *aToBeDeletedMarkIter;
+        m_vMarks.erase( aToBeDeletedMarkIter );
     }
 
     void MarkManager::deleteMark(const IMark* const pMark)
diff --git a/sw/source/core/inc/bookmrk.hxx b/sw/source/core/inc/bookmrk.hxx
index 92df083..aabf6dd 100644
--- a/sw/source/core/inc/bookmrk.hxx
+++ b/sw/source/core/inc/bookmrk.hxx
@@ -159,8 +159,13 @@ namespace sw { namespace mark
 
             void DeregisterFromDoc(SwDoc* const pDoc);
             virtual ~DdeBookmark();
+            inline bool IsInDestruction() const
+            {
+                return mbInDestruction;
+            }
         private:
             SwServerObjectRef m_aRefObj;
+            bool mbInDestruction;
             static const ::rtl::OUString our_sNamePrefix;
     };
 
diff --git a/sw/source/ui/dochdl/swdtflvr.cxx b/sw/source/ui/dochdl/swdtflvr.cxx
index 2f72917..08e4c2d 100644
--- a/sw/source/ui/dochdl/swdtflvr.cxx
+++ b/sw/source/ui/dochdl/swdtflvr.cxx
@@ -87,6 +87,7 @@
 #include <IDocumentUndoRedo.hxx>
 #include <pagedesc.hxx>
 #include <IMark.hxx>
+#include <bookmrk.hxx>
 #include <docary.hxx>
 #include <section.hxx>
 #include <ndtxt.hxx>
@@ -3771,12 +3772,6 @@ sal_Bool SwTrnsfrDdeLink::WriteData( SvStream& rStrm )
     rStrm.Write( pMem, nLen );
     delete[] pMem;
 
-    //if( bDelBookmrk )
-    //{
-    //  // er wird das erstemal abgeholt, also ins Undo mitaufnehmen
-    //  // aber wie??
-    //}
-
     IDocumentMarkAccess* const pMarkAccess = pDocShell->GetDoc()->getIDocumentMarkAccess();
     IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->findMark(sName);
     if(ppMark != pMarkAccess->getMarksEnd()
@@ -3822,7 +3817,7 @@ void SwTrnsfrDdeLink::Disconnect( sal_Bool bRemoveDataAdvise )
     //      kein DataChanged mehr entgegen nehmen, wenn man
     //      sich schon im Disconnet befindet!
     //      (DTOR vom Bookmark verschickt einen DataChanged!)
-    sal_Bool bOldDisconnect = bInDisconnect;
+    const sal_Bool bOldDisconnect = bInDisconnect;
     bInDisconnect = sal_True;
 
     // den nicht verwendeten Bookmark wieder zerstoeren (ohne Undo!)?
@@ -3838,13 +3833,20 @@ void SwTrnsfrDdeLink::Disconnect( sal_Bool bRemoveDataAdvise )
         sal_Bool bIsModified = pDoc->IsModified();
 
         IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
-        pMarkAccess->deleteMark(pMarkAccess->findMark(sName));
+        // check, if DdeBookmark is already in its desctruction
+        IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->findMark(sName);
+        if ( ppMark != pMarkAccess->getMarksEnd() )
+        {
+            ::sw::mark::DdeBookmark* const pDdeBookmark = dynamic_cast< ::sw::mark::DdeBookmark* >(ppMark->get());
+            if ( pDdeBookmark && !pDdeBookmark->IsInDestruction() )
+            {
+                pMarkAccess->deleteMark(ppMark);
+            }
+        }
 
         if( !bIsModified )
             pDoc->ResetModified();
-        // --> OD, CD, OS 2005-11-25 #i58448#
         pDoc->SetOle2Link( aSavedOle2Link );
-        // <--
 
         bDelBookmrk = sal_False;
     }


More information about the Libreoffice-commits mailing list