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

Generated by: LCOV version 1.10