Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  undraw.cxx   Sprache: C

 
/* -*- 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 <osl/diagnose.h>

#include <hintids.hxx>
#include <fmtanchr.hxx>
#include <fmtflcnt.hxx>
#include <txtflcnt.hxx>
#include <frmfmt.hxx>
#include <doc.hxx>
#include <IDocumentUndoRedo.hxx>
#include <IDocumentLayoutAccess.hxx>
#include <swundo.hxx>
#include <pam.hxx>
#include <ndtxt.hxx>
#include <UndoCore.hxx>
#include <dcontact.hxx>
#include <viewsh.hxx>
#include <frameformats.hxx>
#include <textboxhelper.hxx>

struct SwUndoGroupObjImpl
{
    SwDrawFrameFormat* pFormat;
    SdrObject* pObj;
    SwNodeOffset nNodeIdx;
};

// Draw-Object

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& rDoc )
    : SwUndo( SwUndoId::DRAWUNDO, rDoc ), 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_SaveAnchor( SwFrameFormat* pFormat, SwNodeOffset& 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())))
        return;

    rNodePos = rAnchor.GetAnchorNode()->GetIndex();
    sal_Int32 nContentPos = 0;

    if (RndStdIds::FLY_AS_CHAR == rAnchor.GetAnchorId())
    {
        nContentPos = rAnchor.GetAnchorContentOffset();

        // destroy TextAttribute
        SwTextNode *pTextNd = pFormat->GetDoc().GetNodes()[ rNodePos ]->GetTextNode();
        assert(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();
            SwContentIndex aIdx( pTextNd, nContentPos );
            pTextNd->EraseText( aIdx, 1 );
        }
    }
    else if (RndStdIds::FLY_AT_CHAR == rAnchor.GetAnchorId())
    {
        nContentPos = rAnchor.GetAnchorContentOffset();
    }

    pFormat->SetFormatAttr( SwFormatAnchor( rAnchor.GetAnchorId(), nContentPos ) );
}

static void lcl_RestoreAnchor( SwFrameFormat* pFormat, SwNodeOffset 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())))
        return;

    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.SetContent( 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& rDoc )
    : SwUndo( SwUndoId::DRAWGROUP, rDoc ), 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);

    // This will store the textboxes what were owned by this group
    std::vector<std::pair<SdrObject*, SwFrameFormat*>> vTextBoxes;
    if (auto pOldTextBoxNode = pFormat->GetOtherTextBoxFormats())
    {
        if (auto pChildren = pObj->getChildrenOfSdrObject())
        {
            for (const rtl::Reference<SdrObject>& pChild : *pChildren)
            {
                if (auto pTextBox = pOldTextBoxNode->GetTextBox(pChild.get()))
                    vTextBoxes.push_back(std::pair(pChild.get(), pTextBox));
            }
        }
    }

    ::lcl_SaveAnchor( pFormat, m_pObjArray[0].nNodeIdx );

    pFormat->RemoveAllUnos();

    // remove from array
    SwDoc& rDoc = pFormat->GetDoc();
    sw::SpzFrameFormats& rFlyFormats = *rDoc.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(static_cast<sw::SpzFrameFormat*>(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 );

        for (auto& rElem : vTextBoxes)
        {
            if (rElem.first == pObj)
            {
                auto pNewTextBoxNode = std::make_shared<SwTextBoxNode>(SwTextBoxNode(rSave.pFormat));
                rSave.pFormat->SetOtherTextBoxFormats(pNewTextBoxNode);
                pNewTextBoxNode->AddTextBox(rElem.first, rElem.second);
                rElem.second->SetOtherTextBoxFormats(pNewTextBoxNode);
                break;
            }
        }

        SwDrawFrameFormat* pDrawFrameFormat = rSave.pFormat;

        // #i45952# - notify that position attributes are already set
        OSL_ENSURE(pDrawFrameFormat,
                " - wrong type of frame format for drawing object");
        if (pDrawFrameFormat)
            pDrawFrameFormat->PosAttrSet();
    }
}

void SwUndoDrawGroup::RedoImpl(::sw::UndoRedoContext &)
{
    m_bDeleteFormat = true;

    // remove from array
    SwDoc& rDoc = m_pObjArray[0].pFormat->GetDoc();
    sw::SpzFrameFormats& rFlyFormats = *rDoc.GetSpzFrameFormats();

    // This will store the textboxes from the ex-group-shapes
    std::vector<std::pair<SdrObject*, SwFrameFormat*>> vTextBoxes;

    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));
        if (!pContact)
            continue;

        // Save the textboxes
        if (auto pOldTextBoxNode = rSave.pFormat->GetOtherTextBoxFormats())
        {
            if (auto pTextBox = pOldTextBoxNode->GetTextBox(pObj))
                vTextBoxes.push_back(std::pair(pObj, pTextBox));
        }

        // object will destroy itself
        pContact->Changed( *pObj, SdrUserCallType::Delete, pObj->GetLastBoundRect() );
        pObj->SetUserCall( nullptr );

        ::lcl_SaveAnchor( rSave.pFormat, rSave.nNodeIdx );

        rSave.pFormat->RemoveAllUnos();

        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(static_cast<sw::SpzFrameFormat*>(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;

    // Restore the textboxes
    if (vTextBoxes.size())
    {
        auto pNewTextBoxNode = std::make_shared<SwTextBoxNode>(SwTextBoxNode(m_pObjArray[0].pFormat));
        for (auto& rElem : vTextBoxes)
        {
            pNewTextBoxNode->AddTextBox(rElem.first, rElem.second);
            rElem.second->SetOtherTextBoxFormats(pNewTextBoxNode);
        }
        m_pObjArray[0].pFormat->SetOtherTextBoxFormats(pNewTextBoxNode);
    }

    // #i45952# - notify that position attributes are already set
    OSL_ENSURE(pDrawFrameFormat,
            " - 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 );

    pFormat->RemoveAllUnos();

    // remove from array
    sw::SpzFrameFormats& 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& rDoc )
    : SwUndo( SwUndoId::DRAWUNGROUP, rDoc ), m_bDeleteFormat( false )
{
    m_nSize = o3tl::narrowing<sal_uInt16>(pObj->GetSubList()->GetObjCount()) + 1;
    m_pObjArray.reset( new SwUndoGroupObjImpl[ m_nSize ] );

    if (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 );

        pFormat->RemoveAllUnos();

        // remove from array
        sw::SpzFrameFormats& 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& rDoc = rContext.GetDoc();
    sw::SpzFrameFormats& rFlyFormats = *rDoc.GetSpzFrameFormats();

    // This will store the textboxes what were owned by this group
    std::vector<std::pair<SdrObject*, SwFrameFormat*>> vTextBoxes;

    // remove from array
    for( sal_uInt16 n = 1; n < m_nSize; ++n )
    {
        SwUndoGroupObjImpl& rSave = m_pObjArray[n];

        ::lcl_SaveAnchor( rSave.pFormat, rSave.nNodeIdx );

        // copy the textboxes for later use to this vector
        if (auto pTxBxNd = rSave.pFormat->GetOtherTextBoxFormats())
        {
            if (auto pGroupObj = m_pObjArray[0].pObj)
            {
                if (auto pChildren = pGroupObj->getChildrenOfSdrObject())
                {
                    for (const rtl::Reference<SdrObject>& pChild : *pChildren)
                    {
                        if (auto pTextBox = pTxBxNd->GetTextBox(pChild.get()))
                            vTextBoxes.push_back(std::pair(pChild.get(), pTextBox));
                    }
                }
            }
        }

        rSave.pFormat->RemoveAllUnos();

        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(static_cast<sw::SpzFrameFormat*>(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;

    // Restore the vector content for the new formats
    if (vTextBoxes.size())
    {
        auto pNewTxBxNd = std::make_shared<SwTextBoxNode>( SwTextBoxNode(m_pObjArray[0].pFormat));
        for (auto& rElem : vTextBoxes)
        {
            pNewTxBxNd->AddTextBox(rElem.first, rElem.second);
            rElem.second->SetOtherTextBoxFormats(pNewTxBxNd);
        }
        m_pObjArray[0].pFormat->SetOtherTextBoxFormats(pNewTxBxNd);
    }


    // #i45952# - notify that position attributes are already set
    OSL_ENSURE(pDrawFrameFormat,
            " - 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 );

    // Store the textboxes in this vector for later use.
    std::vector<std::pair<SdrObject*, SwFrameFormat*>> vTextBoxes;
    if (auto pTextBoxNode = pFormat->GetOtherTextBoxFormats())
    {
        auto pMasterObj = m_pObjArray[0].pObj;

        if (auto pObjList = pMasterObj->getChildrenOfSdrObject())
            for (const rtl::Reference<SdrObject>& pObj : *pObjList)
            {
                vTextBoxes.push_back(std::pair(pObj.get(), pTextBoxNode->GetTextBox(pObj.get())));
            }
    }

    pFormat->RemoveAllUnos();

    // remove from array
    SwDoc& rDoc = pFormat->GetDoc();
    sw::SpzFrameFormats& rFlyFormats = *rDoc.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(static_cast<sw::SpzFrameFormat*>(rSave.pFormat));

        SwDrawFrameFormat* pDrawFrameFormat = rSave.pFormat;

        // Restore the textboxes for the restored group shape.
        for (auto& pElem : vTextBoxes)
        {
            if (pElem.first == rSave.pObj)
            {
                auto pTmpTxBxNd = std::make_shared<SwTextBoxNode>(SwTextBoxNode(rSave.pFormat));
                pTmpTxBxNd->AddTextBox(rSave.pObj, pElem.second);
                pFormat->SetOtherTextBoxFormats(pTmpTxBxNd);
                pElem.second->SetOtherTextBoxFormats(pTmpTxBxNd);
                break;
            }
        }

        // #i45952# - notify that position attributes are already set
        OSL_ENSURE(pDrawFrameFormat,
                " - 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&&nbsp;rDoc)
    : SwUndo( SwUndoId::DRAWUNGROUP, rDoc )
{
}

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,
                " -- 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& rDoc )
    : SwUndo( SwUndoId::DRAWDELETE, rDoc ), 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;
    sw::SpzFrameFormats& 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(static_cast<sw::SpzFrameFormat*>(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;
        if (pDrawFrameFormat->GetOtherTextBoxFormats())
        {
            SwTextBoxHelper::synchronizeGroupTextBoxProperty(
                SwTextBoxHelper::changeAnchor, pDrawFrameFormat, pObj);
        }

        // #i45952# - notify that position attributes are already set
        OSL_ENSURE(pDrawFrameFormat,
                " - 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;
    sw::SpzFrameFormats& 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));
        if (!pContact)
            continue;

        SwDrawFrameFormat *pFormat = static_cast<SwDrawFrameFormat*>(pContact->GetFormat());

        // object will destroy itself
        pContact->Changed( *pObj, SdrUserCallType::Delete, pObj->GetLastBoundRect() );
        pObj->SetUserCall( nullptr );

        pFormat->RemoveAllUnos();

        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 );

    pFormat->RemoveAllUnos();

    // remove from array
    SwDoc& rDoc = pFormat->GetDoc();
    sw::SpzFrameFormats& rFlyFormats = *rDoc.GetSpzFrameFormats();
    rFlyFormats.erase( std::find( rFlyFormats.begin(), rFlyFormats.end(), pFormat ));

    m_pMarkList->InsertEntry( rMark );
}

void SwUndoDrawDelete::dumpAsXml(xmlTextWriterPtr pWriter) const
{
    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwUndoDrawDelete"));

    for (size_t i = 0; i < m_pMarkList->GetMarkCount(); ++i)
    {
        SwUndoGroupObjImpl& rObj = m_pObjArray[i];
        (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwUndoGroupObjImpl"));
        (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("index"),
                                    BAD_CAST(OString::number(i).getStr()));

        if (rObj.pFormat)
        {
            (void)xmlTextWriterStartElement(pWriter, BAD_CAST("pFormat"));
            rObj.pFormat->dumpAsXml(pWriter);
            (void)xmlTextWriterEndElement(pWriter);
        }
        (void)xmlTextWriterEndElement(pWriter);
    }

    (void)xmlTextWriterEndElement(pWriter);
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=94 H=84 G=88

¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge