summaryrefslogtreecommitdiffstats
path: root/sw/source/core/undo/undraw.cxx
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
commit940b4d1848e8c70ab7642901a68594e8016caffc (patch)
treeeb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /sw/source/core/undo/undraw.cxx
parentInitial commit. (diff)
downloadlibreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.tar.xz
libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.zip
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sw/source/core/undo/undraw.cxx')
-rw-r--r--sw/source/core/undo/undraw.cxx559
1 files changed, 559 insertions, 0 deletions
diff --git a/sw/source/core/undo/undraw.cxx b/sw/source/core/undo/undraw.cxx
new file mode 100644
index 000000000..b6c8bd521
--- /dev/null
+++ b/sw/source/core/undo/undraw.cxx
@@ -0,0 +1,559 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <UndoDraw.hxx>
+
+#include <svx/svdogrp.hxx>
+#include <svx/svdundo.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdmark.hxx>
+#include <svx/svdview.hxx>
+
+#include <hintids.hxx>
+#include <hints.hxx>
+#include <fmtanchr.hxx>
+#include <fmtflcnt.hxx>
+#include <txtflcnt.hxx>
+#include <frmfmt.hxx>
+#include <doc.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <IDocumentLayoutAccess.hxx>
+#include <docary.hxx>
+#include <swundo.hxx>
+#include <pam.hxx>
+#include <ndtxt.hxx>
+#include <UndoCore.hxx>
+#include <dcontact.hxx>
+#include <viewsh.hxx>
+#include <frameformats.hxx>
+
+struct SwUndoGroupObjImpl
+{
+ SwDrawFrameFormat* pFormat;
+ SdrObject* pObj;
+ sal_uLong nNodeIdx;
+};
+
+// Draw-Objecte
+
+void SwDoc::AddDrawUndo( std::unique_ptr<SdrUndoAction> pUndo )
+{
+ if (GetIDocumentUndoRedo().DoesUndo() &&
+ GetIDocumentUndoRedo().DoesDrawUndo())
+ {
+ const SdrMarkList* pMarkList = nullptr;
+ SwViewShell* pSh = getIDocumentLayoutAccess().GetCurrentViewShell();
+ if( pSh && pSh->HasDrawView() )
+ pMarkList = &pSh->GetDrawView()->GetMarkedObjectList();
+
+ GetIDocumentUndoRedo().AppendUndo( std::make_unique<SwSdrUndo>(std::move(pUndo), pMarkList, this) );
+ }
+}
+
+SwSdrUndo::SwSdrUndo( std::unique_ptr<SdrUndoAction> pUndo, const SdrMarkList* pMrkLst, const SwDoc* pDoc )
+ : SwUndo( SwUndoId::DRAWUNDO, pDoc ), m_pSdrUndo( std::move(pUndo) )
+{
+ if( pMrkLst && pMrkLst->GetMarkCount() )
+ m_pMarkList.reset( new SdrMarkList( *pMrkLst ) );
+}
+
+SwSdrUndo::~SwSdrUndo()
+{
+ m_pSdrUndo.reset();
+ m_pMarkList.reset();
+}
+
+void SwSdrUndo::UndoImpl(::sw::UndoRedoContext & rContext)
+{
+ m_pSdrUndo->Undo();
+ rContext.SetSelections(nullptr, m_pMarkList.get());
+}
+
+void SwSdrUndo::RedoImpl(::sw::UndoRedoContext & rContext)
+{
+ m_pSdrUndo->Redo();
+ rContext.SetSelections(nullptr, m_pMarkList.get());
+}
+
+OUString SwSdrUndo::GetComment() const
+{
+ return m_pSdrUndo->GetComment();
+}
+
+static void lcl_SendRemoveToUno( SwFormat& rFormat )
+{
+ SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT, &rFormat );
+ rFormat.ModifyNotification( &aMsgHint, &aMsgHint );
+}
+
+static void lcl_SaveAnchor( SwFrameFormat* pFormat, sal_uLong& rNodePos )
+{
+ const SwFormatAnchor& rAnchor = pFormat->GetAnchor();
+ if ((RndStdIds::FLY_AT_PARA == rAnchor.GetAnchorId()) ||
+ (RndStdIds::FLY_AT_CHAR == rAnchor.GetAnchorId()) ||
+ (RndStdIds::FLY_AT_FLY == rAnchor.GetAnchorId()) ||
+ (RndStdIds::FLY_AS_CHAR == rAnchor.GetAnchorId()))
+ {
+ rNodePos = rAnchor.GetContentAnchor()->nNode.GetIndex();
+ sal_Int32 nContentPos = 0;
+
+ if (RndStdIds::FLY_AS_CHAR == rAnchor.GetAnchorId())
+ {
+ nContentPos = rAnchor.GetContentAnchor()->nContent.GetIndex();
+
+ // destroy TextAttribute
+ SwTextNode *pTextNd = pFormat->GetDoc()->GetNodes()[ rNodePos ]->GetTextNode();
+ OSL_ENSURE( pTextNd, "No text node found!" );
+ SwTextFlyCnt* pAttr = static_cast<SwTextFlyCnt*>(
+ pTextNd->GetTextAttrForCharAt( nContentPos, RES_TXTATR_FLYCNT ));
+ // attribute still in text node, delete
+ if( pAttr && pAttr->GetFlyCnt().GetFrameFormat() == pFormat )
+ {
+ // just set pointer to 0, don't delete
+ const_cast<SwFormatFlyCnt&>(pAttr->GetFlyCnt()).SetFlyFormat();
+ SwIndex aIdx( pTextNd, nContentPos );
+ pTextNd->EraseText( aIdx, 1 );
+ }
+ }
+ else if (RndStdIds::FLY_AT_CHAR == rAnchor.GetAnchorId())
+ {
+ nContentPos = rAnchor.GetContentAnchor()->nContent.GetIndex();
+ }
+
+ pFormat->SetFormatAttr( SwFormatAnchor( rAnchor.GetAnchorId(), nContentPos ) );
+ }
+}
+
+static void lcl_RestoreAnchor( SwFrameFormat* pFormat, sal_uLong nNodePos )
+{
+ const SwFormatAnchor& rAnchor = pFormat->GetAnchor();
+ if ((RndStdIds::FLY_AT_PARA == rAnchor.GetAnchorId()) ||
+ (RndStdIds::FLY_AT_CHAR == rAnchor.GetAnchorId()) ||
+ (RndStdIds::FLY_AT_FLY == rAnchor.GetAnchorId()) ||
+ (RndStdIds::FLY_AS_CHAR == rAnchor.GetAnchorId()))
+ {
+ const sal_Int32 nContentPos = rAnchor.GetPageNum();
+ SwNodes& rNds = pFormat->GetDoc()->GetNodes();
+
+ SwNodeIndex aIdx( rNds, nNodePos );
+ SwPosition aPos( aIdx );
+
+ SwFormatAnchor aTmp( rAnchor.GetAnchorId() );
+ if ((RndStdIds::FLY_AS_CHAR == rAnchor.GetAnchorId()) ||
+ (RndStdIds::FLY_AT_CHAR == rAnchor.GetAnchorId()))
+ {
+ aPos.nContent.Assign( aIdx.GetNode().GetContentNode(), nContentPos );
+ }
+ aTmp.SetAnchor( &aPos );
+ RndStdIds nAnchorId = rAnchor.GetAnchorId();
+ pFormat->SetFormatAttr( aTmp );
+
+ if (RndStdIds::FLY_AS_CHAR == nAnchorId)
+ {
+ SwTextNode *pTextNd = aIdx.GetNode().GetTextNode();
+ OSL_ENSURE( pTextNd, "no Text Node" );
+ SwFormatFlyCnt aFormat( pFormat );
+ pTextNd->InsertItem( aFormat, nContentPos, nContentPos );
+ }
+ }
+}
+
+SwUndoDrawGroup::SwUndoDrawGroup( sal_uInt16 nCnt, const SwDoc* pDoc )
+ : SwUndo( SwUndoId::DRAWGROUP, pDoc ), m_nSize( nCnt + 1 ), m_bDeleteFormat( true )
+{
+ m_pObjArray.reset( new SwUndoGroupObjImpl[ m_nSize ] );
+}
+
+SwUndoDrawGroup::~SwUndoDrawGroup()
+{
+ if( m_bDeleteFormat )
+ {
+ SwUndoGroupObjImpl* pTmp = m_pObjArray.get() + 1;
+ for( sal_uInt16 n = 1; n < m_nSize; ++n, ++pTmp )
+ delete pTmp->pFormat;
+ }
+ else
+ delete m_pObjArray[0].pFormat;
+}
+
+void SwUndoDrawGroup::UndoImpl(::sw::UndoRedoContext &)
+{
+ m_bDeleteFormat = false;
+
+ // save group object
+ SwDrawFrameFormat* pFormat = m_pObjArray[0].pFormat;
+
+ pFormat->CallSwClientNotify(sw::ContactChangedHint(&m_pObjArray[0].pObj));
+ auto pObj = m_pObjArray[0].pObj;
+ pObj->SetUserCall(nullptr);
+
+ ::lcl_SaveAnchor( pFormat, m_pObjArray[0].nNodeIdx );
+
+ // notify UNO objects to decouple
+ ::lcl_SendRemoveToUno( *pFormat );
+
+ // remove from array
+ SwDoc* pDoc = pFormat->GetDoc();
+ SwFrameFormats& rFlyFormats = *pDoc->GetSpzFrameFormats();
+ rFlyFormats.erase( std::find( rFlyFormats.begin(), rFlyFormats.end(), pFormat ));
+
+ for( sal_uInt16 n = 1; n < m_nSize; ++n )
+ {
+ SwUndoGroupObjImpl& rSave = m_pObjArray[n];
+
+ ::lcl_RestoreAnchor( rSave.pFormat, rSave.nNodeIdx );
+ rFlyFormats.push_back( rSave.pFormat );
+
+ pObj = rSave.pObj;
+
+ SwDrawContact *pContact = new SwDrawContact( rSave.pFormat, pObj );
+ pContact->ConnectToLayout();
+ // #i45718# - follow-up of #i35635# move object to visible layer
+ pContact->MoveObjToVisibleLayer( pObj );
+
+ SwDrawFrameFormat* pDrawFrameFormat = rSave.pFormat;
+
+ // #i45952# - notify that position attributes are already set
+ OSL_ENSURE(pDrawFrameFormat,
+ "<SwUndoDrawGroup::Undo(..)> - wrong type of frame format for drawing object");
+ if (pDrawFrameFormat)
+ pDrawFrameFormat->PosAttrSet();
+ }
+}
+
+void SwUndoDrawGroup::RedoImpl(::sw::UndoRedoContext &)
+{
+ m_bDeleteFormat = true;
+
+ // remove from array
+ SwDoc* pDoc = m_pObjArray[0].pFormat->GetDoc();
+ SwFrameFormats& rFlyFormats = *pDoc->GetSpzFrameFormats();
+
+ for( sal_uInt16 n = 1; n < m_nSize; ++n )
+ {
+ SwUndoGroupObjImpl& rSave = m_pObjArray[n];
+
+ SdrObject* pObj = rSave.pObj;
+
+ SwDrawContact *pContact = static_cast<SwDrawContact*>(GetUserCall(pObj));
+
+ // object will destroy itself
+ pContact->Changed( *pObj, SdrUserCallType::Delete, pObj->GetLastBoundRect() );
+ pObj->SetUserCall( nullptr );
+
+ ::lcl_SaveAnchor( rSave.pFormat, rSave.nNodeIdx );
+
+ // notify UNO objects to decouple
+ ::lcl_SendRemoveToUno( *rSave.pFormat );
+
+ rFlyFormats.erase( std::find( rFlyFormats.begin(), rFlyFormats.end(), rSave.pFormat ));
+ }
+
+ // re-insert group object
+ ::lcl_RestoreAnchor( m_pObjArray[0].pFormat, m_pObjArray[0].nNodeIdx );
+ rFlyFormats.push_back( m_pObjArray[0].pFormat );
+
+ SwDrawContact *pContact = new SwDrawContact( m_pObjArray[0].pFormat, m_pObjArray[0].pObj );
+ // #i26791# - correction: connect object to layout
+ pContact->ConnectToLayout();
+ // #i45718# - follow-up of #i35635# move object to visible layer
+ pContact->MoveObjToVisibleLayer( m_pObjArray[0].pObj );
+
+ SwDrawFrameFormat* pDrawFrameFormat = m_pObjArray[0].pFormat;
+
+ // #i45952# - notify that position attributes are already set
+ OSL_ENSURE(pDrawFrameFormat,
+ "<SwUndoDrawGroup::Undo(..)> - wrong type of frame format for drawing object");
+ if (pDrawFrameFormat)
+ pDrawFrameFormat->PosAttrSet();
+}
+
+void SwUndoDrawGroup::AddObj( sal_uInt16 nPos, SwDrawFrameFormat* pFormat, SdrObject* pObj )
+{
+ SwUndoGroupObjImpl& rSave = m_pObjArray[nPos + 1];
+ rSave.pObj = pObj;
+ rSave.pFormat = pFormat;
+ ::lcl_SaveAnchor( pFormat, rSave.nNodeIdx );
+
+ // notify UNO objects to decouple
+ ::lcl_SendRemoveToUno( *pFormat );
+
+ // remove from array
+ SwFrameFormats& rFlyFormats = *pFormat->GetDoc()->GetSpzFrameFormats();
+ rFlyFormats.erase( std::find( rFlyFormats.begin(), rFlyFormats.end(), pFormat ));
+}
+
+void SwUndoDrawGroup::SetGroupFormat( SwDrawFrameFormat* pFormat )
+{
+ m_pObjArray[0].pObj = nullptr;
+ m_pObjArray[0].pFormat = pFormat;
+}
+
+SwUndoDrawUnGroup::SwUndoDrawUnGroup( SdrObjGroup* pObj, const SwDoc* pDoc )
+ : SwUndo( SwUndoId::DRAWUNGROUP, pDoc ), m_bDeleteFormat( false )
+{
+ m_nSize = static_cast<sal_uInt16>(pObj->GetSubList()->GetObjCount()) + 1;
+ m_pObjArray.reset( new SwUndoGroupObjImpl[ m_nSize ] );
+
+ SwDrawContact *pContact = static_cast<SwDrawContact*>(GetUserCall(pObj));
+ SwDrawFrameFormat* pFormat = static_cast<SwDrawFrameFormat*>(pContact->GetFormat());
+
+ m_pObjArray[0].pObj = pObj;
+ m_pObjArray[0].pFormat = pFormat;
+
+ // object will destroy itself
+ pContact->Changed( *pObj, SdrUserCallType::Delete, pObj->GetLastBoundRect() );
+ pObj->SetUserCall( nullptr );
+
+ ::lcl_SaveAnchor( pFormat, m_pObjArray[0].nNodeIdx );
+
+ // notify UNO objects to decouple
+ ::lcl_SendRemoveToUno( *pFormat );
+
+ // remove from array
+ SwFrameFormats& rFlyFormats = *pFormat->GetDoc()->GetSpzFrameFormats();
+ rFlyFormats.erase( std::find( rFlyFormats.begin(), rFlyFormats.end(), pFormat ));
+}
+
+SwUndoDrawUnGroup::~SwUndoDrawUnGroup()
+{
+ if( m_bDeleteFormat )
+ {
+ SwUndoGroupObjImpl* pTmp = m_pObjArray.get() + 1;
+ for( sal_uInt16 n = 1; n < m_nSize; ++n, ++pTmp )
+ delete pTmp->pFormat;
+ }
+ else
+ delete m_pObjArray[0].pFormat;
+}
+
+void SwUndoDrawUnGroup::UndoImpl(::sw::UndoRedoContext & rContext)
+{
+ m_bDeleteFormat = true;
+
+ SwDoc *const pDoc = & rContext.GetDoc();
+ SwFrameFormats& rFlyFormats = *pDoc->GetSpzFrameFormats();
+
+ // remove from array
+ for( sal_uInt16 n = 1; n < m_nSize; ++n )
+ {
+ SwUndoGroupObjImpl& rSave = m_pObjArray[n];
+
+ ::lcl_SaveAnchor( rSave.pFormat, rSave.nNodeIdx );
+
+ // notify UNO objects to decouple
+ ::lcl_SendRemoveToUno( *rSave.pFormat );
+
+ rFlyFormats.erase( std::find( rFlyFormats.begin(), rFlyFormats.end(), rSave.pFormat ));
+ }
+
+ // re-insert group object
+ ::lcl_RestoreAnchor( m_pObjArray[0].pFormat, m_pObjArray[0].nNodeIdx );
+ rFlyFormats.push_back( m_pObjArray[0].pFormat );
+
+ SwDrawContact *pContact = new SwDrawContact( m_pObjArray[0].pFormat, m_pObjArray[0].pObj );
+ pContact->ConnectToLayout();
+ // #i45718# - follow-up of #i35635# move object to visible layer
+ pContact->MoveObjToVisibleLayer( m_pObjArray[0].pObj );
+
+ SwDrawFrameFormat* pDrawFrameFormat = m_pObjArray[0].pFormat;
+
+ // #i45952# - notify that position attributes are already set
+ OSL_ENSURE(pDrawFrameFormat,
+ "<SwUndoDrawGroup::Undo(..)> - wrong type of frame format for drawing object");
+ if (pDrawFrameFormat)
+ pDrawFrameFormat->PosAttrSet();
+}
+
+void SwUndoDrawUnGroup::RedoImpl(::sw::UndoRedoContext &)
+{
+ m_bDeleteFormat = false;
+
+ // save group object
+ SwDrawFrameFormat* pFormat = m_pObjArray[0].pFormat;
+ pFormat->CallSwClientNotify(sw::ContactChangedHint(&(m_pObjArray[0].pObj)));
+ m_pObjArray[0].pObj->SetUserCall( nullptr );
+
+ ::lcl_SaveAnchor( pFormat, m_pObjArray[0].nNodeIdx );
+
+ // notify UNO objects to decouple
+ ::lcl_SendRemoveToUno( *pFormat );
+
+ // remove from array
+ SwDoc* pDoc = pFormat->GetDoc();
+ SwFrameFormats& rFlyFormats = *pDoc->GetSpzFrameFormats();
+ rFlyFormats.erase( std::find( rFlyFormats.begin(), rFlyFormats.end(), pFormat ));
+
+ for( sal_uInt16 n = 1; n < m_nSize; ++n )
+ {
+ SwUndoGroupObjImpl& rSave = m_pObjArray[n];
+
+ ::lcl_RestoreAnchor( rSave.pFormat, rSave.nNodeIdx );
+ rFlyFormats.push_back( rSave.pFormat );
+
+ SwDrawFrameFormat* pDrawFrameFormat = rSave.pFormat;
+
+ // #i45952# - notify that position attributes are already set
+ OSL_ENSURE(pDrawFrameFormat,
+ "<SwUndoDrawGroup::Undo(..)> - wrong type of frame format for drawing object" );
+ if (pDrawFrameFormat)
+ pDrawFrameFormat->PosAttrSet();
+ }
+}
+
+void SwUndoDrawUnGroup::AddObj( sal_uInt16 nPos, SwDrawFrameFormat* pFormat )
+{
+ SwUndoGroupObjImpl& rSave = m_pObjArray[ nPos + 1 ];
+ rSave.pFormat = pFormat;
+ rSave.pObj = nullptr;
+}
+
+SwUndoDrawUnGroupConnectToLayout::SwUndoDrawUnGroupConnectToLayout(const SwDoc* pDoc)
+ : SwUndo( SwUndoId::DRAWUNGROUP, pDoc )
+{
+}
+
+SwUndoDrawUnGroupConnectToLayout::~SwUndoDrawUnGroupConnectToLayout()
+{
+}
+
+void
+SwUndoDrawUnGroupConnectToLayout::UndoImpl(::sw::UndoRedoContext &)
+{
+ for (const std::pair< SwDrawFrameFormat*, SdrObject* > & rPair : m_aDrawFormatsAndObjs)
+ {
+ SdrObject* pObj( rPair.second );
+ SwDrawContact* pDrawContact( dynamic_cast<SwDrawContact*>(pObj->GetUserCall()) );
+ OSL_ENSURE( pDrawContact,
+ "<SwUndoDrawUnGroupConnectToLayout::Undo(..)> -- missing SwDrawContact instance" );
+ if ( pDrawContact )
+ {
+ // deletion of instance <pDrawContact> and thus disconnection from
+ // the Writer layout.
+ pDrawContact->Changed( *pObj, SdrUserCallType::Delete, pObj->GetLastBoundRect() );
+ pObj->SetUserCall( nullptr );
+ }
+ }
+}
+
+void
+SwUndoDrawUnGroupConnectToLayout::RedoImpl(::sw::UndoRedoContext &)
+{
+ for (const std::pair< SwDrawFrameFormat*, SdrObject* > & rPair : m_aDrawFormatsAndObjs)
+ {
+ SwDrawFrameFormat* pFormat( rPair.first );
+ SdrObject* pObj( rPair.second );
+ SwDrawContact *pContact = new SwDrawContact( pFormat, pObj );
+ pContact->ConnectToLayout();
+ pContact->MoveObjToVisibleLayer( pObj );
+ }
+}
+
+void SwUndoDrawUnGroupConnectToLayout::AddFormatAndObj( SwDrawFrameFormat* pDrawFrameFormat,
+ SdrObject* pDrawObject )
+{
+ m_aDrawFormatsAndObjs.emplace_back( pDrawFrameFormat, pDrawObject );
+}
+
+SwUndoDrawDelete::SwUndoDrawDelete( sal_uInt16 nCnt, const SwDoc* pDoc )
+ : SwUndo( SwUndoId::DRAWDELETE, pDoc ), m_bDeleteFormat( true )
+{
+ m_pObjArray.reset( new SwUndoGroupObjImpl[ nCnt ] );
+ m_pMarkList.reset( new SdrMarkList() );
+}
+
+SwUndoDrawDelete::~SwUndoDrawDelete()
+{
+ if( m_bDeleteFormat )
+ {
+ SwUndoGroupObjImpl* pTmp = m_pObjArray.get();
+ for( size_t n = 0; n < m_pMarkList->GetMarkCount(); ++n, ++pTmp )
+ delete pTmp->pFormat;
+ }
+}
+
+void SwUndoDrawDelete::UndoImpl(::sw::UndoRedoContext & rContext)
+{
+ m_bDeleteFormat = false;
+ SwFrameFormats & rFlyFormats = *rContext.GetDoc().GetSpzFrameFormats();
+ for( size_t n = 0; n < m_pMarkList->GetMarkCount(); ++n )
+ {
+ SwUndoGroupObjImpl& rSave = m_pObjArray[n];
+ ::lcl_RestoreAnchor( rSave.pFormat, rSave.nNodeIdx );
+ rFlyFormats.push_back( rSave.pFormat );
+ SdrObject *pObj = rSave.pObj;
+ SwDrawContact *pContact = new SwDrawContact( rSave.pFormat, pObj );
+ pContact->Changed_( *pObj, SdrUserCallType::Inserted, nullptr );
+ // #i45718# - follow-up of #i35635# move object to visible layer
+ pContact->MoveObjToVisibleLayer( pObj );
+
+ SwDrawFrameFormat* pDrawFrameFormat = rSave.pFormat;
+
+ // #i45952# - notify that position attributes are already set
+ OSL_ENSURE(pDrawFrameFormat,
+ "<SwUndoDrawGroup::Undo(..)> - wrong type of frame format for drawing object");
+ if (pDrawFrameFormat)
+ pDrawFrameFormat->PosAttrSet();
+ }
+ rContext.SetSelections(nullptr, m_pMarkList.get());
+}
+
+void SwUndoDrawDelete::RedoImpl(::sw::UndoRedoContext & rContext)
+{
+ m_bDeleteFormat = true;
+ SwFrameFormats & rFlyFormats = *rContext.GetDoc().GetSpzFrameFormats();
+ for( size_t n = 0; n < m_pMarkList->GetMarkCount(); ++n )
+ {
+ SwUndoGroupObjImpl& rSave = m_pObjArray[n];
+ SdrObject *pObj = rSave.pObj;
+ SwDrawContact *pContact = static_cast<SwDrawContact*>(GetUserCall(pObj));
+ SwDrawFrameFormat *pFormat = static_cast<SwDrawFrameFormat*>(pContact->GetFormat());
+
+ // object will destroy itself
+ pContact->Changed( *pObj, SdrUserCallType::Delete, pObj->GetLastBoundRect() );
+ pObj->SetUserCall( nullptr );
+
+ // notify UNO objects to decouple
+ ::lcl_SendRemoveToUno( *pFormat );
+
+ rFlyFormats.erase( std::find( rFlyFormats.begin(), rFlyFormats.end(), pFormat ));
+ ::lcl_SaveAnchor( pFormat, rSave.nNodeIdx );
+ }
+}
+
+void SwUndoDrawDelete::AddObj( SwDrawFrameFormat* pFormat,
+ const SdrMark& rMark )
+{
+ SwUndoGroupObjImpl& rSave = m_pObjArray[ m_pMarkList->GetMarkCount() ];
+ rSave.pObj = rMark.GetMarkedSdrObj();
+ rSave.pFormat = pFormat;
+ ::lcl_SaveAnchor( pFormat, rSave.nNodeIdx );
+
+ // notify UNO objects to decouple
+ ::lcl_SendRemoveToUno( *pFormat );
+
+ // remove from array
+ SwDoc* pDoc = pFormat->GetDoc();
+ SwFrameFormats& rFlyFormats = *pDoc->GetSpzFrameFormats();
+ rFlyFormats.erase( std::find( rFlyFormats.begin(), rFlyFormats.end(), pFormat ));
+
+ m_pMarkList->InsertEntry( rMark );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */