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@libreoffice.org> Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
This commit is contained in:
@@ -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 )
|
||||
|
@@ -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
|
||||
|
@@ -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; }
|
||||
|
@@ -175,7 +175,8 @@ SdPage::~SdPage()
|
||||
|
||||
clearChildNodes(mxAnimationNode);
|
||||
|
||||
Clear();
|
||||
// clear SdrObjects with broadcasting
|
||||
ClearSdrObjList();
|
||||
}
|
||||
|
||||
struct OrdNumSorter
|
||||
|
@@ -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++)
|
||||
{
|
||||
|
@@ -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())
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user