[Libreoffice-commits] core.git: basctl/source include/svx sd/source svx/source

Armin Le Grand Armin.Le.Grand at cib.de
Fri May 4 12:49:01 UTC 2018


 basctl/source/dlged/dlged.cxx     |    5 +-
 basctl/source/dlged/dlgedpage.cxx |    3 -
 include/svx/svdpage.hxx           |   15 ++++++
 sd/source/core/sdpage.cxx         |    3 -
 svx/source/dialog/contwnd.cxx     |    3 -
 svx/source/dialog/imapwnd.cxx     |    4 -
 svx/source/svdraw/svdpage.cxx     |   82 +++++++++++++++++++++-----------------
 7 files changed, 72 insertions(+), 43 deletions(-)

New commits:
commit 0fe7bda233da3c1f95a82c0050c8f917dc39c22e
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
Date:   Fri May 4 11:21:15 2018 +0200

    tdf#116879 Separate SdrObjList::Clear() as needed
    
    SdrObjList::Clear() does broadcast the SdrObject
    removals and deletions and a SetChanged() to SdrModel.
    The old version avoided this in the destructor (with
    a comment to not call virtual methods in destructor,
    but  the problem is more that the ::Notify triggered
    works on the SdrPage already in destruction). To allow
    calls to Clear() without broadcasting I splitted this
    to a impClearSdrObjList(bool bBrodacast) and rename
    of ::Clear to ::ClearSdrObjList to get all places.
    Adapted all places in the code as needed, already pre-
    checked on Linux that this fixes the problem.
    
    Change-Id: Iea46758fb6b57f2b3d9896959a35260c6f6d52d5
    Reviewed-on: https://gerrit.libreoffice.org/53839
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Armin Le Grand <Armin.Le.Grand at cib.de>

diff --git a/basctl/source/dlged/dlged.cxx b/basctl/source/dlged/dlged.cxx
index 186e83521b05..f3755414bfb3 100644
--- a/basctl/source/dlged/dlged.cxx
+++ b/basctl/source/dlged/dlged.cxx
@@ -414,7 +414,10 @@ void DlgEditor::ResetDialog ()
     SdrPageView* pPgView = pDlgEdView->GetSdrPageView();
     bool bWasMarked = pDlgEdView->IsObjMarked( pOldDlgEdForm );
     pDlgEdView->UnmarkAll();
-    pPage->Clear();
+
+    // clear SdrObjects with broadcasting
+    pPage->ClearSdrObjList();
+
     pPage->SetDlgEdForm( nullptr );
     SetDialog( m_xUnoControlDialogModel );
     if( bWasMarked )
diff --git a/basctl/source/dlged/dlgedpage.cxx b/basctl/source/dlged/dlgedpage.cxx
index da9ba12ef1b0..73241128d447 100644
--- a/basctl/source/dlged/dlgedpage.cxx
+++ b/basctl/source/dlged/dlgedpage.cxx
@@ -34,7 +34,8 @@ DlgEdPage::DlgEdPage(DlgEdModel& rModel, bool bMasterPage)
 
 DlgEdPage::~DlgEdPage()
 {
-    Clear();
+    // clear SdrObjects with broadcasting
+    ClearSdrObjList();
 }
 
 SdrPage* DlgEdPage::Clone(SdrModel* const pNewModel) const
diff --git a/include/svx/svdpage.hxx b/include/svx/svdpage.hxx
index a4cc40feebd4..fa5364bae022 100644
--- a/include/svx/svdpage.hxx
+++ b/include/svx/svdpage.hxx
@@ -88,13 +88,24 @@ protected:
 private:
     /// simple ActionChildInserted forwarder to have it on a central place
     static void impChildInserted(SdrObject const & rChild);
+
+    // tdf#116879 Clear SdrObjList, no Undo done. Used from destructor, but also
+    // from other places. When used from destructor, suppress broadcasts
+    // to not get callbacks to evtl. derived objects already in destruction
+    // (e.g. SdrPage)
+    void impClearSdrObjList(bool bBroadcast);
+
 public:
     SdrObjList(SdrPage* pNewPage = nullptr);
     virtual ~SdrObjList();
 
     void CopyObjects(const SdrObjList& rSrcList, SdrModel* pNewModel = nullptr);
-    /// clean up everything (without Undo)
-    void    Clear();
+
+    // tdf#116879 clean up everything (without Undo), plus broadcasting
+    // changes. Split to this call and a private one (impClearSdrObjList)
+    // that allows cleanup without broadcasting in the destructor
+    void ClearSdrObjList();
+
     SdrObjListKind GetListKind() const                  { return eListKind; }
     void           SetListKind(SdrObjListKind eNewKind) { eListKind=eNewKind; }
     SdrObjList*    GetUpList() const                    { return pUpList; }
diff --git a/sd/source/core/sdpage.cxx b/sd/source/core/sdpage.cxx
index fc60775f6cef..aadb6a91e905 100644
--- a/sd/source/core/sdpage.cxx
+++ b/sd/source/core/sdpage.cxx
@@ -175,7 +175,8 @@ SdPage::~SdPage()
 
     clearChildNodes(mxAnimationNode);
 
-    Clear();
+    // clear SdrObjects with broadcasting
+    ClearSdrObjList();
 }
 
 struct OrdNumSorter
diff --git a/svx/source/dialog/contwnd.cxx b/svx/source/dialog/contwnd.cxx
index 4ac1e23083d5..014a10d9e472 100644
--- a/svx/source/dialog/contwnd.cxx
+++ b/svx/source/dialog/contwnd.cxx
@@ -54,7 +54,8 @@ void ContourWindow::SetPolyPolygon(const tools::PolyPolygon& rPolyPoly)
     // them first (!)
     pView->UnmarkAllObj();
 
-    pPage->Clear();
+    // clear SdrObjects with broadcasting
+    pPage->ClearSdrObjList();
 
     for (sal_uInt16 i = 0; i < nPolyCount; i++)
     {
diff --git a/svx/source/dialog/imapwnd.cxx b/svx/source/dialog/imapwnd.cxx
index 3e3f1667fbf2..6275842c6791 100644
--- a/svx/source/dialog/imapwnd.cxx
+++ b/svx/source/dialog/imapwnd.cxx
@@ -101,8 +101,8 @@ void IMapWindow::ReplaceImageMap( const ImageMap& rImageMap )
 
     if(pPage)
     {
-        // clear all draw objects
-        pPage->Clear();
+        // clear SdrObjects with broadcasting
+        pPage->ClearSdrObjList();
     }
 
     if(GetSdrView())
diff --git a/svx/source/svdraw/svdpage.cxx b/svx/source/svdraw/svdpage.cxx
index a5d16568e049..b5a7f81abccf 100644
--- a/svx/source/svdraw/svdpage.cxx
+++ b/svx/source/svdraw/svdpage.cxx
@@ -84,9 +84,52 @@ SdrObjList::SdrObjList(SdrPage* pNewPage)
     eListKind=SdrObjListKind::Unknown;
 }
 
+void SdrObjList::impClearSdrObjList(bool bBroadcast)
+{
+    SdrModel* pSdrModelFromRemovedSdrObject(nullptr);
+
+    while(!maList.empty())
+    {
+        // remove last object from list
+        SdrObject* pObj = maList.back();
+        RemoveObjectFromContainer(maList.size()-1);
+
+        // flushViewObjectContacts() is done since SdrObject::Free is not guaranteed
+        // to delete the object and thus refresh visualisations
+        pObj->GetViewContact().flushViewObjectContacts();
+
+        if(bBroadcast)
+        {
+            if(nullptr == pSdrModelFromRemovedSdrObject)
+            {
+                pSdrModelFromRemovedSdrObject = &pObj->getSdrModelFromSdrObject();
+            }
+
+            // sent remove hint (after removal, see RemoveObject())
+            SdrHint aHint(SdrHintKind::ObjectRemoved, *pObj, mpPage);
+            pObj->getSdrModelFromSdrObject().Broadcast(aHint);
+        }
+
+        // delete the object itself
+        SdrObject::Free( pObj );
+    }
+
+    if(bBroadcast && nullptr != pSdrModelFromRemovedSdrObject)
+    {
+        pSdrModelFromRemovedSdrObject->SetChanged();
+    }
+}
+
+void SdrObjList::ClearSdrObjList()
+{
+    // clear SdrObjects with broadcasting
+    impClearSdrObjList(true);
+}
+
 SdrObjList::~SdrObjList()
 {
-    Clear(); // delete contents of container
+    // clear SdrObjects without broadcasting
+    impClearSdrObjList(false);
 }
 
 void SdrObjList::copyDataFromSdrObjList(const SdrObjList& rSrcList, SdrModel* pNewModelel)
@@ -99,7 +142,9 @@ void SdrObjList::copyDataFromSdrObjList(const SdrObjList& rSrcList, SdrModel* pN
 
 void SdrObjList::CopyObjects(const SdrObjList& rSrcList, SdrModel* pNewModelel)
 {
-    Clear();
+    // clear SdrObjects with broadcasting
+    ClearSdrObjList();
+
     bObjOrdNumsDirty = false;
     bRectsDirty = false;
     size_t nCloneErrCnt(0);
@@ -187,39 +232,6 @@ void SdrObjList::CopyObjects(const SdrObjList& rSrcList, SdrModel* pNewModelel)
     }
 }
 
-void SdrObjList::Clear()
-{
-    SdrModel* pSdrModelFromRemovedSdrObject(nullptr);
-
-    while(!maList.empty())
-    {
-        // remove last object from list
-        SdrObject* pObj = maList.back();
-        RemoveObjectFromContainer(maList.size()-1);
-
-        // flushViewObjectContacts() is done since SdrObject::Free is not guaranteed
-        // to delete the object and thus refresh visualisations
-        pObj->GetViewContact().flushViewObjectContacts();
-
-        if(nullptr == pSdrModelFromRemovedSdrObject)
-        {
-            pSdrModelFromRemovedSdrObject = &pObj->getSdrModelFromSdrObject();
-        }
-
-        // sent remove hint (after removal, see RemoveObject())
-        SdrHint aHint(SdrHintKind::ObjectRemoved, *pObj, mpPage);
-        pObj->getSdrModelFromSdrObject().Broadcast(aHint);
-
-        // delete the object itself
-        SdrObject::Free( pObj );
-    }
-
-    if(nullptr != pSdrModelFromRemovedSdrObject)
-    {
-        pSdrModelFromRemovedSdrObject->SetChanged();
-    }
-}
-
 SdrPage* SdrObjList::GetPage() const
 {
     return mpPage;


More information about the Libreoffice-commits mailing list