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

Generated by: LCOV version 1.10