[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