LCOV - code coverage report
Current view: top level - sw/source/core/undo - undobj1.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 151 322 46.9 %
Date: 2015-06-13 12:38:46 Functions: 20 30 66.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <svl/itemiter.hxx>
      21             : #include <hintids.hxx>
      22             : #include <hints.hxx>
      23             : #include <fmtflcnt.hxx>
      24             : #include <fmtanchr.hxx>
      25             : #include <fmtcntnt.hxx>
      26             : #include <txtflcnt.hxx>
      27             : #include <frmfmt.hxx>
      28             : #include <flyfrm.hxx>
      29             : #include <UndoCore.hxx>
      30             : #include <UndoDraw.hxx>
      31             : #include <rolbck.hxx>
      32             : #include <doc.hxx>
      33             : #include <IDocumentLayoutAccess.hxx>
      34             : #include <docary.hxx>
      35             : #include <rootfrm.hxx>
      36             : #include <swundo.hxx>
      37             : #include <pam.hxx>
      38             : #include <ndtxt.hxx>
      39             : #include <dcontact.hxx>
      40             : #include <ndole.hxx>
      41             : 
      42         438 : SwUndoFlyBase::SwUndoFlyBase( SwFrameFormat* pFormat, SwUndoId nUndoId )
      43             :     : SwUndo(nUndoId)
      44             :     , pFrameFormat(pFormat)
      45             :     , nNdPgPos(0)
      46             :     , nCntPos(0)
      47             :     , nRndId(0)
      48         438 :     , bDelFormat(false)
      49             : {
      50         438 : }
      51             : 
      52         876 : SwUndoFlyBase::~SwUndoFlyBase()
      53             : {
      54         438 :     if( bDelFormat )       // delete during an Undo?
      55           3 :         delete pFrameFormat;
      56         438 : }
      57             : 
      58           1 : void SwUndoFlyBase::InsFly(::sw::UndoRedoContext & rContext, bool bShowSelFrm)
      59             : {
      60           1 :     SwDoc *const pDoc = & rContext.GetDoc();
      61             : 
      62             :     // add again into array
      63           1 :     SwFrameFormats& rFlyFormats = *pDoc->GetSpzFrameFormats();
      64           1 :     rFlyFormats.push_back( pFrameFormat );
      65             : 
      66             :     // OD 26.06.2003 #108784# - insert 'master' drawing object into drawing page
      67           1 :     if ( RES_DRAWFRMFMT == pFrameFormat->Which() )
      68             :     {
      69             :         SwDrawContact* pDrawContact =
      70           0 :             static_cast<SwDrawContact*>(pFrameFormat->FindContactObj());
      71           0 :         if ( pDrawContact )
      72             :         {
      73           0 :             pDrawContact->InsertMasterIntoDrawPage();
      74             :             // #i40845# - follow-up of #i35635#
      75             :             // move object to visible layer
      76           0 :             pDrawContact->MoveObjToVisibleLayer( pDrawContact->GetMaster() );
      77             :         }
      78             :     }
      79             : 
      80           1 :     SwFormatAnchor aAnchor( (RndStdIds)nRndId );
      81             : 
      82           1 :     if (FLY_AT_PAGE == nRndId)
      83             :     {
      84           0 :         aAnchor.SetPageNum( (sal_uInt16)nNdPgPos );
      85             :     }
      86             :     else
      87             :     {
      88           1 :         SwPosition aNewPos(pDoc->GetNodes().GetEndOfContent());
      89           1 :         aNewPos.nNode = nNdPgPos;
      90           1 :         if ((FLY_AS_CHAR == nRndId) || (FLY_AT_CHAR == nRndId))
      91             :         {
      92           1 :             aNewPos.nContent.Assign( aNewPos.nNode.GetNode().GetContentNode(),
      93           2 :                                     nCntPos );
      94             :         }
      95           1 :         aAnchor.SetAnchor( &aNewPos );
      96             :     }
      97             : 
      98           1 :     pFrameFormat->SetFormatAttr( aAnchor );     // reset anchor
      99             : 
     100           1 :     if( RES_DRAWFRMFMT != pFrameFormat->Which() )
     101             :     {
     102             :         // get Content and reset ContentAttribute
     103           1 :         SwNodeIndex aIdx( pDoc->GetNodes() );
     104           1 :         RestoreSection( pDoc, &aIdx, SwFlyStartNode );
     105           1 :         pFrameFormat->SetFormatAttr( SwFormatContent( aIdx.GetNode().GetStartNode() ));
     106             :     }
     107             : 
     108             :     // Set InContentAttribute not until there is content!
     109             :     // Otherwise the layout would format the Fly beforehand but would not find
     110             :     // content; this happened with graphics from the internet.
     111           1 :     if (FLY_AS_CHAR == nRndId)
     112             :     {
     113             :         // there must be at least the attribute in a TextNode
     114           1 :         SwContentNode* pCNd = aAnchor.GetContentAnchor()->nNode.GetNode().GetContentNode();
     115             :         OSL_ENSURE( pCNd->IsTextNode(), "no Text Node at position." );
     116           1 :         SwFormatFlyCnt aFormat( pFrameFormat );
     117           1 :         pCNd->GetTextNode()->InsertItem( aFormat, nCntPos, nCntPos );
     118             :     }
     119             : 
     120           1 :     pFrameFormat->MakeFrms();
     121             : 
     122           1 :     if( bShowSelFrm )
     123             :     {
     124           0 :         rContext.SetSelections(pFrameFormat, 0);
     125             :     }
     126             : 
     127           1 :     if( GetHistory() )
     128           0 :         GetHistory()->Rollback( pDoc );
     129             : 
     130           1 :     switch( nRndId )
     131             :     {
     132             :     case FLY_AS_CHAR:
     133             :     case FLY_AT_CHAR:
     134             :         {
     135           1 :             const SwFormatAnchor& rAnchor = pFrameFormat->GetAnchor();
     136           1 :             nNdPgPos = rAnchor.GetContentAnchor()->nNode.GetIndex();
     137           1 :             nCntPos = rAnchor.GetContentAnchor()->nContent.GetIndex();
     138             :         }
     139           1 :         break;
     140             :     case FLY_AT_PARA:
     141             :     case FLY_AT_FLY:
     142             :         {
     143           0 :             const SwFormatAnchor& rAnchor = pFrameFormat->GetAnchor();
     144           0 :             nNdPgPos = rAnchor.GetContentAnchor()->nNode.GetIndex();
     145             :         }
     146           0 :         break;
     147             :     case FLY_AT_PAGE:
     148           0 :         break;
     149             :     }
     150           1 :     bDelFormat =  false;
     151           1 : }
     152             : 
     153           4 : void SwUndoFlyBase::DelFly( SwDoc* pDoc )
     154             : {
     155           4 :     bDelFormat = true;                 // delete Format in DTOR
     156           4 :     pFrameFormat->DelFrms();                 // destroy Frms
     157             : 
     158             :     // all Uno objects should now log themselves off
     159             :     {
     160           4 :         SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT, pFrameFormat );
     161           4 :         pFrameFormat->ModifyNotification( &aMsgHint, &aMsgHint );
     162             :     }
     163             : 
     164           4 :     if ( RES_DRAWFRMFMT != pFrameFormat->Which() )
     165             :     {
     166             :         // if there is content than save it
     167           3 :         const SwFormatContent& rContent = pFrameFormat->GetContent();
     168             :         OSL_ENSURE( rContent.GetContentIdx(), "Fly ohne Inhalt" );
     169             : 
     170           3 :         SaveSection( *rContent.GetContentIdx() );
     171           3 :         const_cast<SwFormatContent&>(rContent).SetNewContentIdx( nullptr );
     172             :     }
     173             :     // OD 02.07.2003 #108784# - remove 'master' drawing object from drawing page
     174           1 :     else if ( RES_DRAWFRMFMT == pFrameFormat->Which() )
     175             :     {
     176             :         SwDrawContact* pDrawContact =
     177           1 :             static_cast<SwDrawContact*>(pFrameFormat->FindContactObj());
     178           1 :         if ( pDrawContact )
     179             :         {
     180           1 :             pDrawContact->RemoveMasterFromDrawPage();
     181             :         }
     182             :     }
     183             : 
     184           4 :     const SwFormatAnchor& rAnchor = pFrameFormat->GetAnchor();
     185           4 :     const SwPosition* pPos = rAnchor.GetContentAnchor();
     186             :     // The positions in Nodes array got shifted.
     187           4 :     nRndId = static_cast<sal_uInt16>(rAnchor.GetAnchorId());
     188           4 :     if (FLY_AS_CHAR == nRndId)
     189             :     {
     190           2 :         nNdPgPos = pPos->nNode.GetIndex();
     191           2 :         nCntPos = pPos->nContent.GetIndex();
     192           2 :         SwTextNode *const pTextNd = pPos->nNode.GetNode().GetTextNode();
     193             :         OSL_ENSURE( pTextNd, "Kein Textnode gefunden" );
     194             :         SwTextFlyCnt* const pAttr = static_cast<SwTextFlyCnt*>(
     195           2 :             pTextNd->GetTextAttrForCharAt( nCntPos, RES_TXTATR_FLYCNT ) );
     196             :         // attribute is still in TextNode, delete
     197           2 :         if( pAttr && pAttr->GetFlyCnt().GetFrameFormat() == pFrameFormat )
     198             :         {
     199             :             // Pointer to 0, do not delete
     200           1 :             const_cast<SwFormatFlyCnt&>(pAttr->GetFlyCnt()).SetFlyFormat();
     201           1 :             SwIndex aIdx( pPos->nContent );
     202           1 :             pTextNd->EraseText( aIdx, 1 );
     203             :         }
     204             :     }
     205           2 :     else if (FLY_AT_CHAR == nRndId)
     206             :     {
     207           0 :         nNdPgPos = pPos->nNode.GetIndex();
     208           0 :         nCntPos = pPos->nContent.GetIndex();
     209             :     }
     210           2 :     else if ((FLY_AT_PARA == nRndId) || (FLY_AT_FLY == nRndId))
     211             :     {
     212           1 :         nNdPgPos = pPos->nNode.GetIndex();
     213             :     }
     214             :     else
     215             :     {
     216           1 :         nNdPgPos = rAnchor.GetPageNum();
     217             :     }
     218             : 
     219           4 :     pFrameFormat->ResetFormatAttr( RES_ANCHOR );        // delete anchor
     220             : 
     221             :     // delete from array
     222           4 :     SwFrameFormats& rFlyFormats = *pDoc->GetSpzFrameFormats();
     223           4 :     rFlyFormats.erase( std::find( rFlyFormats.begin(), rFlyFormats.end(), pFrameFormat ));
     224           4 : }
     225             : 
     226         434 : SwUndoInsLayFormat::SwUndoInsLayFormat( SwFrameFormat* pFormat, sal_uLong nNodeIdx, sal_Int32 nCntIdx )
     227         434 :     : SwUndoFlyBase( pFormat, RES_DRAWFRMFMT == pFormat->Which() ?
     228             :                                             UNDO_INSDRAWFMT : UNDO_INSLAYFMT ),
     229         434 :     mnCrsrSaveIndexPara( nNodeIdx ), mnCrsrSaveIndexPos( nCntIdx )
     230             : {
     231         434 :     const SwFormatAnchor& rAnchor = pFrameFormat->GetAnchor();
     232         434 :     nRndId = static_cast<sal_uInt16>(rAnchor.GetAnchorId());
     233         434 :     bDelFormat = false;
     234         434 :     switch( nRndId )
     235             :     {
     236             :     case FLY_AT_PAGE:
     237         105 :         nNdPgPos = rAnchor.GetPageNum();
     238         105 :         break;
     239             :     case FLY_AT_PARA:
     240             :     case FLY_AT_FLY:
     241          16 :         nNdPgPos = rAnchor.GetContentAnchor()->nNode.GetIndex();
     242          16 :         break;
     243             :     case FLY_AS_CHAR:
     244             :     case FLY_AT_CHAR:
     245             :         {
     246         313 :             const SwPosition* pPos = rAnchor.GetContentAnchor();
     247         313 :             nCntPos = pPos->nContent.GetIndex();
     248         313 :             nNdPgPos = pPos->nNode.GetIndex();
     249             :         }
     250         313 :         break;
     251             :     default:
     252             :         OSL_FAIL( "Which FlyFrame?" );
     253             :     }
     254         434 : }
     255             : 
     256         868 : SwUndoInsLayFormat::~SwUndoInsLayFormat()
     257             : {
     258         868 : }
     259             : 
     260           0 : void SwUndoInsLayFormat::UndoImpl(::sw::UndoRedoContext & rContext)
     261             : {
     262           0 :     SwDoc & rDoc(rContext.GetDoc());
     263           0 :     const SwFormatContent& rContent = pFrameFormat->GetContent();
     264           0 :     if( rContent.GetContentIdx() )  // no content
     265             :     {
     266           0 :         bool bRemoveIdx = true;
     267           0 :         if( mnCrsrSaveIndexPara > 0 )
     268             :         {
     269             :             SwTextNode *const pNode =
     270           0 :                 rDoc.GetNodes()[mnCrsrSaveIndexPara]->GetTextNode();
     271           0 :             if( pNode )
     272             :             {
     273           0 :                 SwNodeIndex aIdx( rDoc.GetNodes(),
     274           0 :                         rContent.GetContentIdx()->GetIndex() );
     275           0 :                 SwNodeIndex aEndIdx( rDoc.GetNodes(),
     276           0 :                         aIdx.GetNode().EndOfSectionIndex() );
     277           0 :                 SwIndex aIndex( pNode, mnCrsrSaveIndexPos );
     278           0 :                 SwPosition aPos( *pNode, aIndex );
     279           0 :                 SwDoc::CorrAbs( aIdx, aEndIdx, aPos, true );
     280           0 :                 bRemoveIdx = false;
     281             :             }
     282             :         }
     283           0 :         if( bRemoveIdx )
     284             :         {
     285           0 :             RemoveIdxFromSection( rDoc, rContent.GetContentIdx()->GetIndex() );
     286             :         }
     287             :     }
     288           0 :     DelFly(& rDoc);
     289           0 : }
     290             : 
     291           0 : void SwUndoInsLayFormat::RedoImpl(::sw::UndoRedoContext & rContext)
     292             : {
     293           0 :     InsFly(rContext);
     294           0 : }
     295             : 
     296           0 : void SwUndoInsLayFormat::RepeatImpl(::sw::RepeatContext & rContext)
     297             : {
     298           0 :     SwDoc *const pDoc = & rContext.GetDoc();
     299             :     // get anchor and reset it
     300           0 :     SwFormatAnchor aAnchor( pFrameFormat->GetAnchor() );
     301           0 :     if ((FLY_AT_PARA == aAnchor.GetAnchorId()) ||
     302           0 :         (FLY_AT_CHAR == aAnchor.GetAnchorId()) ||
     303           0 :         (FLY_AS_CHAR == aAnchor.GetAnchorId()))
     304             :     {
     305           0 :         SwPosition aPos( *rContext.GetRepeatPaM().GetPoint() );
     306           0 :         if (FLY_AT_PARA == aAnchor.GetAnchorId())
     307             :         {
     308           0 :             aPos.nContent.Assign( 0, 0 );
     309             :         }
     310           0 :         aAnchor.SetAnchor( &aPos );
     311             :     }
     312           0 :     else if( FLY_AT_FLY == aAnchor.GetAnchorId() )
     313             :     {
     314             :         SwStartNode const*const pSttNd =
     315           0 :             rContext.GetRepeatPaM().GetNode().FindFlyStartNode();
     316           0 :         if( pSttNd )
     317             :         {
     318           0 :             SwPosition aPos( *pSttNd );
     319           0 :             aAnchor.SetAnchor( &aPos );
     320             :         }
     321             :         else
     322             :         {
     323           0 :             return ;
     324             :         }
     325             :     }
     326           0 :     else if (FLY_AT_PAGE == aAnchor.GetAnchorId())
     327             :     {
     328           0 :         aAnchor.SetPageNum( pDoc->getIDocumentLayoutAccess().GetCurrentLayout()->GetCurrPage( &rContext.GetRepeatPaM() ));
     329             :     }
     330             :     else {
     331             :         OSL_FAIL( "What kind of anchor is this?" );
     332             :     }
     333             : 
     334           0 :     SwFrameFormat* pFlyFormat = pDoc->getIDocumentLayoutAccess().CopyLayoutFormat( *pFrameFormat, aAnchor, true, true );
     335           0 :     (void) pFlyFormat;
     336             : }
     337             : 
     338             : // #111827#
     339         499 : OUString SwUndoInsLayFormat::GetComment() const
     340             : {
     341         499 :     OUString aResult;
     342             : 
     343             :     // HACK: disable caching:
     344             :     // the SfxUndoManager calls GetComment() too early: the pFrameFormat does not
     345             :     // have a SwDrawContact yet, so it will fall back to SwUndo::GetComment(),
     346             :     // which sets pComment to a wrong value.
     347             : //    if (! pComment)
     348             :     if (true)
     349             :     {
     350             :         /*
     351             :           If frame format is present and has an SdrObject use the undo
     352             :           comment of the SdrObject. Otherwise use the default comment.
     353             :         */
     354         499 :         bool bDone = false;
     355         499 :         if (pFrameFormat)
     356             :         {
     357         499 :             const SdrObject * pSdrObj = pFrameFormat->FindSdrObject();
     358         499 :             if ( pSdrObj )
     359             :             {
     360         430 :                 aResult = SdrUndoNewObj::GetComment( *pSdrObj );
     361         430 :                 bDone = true;
     362             :             }
     363             :         }
     364             : 
     365         499 :         if (! bDone)
     366          69 :             aResult = SwUndo::GetComment();
     367             :     }
     368             :     else
     369             :         aResult = *pComment;
     370             : 
     371         499 :     return aResult;
     372             : }
     373             : 
     374             : static SwUndoId
     375           4 : lcl_GetSwUndoId(SwFrameFormat *const pFrameFormat)
     376             : {
     377           4 :     if (RES_DRAWFRMFMT != pFrameFormat->Which())
     378             :     {
     379           3 :         const SwFormatContent& rContent = pFrameFormat->GetContent();
     380             :         OSL_ENSURE( rContent.GetContentIdx(), "Fly without content" );
     381             : 
     382           3 :         SwNodeIndex firstNode(*rContent.GetContentIdx(), 1);
     383           3 :         SwNoTextNode *const pNoTextNode(firstNode.GetNode().GetNoTextNode());
     384           3 :         if (pNoTextNode && pNoTextNode->IsGrfNode())
     385             :         {
     386           1 :             return UNDO_DELGRF;
     387             :         }
     388           2 :         else if (pNoTextNode && pNoTextNode->IsOLENode())
     389             :         {
     390             :             // surprisingly not UNDO_DELOLE, which does not seem to work
     391           0 :             return UNDO_DELETE;
     392           2 :         }
     393             :     }
     394           3 :     return UNDO_DELLAYFMT;
     395             : }
     396             : 
     397           4 : SwUndoDelLayFormat::SwUndoDelLayFormat( SwFrameFormat* pFormat )
     398             :     : SwUndoFlyBase( pFormat, lcl_GetSwUndoId(pFormat) )
     399           4 :     , bShowSelFrm( true )
     400             : {
     401           4 :     SwDoc* pDoc = pFormat->GetDoc();
     402           4 :     DelFly( pDoc );
     403           4 : }
     404             : 
     405           3 : SwRewriter SwUndoDelLayFormat::GetRewriter() const
     406             : {
     407           3 :     SwRewriter aRewriter;
     408             : 
     409           3 :     SwDoc * pDoc = pFrameFormat->GetDoc();
     410             : 
     411           3 :     if (pDoc)
     412             :     {
     413           3 :         SwNodeIndex* pIdx = GetMvSttIdx();
     414           3 :         if( 1 == GetMvNodeCnt() && pIdx)
     415             :         {
     416           2 :             SwNode *const pNd = & pIdx->GetNode();
     417             : 
     418           2 :             if ( pNd->IsNoTextNode() && pNd->IsOLENode())
     419             :             {
     420           0 :                 SwOLENode * pOLENd = pNd->GetOLENode();
     421             : 
     422           0 :                 aRewriter.AddRule(UndoArg1, pOLENd->GetDescription());
     423             :             }
     424             :         }
     425             :     }
     426             : 
     427           3 :     return aRewriter;
     428             : }
     429             : 
     430           1 : void SwUndoDelLayFormat::UndoImpl(::sw::UndoRedoContext & rContext)
     431             : {
     432           1 :     InsFly( rContext, bShowSelFrm );
     433           1 : }
     434             : 
     435           0 : void SwUndoDelLayFormat::RedoImpl(::sw::UndoRedoContext & rContext)
     436             : {
     437           0 :     SwDoc & rDoc(rContext.GetDoc());
     438           0 :     const SwFormatContent& rContent = pFrameFormat->GetContent();
     439           0 :     if( rContent.GetContentIdx() )  // no content
     440             :     {
     441           0 :         RemoveIdxFromSection(rDoc, rContent.GetContentIdx()->GetIndex());
     442             :     }
     443             : 
     444           0 :     DelFly(& rDoc);
     445           0 : }
     446             : 
     447           0 : void SwUndoDelLayFormat::RedoForRollback()
     448             : {
     449           0 :     const SwFormatContent& rContent = pFrameFormat->GetContent();
     450           0 :     if( rContent.GetContentIdx() )  // no content
     451           0 :         RemoveIdxFromSection( *pFrameFormat->GetDoc(),
     452           0 :                                 rContent.GetContentIdx()->GetIndex() );
     453             : 
     454           0 :     DelFly( pFrameFormat->GetDoc() );
     455           0 : }
     456             : 
     457           5 : SwUndoSetFlyFormat::SwUndoSetFlyFormat( SwFrameFormat& rFlyFormat, SwFrameFormat& rNewFrameFormat )
     458             :     : SwUndo( UNDO_SETFLYFRMFMT ), SwClient( &rFlyFormat ), pFrameFormat( &rFlyFormat ),
     459           5 :     pOldFormat( static_cast<SwFrameFormat*>(rFlyFormat.DerivedFrom()) ), pNewFormat( &rNewFrameFormat ),
     460           5 :     pItemSet( new SfxItemSet( *rFlyFormat.GetAttrSet().GetPool(),
     461          10 :                                 rFlyFormat.GetAttrSet().GetRanges() )),
     462             :     nOldNode( 0 ), nNewNode( 0 ),
     463             :     nOldContent( 0 ), nNewContent( 0 ),
     464          25 :     nOldAnchorTyp( 0 ), nNewAnchorTyp( 0 ), bAnchorChgd( false )
     465             : {
     466           5 : }
     467             : 
     468           5 : SwRewriter SwUndoSetFlyFormat::GetRewriter() const
     469             : {
     470           5 :     SwRewriter aRewriter;
     471             : 
     472           5 :     if (pNewFormat)
     473           5 :         aRewriter.AddRule(UndoArg1, pNewFormat->GetName());
     474             : 
     475           5 :     return aRewriter;
     476             : }
     477             : 
     478          15 : SwUndoSetFlyFormat::~SwUndoSetFlyFormat()
     479             : {
     480           5 :     delete pItemSet;
     481          10 : }
     482             : 
     483           5 : void SwUndoSetFlyFormat::DeRegisterFromFormat( SwFormat& rFormat )
     484             : {
     485           5 :     rFormat.Remove(this);
     486           5 : }
     487             : 
     488           0 : void SwUndoSetFlyFormat::GetAnchor( SwFormatAnchor& rAnchor,
     489             :                                 sal_uLong nNode, sal_Int32 nContent )
     490             : {
     491           0 :     RndStdIds nAnchorTyp = rAnchor.GetAnchorId();
     492           0 :     if (FLY_AT_PAGE != nAnchorTyp)
     493             :     {
     494           0 :         SwNode* pNd = pFrameFormat->GetDoc()->GetNodes()[ nNode ];
     495             : 
     496           0 :         if( FLY_AT_FLY == nAnchorTyp
     497           0 :                 ? ( !pNd->IsStartNode() || SwFlyStartNode !=
     498           0 :                     static_cast<SwStartNode*>(pNd)->GetStartNodeType() )
     499           0 :                 : !pNd->IsTextNode() )
     500             :         {
     501           0 :             pNd = 0;    // invalid position
     502             :         }
     503             :         else
     504             :         {
     505           0 :             SwPosition aPos( *pNd );
     506           0 :             if ((FLY_AS_CHAR == nAnchorTyp) ||
     507             :                 (FLY_AT_CHAR == nAnchorTyp))
     508             :             {
     509           0 :                 if (nContent > pNd->GetTextNode()->GetText().getLength())
     510             :                 {
     511           0 :                     pNd = 0;    // invalid position
     512             :                 }
     513             :                 else
     514             :                 {
     515           0 :                     aPos.nContent.Assign(pNd->GetTextNode(), nContent);
     516             :                 }
     517             :             }
     518           0 :             if ( pNd )
     519             :             {
     520           0 :                 rAnchor.SetAnchor( &aPos );
     521           0 :             }
     522             :         }
     523             : 
     524           0 :         if( !pNd )
     525             :         {
     526             :             // invalid position - assign first page
     527           0 :             rAnchor.SetType( FLY_AT_PAGE );
     528           0 :             rAnchor.SetPageNum( 1 );
     529             :         }
     530             :     }
     531             :     else
     532           0 :         rAnchor.SetPageNum( nContent );
     533           0 : }
     534             : 
     535           0 : void SwUndoSetFlyFormat::UndoImpl(::sw::UndoRedoContext & rContext)
     536             : {
     537           0 :     SwDoc & rDoc = rContext.GetDoc();
     538             : 
     539             :     // Is the new Format still existent?
     540           0 :     if( rDoc.GetFrameFormats()->Contains( pOldFormat ) )
     541             :     {
     542           0 :         if( bAnchorChgd )
     543           0 :             pFrameFormat->DelFrms();
     544             : 
     545           0 :         if( pFrameFormat->DerivedFrom() != pOldFormat )
     546           0 :             pFrameFormat->SetDerivedFrom( pOldFormat );
     547             : 
     548           0 :         SfxItemIter aIter( *pItemSet );
     549           0 :         const SfxPoolItem* pItem = aIter.GetCurItem();
     550           0 :         while( pItem )
     551             :         {
     552           0 :             if( IsInvalidItem( pItem ))
     553             :                 pFrameFormat->ResetFormatAttr( pItemSet->GetWhichByPos(
     554           0 :                                         aIter.GetCurPos() ));
     555             :             else
     556           0 :                 pFrameFormat->SetFormatAttr( *pItem );
     557             : 
     558           0 :             if( aIter.IsAtEnd() )
     559           0 :                 break;
     560           0 :             pItem = aIter.NextItem();
     561             :         }
     562             : 
     563           0 :         if( bAnchorChgd )
     564             :         {
     565           0 :             const SwFormatAnchor& rOldAnch = pFrameFormat->GetAnchor();
     566           0 :             if (FLY_AS_CHAR == rOldAnch.GetAnchorId())
     567             :             {
     568             :                 // With InContents it's tricky: the text attribute needs to be
     569             :                 // deleted. Unfortunately, this not only destroys the Frms but
     570             :                 // also the format. To prevent that, first detach the
     571             :                 // connection between attribute and format.
     572           0 :                 const SwPosition *pPos = rOldAnch.GetContentAnchor();
     573           0 :                 SwTextNode *pTextNode = pPos->nNode.GetNode().GetTextNode();
     574             :                 OSL_ENSURE( pTextNode->HasHints(), "Missing FlyInCnt-Hint." );
     575           0 :                 const sal_Int32 nIdx = pPos->nContent.GetIndex();
     576             :                 SwTextAttr * pHint = pTextNode->GetTextAttrForCharAt(
     577           0 :                         nIdx, RES_TXTATR_FLYCNT );
     578             :                 OSL_ENSURE( pHint && pHint->Which() == RES_TXTATR_FLYCNT,
     579             :                             "Missing FlyInCnt-Hint." );
     580             :                 OSL_ENSURE( pHint && pHint->GetFlyCnt().GetFrameFormat() == pFrameFormat,
     581             :                             "Wrong TextFlyCnt-Hint." );
     582           0 :                 const_cast<SwFormatFlyCnt&>(pHint->GetFlyCnt()).SetFlyFormat();
     583             : 
     584             :                 // Connection is now detached, therefore the attribute can be
     585             :                 // deleted
     586           0 :                 pTextNode->DeleteAttributes( RES_TXTATR_FLYCNT, nIdx, nIdx );
     587             :             }
     588             : 
     589             :             // reposition anchor
     590           0 :             SwFormatAnchor aNewAnchor( (RndStdIds) nOldAnchorTyp );
     591           0 :             GetAnchor( aNewAnchor, nOldNode, nOldContent );
     592           0 :             pFrameFormat->SetFormatAttr( aNewAnchor );
     593             : 
     594           0 :             if (FLY_AS_CHAR == aNewAnchor.GetAnchorId())
     595             :             {
     596           0 :                 const SwPosition* pPos = aNewAnchor.GetContentAnchor();
     597           0 :                 SwFormatFlyCnt aFormat( pFrameFormat );
     598           0 :                 pPos->nNode.GetNode().GetTextNode()->InsertItem( aFormat,
     599           0 :                     nOldContent, 0 );
     600             :             }
     601             : 
     602           0 :             pFrameFormat->MakeFrms();
     603             :         }
     604           0 :         rContext.SetSelections(pFrameFormat, 0);
     605             :     }
     606           0 : }
     607             : 
     608           0 : void SwUndoSetFlyFormat::RedoImpl(::sw::UndoRedoContext & rContext)
     609             : {
     610           0 :     SwDoc & rDoc = rContext.GetDoc();
     611             : 
     612             :     // Is the new Format still existent?
     613           0 :     if( rDoc.GetFrameFormats()->Contains( pNewFormat ) )
     614             :     {
     615             : 
     616           0 :         if( bAnchorChgd )
     617             :         {
     618           0 :             SwFormatAnchor aNewAnchor( (RndStdIds) nNewAnchorTyp );
     619           0 :             GetAnchor( aNewAnchor, nNewNode, nNewContent );
     620           0 :             SfxItemSet aSet( rDoc.GetAttrPool(), aFrameFormatSetRange );
     621           0 :             aSet.Put( aNewAnchor );
     622           0 :             rDoc.SetFrameFormatToFly( *pFrameFormat, *pNewFormat, &aSet );
     623             :         }
     624             :         else
     625           0 :             rDoc.SetFrameFormatToFly( *pFrameFormat, *pNewFormat, 0 );
     626             : 
     627           0 :         rContext.SetSelections(pFrameFormat, 0);
     628             :     }
     629           0 : }
     630             : 
     631           0 : void SwUndoSetFlyFormat::PutAttr( sal_uInt16 nWhich, const SfxPoolItem* pItem )
     632             : {
     633           0 :     if( pItem && pItem != GetDfltAttr( nWhich ) )
     634             :     {
     635             :         // Special treatment for this anchor
     636           0 :         if( RES_ANCHOR == nWhich )
     637             :         {
     638             :             // only keep the first change
     639             :             OSL_ENSURE( !bAnchorChgd, "multiple changes of an anchor are not allowed!" );
     640             : 
     641           0 :             bAnchorChgd = true;
     642             : 
     643           0 :             const SwFormatAnchor* pAnchor = static_cast<const SwFormatAnchor*>(pItem);
     644           0 :             switch( nOldAnchorTyp = static_cast<sal_uInt16>(pAnchor->GetAnchorId()) )
     645             :             {
     646             :             case FLY_AS_CHAR:
     647             :             case FLY_AT_CHAR:
     648           0 :                 nOldContent = pAnchor->GetContentAnchor()->nContent.GetIndex();
     649             :                 //fall-through
     650             :             case FLY_AT_PARA:
     651             :             case FLY_AT_FLY:
     652           0 :                 nOldNode = pAnchor->GetContentAnchor()->nNode.GetIndex();
     653           0 :                 break;
     654             : 
     655             :             default:
     656           0 :                 nOldContent = pAnchor->GetPageNum();
     657             :             }
     658             : 
     659           0 :             pAnchor = &pFrameFormat->GetAnchor();
     660           0 :             switch( nNewAnchorTyp = static_cast<sal_uInt16>(pAnchor->GetAnchorId()) )
     661             :             {
     662             :             case FLY_AS_CHAR:
     663             :             case FLY_AT_CHAR:
     664           0 :                 nNewContent = pAnchor->GetContentAnchor()->nContent.GetIndex();
     665             :                 //fall-through
     666             :             case FLY_AT_PARA:
     667             :             case FLY_AT_FLY:
     668           0 :                 nNewNode = pAnchor->GetContentAnchor()->nNode.GetIndex();
     669           0 :                 break;
     670             : 
     671             :             default:
     672           0 :                 nNewContent = pAnchor->GetPageNum();
     673             :             }
     674             :         }
     675             :         else
     676           0 :             pItemSet->Put( *pItem );
     677             :     }
     678             :     else
     679           0 :         pItemSet->InvalidateItem( nWhich );
     680           0 : }
     681             : 
     682           5 : void SwUndoSetFlyFormat::Modify( const SfxPoolItem* pOld, const SfxPoolItem* )
     683             : {
     684           5 :     if( pOld )
     685             :     {
     686           5 :         sal_uInt16 nWhich = pOld->Which();
     687             : 
     688           5 :         if( nWhich < POOLATTR_END )
     689           0 :             PutAttr( nWhich, pOld );
     690           5 :         else if( RES_ATTRSET_CHG == nWhich )
     691             :         {
     692           0 :             SfxItemIter aIter( *static_cast<const SwAttrSetChg*>(pOld)->GetChgSet() );
     693           0 :             const SfxPoolItem* pItem = aIter.GetCurItem();
     694           0 :             while( pItem )
     695             :             {
     696           0 :                 PutAttr( pItem->Which(), pItem );
     697           0 :                 if( aIter.IsAtEnd() )
     698           0 :                     break;
     699           0 :                 pItem = aIter.NextItem();
     700           0 :             }
     701             :         }
     702             :     }
     703         182 : }
     704             : 
     705             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11