LCOV - code coverage report
Current view: top level - libreoffice/sw/source/core/undo - undobj1.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 322 0.0 %
Date: 2012-12-17 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 happend 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 =  sal_False;
     146           0 : }
     147             : 
     148           0 : void SwUndoFlyBase::DelFly( SwDoc* pDoc )
     149             : {
     150           0 :     bDelFmt = sal_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             : 
     217             :     // delete from array
     218           0 :     SwFrmFmts& rFlyFmts = *(SwFrmFmts*)pDoc->GetSpzFrmFmts();
     219           0 :     rFlyFmts.erase( std::find( rFlyFmts.begin(), rFlyFmts.end(), pFrmFmt ));
     220           0 : }
     221             : 
     222           0 : SwUndoInsLayFmt::SwUndoInsLayFmt( SwFrmFmt* pFormat, sal_uLong nNodeIdx, xub_StrLen nCntIdx )
     223           0 :     : SwUndoFlyBase( pFormat, RES_DRAWFRMFMT == pFormat->Which() ?
     224             :                                             UNDO_INSDRAWFMT : UNDO_INSLAYFMT ),
     225           0 :     mnCrsrSaveIndexPara( nNodeIdx ), mnCrsrSaveIndexPos( nCntIdx )
     226             : {
     227           0 :     const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor();
     228           0 :     nRndId = static_cast<sal_uInt16>(rAnchor.GetAnchorId());
     229           0 :     bDelFmt = sal_False;
     230           0 :     switch( nRndId )
     231             :     {
     232             :     case FLY_AT_PAGE:
     233           0 :         nNdPgPos = rAnchor.GetPageNum();
     234           0 :         break;
     235             :     case FLY_AT_PARA:
     236             :     case FLY_AT_FLY:
     237           0 :         nNdPgPos = rAnchor.GetCntntAnchor()->nNode.GetIndex();
     238           0 :         break;
     239             :     case FLY_AS_CHAR:
     240             :     case FLY_AT_CHAR:
     241             :         {
     242           0 :             const SwPosition* pPos = rAnchor.GetCntntAnchor();
     243           0 :             nCntPos = pPos->nContent.GetIndex();
     244           0 :             nNdPgPos = pPos->nNode.GetIndex();
     245             :         }
     246           0 :         break;
     247             :     default:
     248             :         OSL_FAIL( "Which FlyFrame?" );
     249             :     }
     250           0 : }
     251             : 
     252           0 : SwUndoInsLayFmt::~SwUndoInsLayFmt()
     253             : {
     254           0 : }
     255             : 
     256           0 : void SwUndoInsLayFmt::UndoImpl(::sw::UndoRedoContext & rContext)
     257             : {
     258           0 :     SwDoc & rDoc(rContext.GetDoc());
     259           0 :     const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt();
     260           0 :     if( rCntnt.GetCntntIdx() )  // no content
     261             :     {
     262           0 :         bool bRemoveIdx = true;
     263           0 :         if( mnCrsrSaveIndexPara > 0 )
     264             :         {
     265             :             SwTxtNode *const pNode =
     266           0 :                 rDoc.GetNodes()[mnCrsrSaveIndexPara]->GetTxtNode();
     267           0 :             if( pNode )
     268             :             {
     269           0 :                 SwNodeIndex aIdx( rDoc.GetNodes(),
     270           0 :                         rCntnt.GetCntntIdx()->GetIndex() );
     271           0 :                 SwNodeIndex aEndIdx( rDoc.GetNodes(),
     272           0 :                         aIdx.GetNode().EndOfSectionIndex() );
     273           0 :                 SwIndex aIndex( pNode, mnCrsrSaveIndexPos );
     274           0 :                 SwPosition aPos( *pNode, aIndex );
     275           0 :                 rDoc.CorrAbs( aIdx, aEndIdx, aPos, sal_True );
     276           0 :                 bRemoveIdx = false;
     277             :             }
     278             :         }
     279           0 :         if( bRemoveIdx )
     280             :         {
     281           0 :             RemoveIdxFromSection( rDoc, rCntnt.GetCntntIdx()->GetIndex() );
     282             :         }
     283             :     }
     284           0 :     DelFly(& rDoc);
     285           0 : }
     286             : 
     287           0 : void SwUndoInsLayFmt::RedoImpl(::sw::UndoRedoContext & rContext)
     288             : {
     289           0 :     InsFly(rContext);
     290           0 : }
     291             : 
     292           0 : void SwUndoInsLayFmt::RepeatImpl(::sw::RepeatContext & rContext)
     293             : {
     294           0 :     SwDoc *const pDoc = & rContext.GetDoc();
     295             :     // get anchor and reset it
     296           0 :     SwFmtAnchor aAnchor( pFrmFmt->GetAnchor() );
     297           0 :     if ((FLY_AT_PARA == aAnchor.GetAnchorId()) ||
     298           0 :         (FLY_AT_CHAR == aAnchor.GetAnchorId()) ||
     299           0 :         (FLY_AS_CHAR == aAnchor.GetAnchorId()))
     300             :     {
     301           0 :         SwPosition aPos( *rContext.GetRepeatPaM().GetPoint() );
     302           0 :         if (FLY_AT_PARA == aAnchor.GetAnchorId())
     303             :         {
     304           0 :             aPos.nContent.Assign( 0, 0 );
     305             :         }
     306           0 :         aAnchor.SetAnchor( &aPos );
     307             :     }
     308           0 :     else if( FLY_AT_FLY == aAnchor.GetAnchorId() )
     309             :     {
     310             :         SwStartNode const*const pSttNd =
     311           0 :             rContext.GetRepeatPaM().GetNode()->FindFlyStartNode();
     312           0 :         if( pSttNd )
     313             :         {
     314           0 :             SwPosition aPos( *pSttNd );
     315           0 :             aAnchor.SetAnchor( &aPos );
     316             :         }
     317             :         else
     318             :         {
     319           0 :             return ;
     320             :         }
     321             :     }
     322           0 :     else if (FLY_AT_PAGE == aAnchor.GetAnchorId())
     323             :     {
     324           0 :         aAnchor.SetPageNum( pDoc->GetCurrentLayout()->GetCurrPage( &rContext.GetRepeatPaM() ));
     325             :     }
     326             :     else {
     327             :         OSL_FAIL( "What kind of anchor is this?" );
     328             :     }
     329             : 
     330           0 :     SwFrmFmt* pFlyFmt = pDoc->CopyLayoutFmt( *pFrmFmt, aAnchor, true, true );
     331           0 :     (void) pFlyFmt;
     332             : }
     333             : 
     334             : // #111827#
     335           0 : rtl::OUString SwUndoInsLayFmt::GetComment() const
     336             : {
     337           0 :     String aResult;
     338             : 
     339             :     // HACK: disable caching:
     340             :     // the SfxUndoManager calls GetComment() too early: the pFrmFmt does not
     341             :     // have a SwDrawContact yet, so it will fall back to SwUndo::GetComment(),
     342             :     // which sets pComment to a wrong value.
     343             : //    if (! pComment)
     344             :     if (true)
     345             :     {
     346             :         /*
     347             :           If frame format is present and has an SdrObject use the undo
     348             :           comment of the SdrObject. Otherwise use the default comment.
     349             :         */
     350           0 :         bool bDone = false;
     351           0 :         if (pFrmFmt)
     352             :         {
     353           0 :             const SdrObject * pSdrObj = pFrmFmt->FindSdrObject();
     354           0 :             if ( pSdrObj )
     355             :             {
     356           0 :                 aResult = SdrUndoNewObj::GetComment( *pSdrObj );
     357           0 :                 bDone = true;
     358             :             }
     359             :         }
     360             : 
     361           0 :         if (! bDone)
     362           0 :             aResult = SwUndo::GetComment();
     363             :     }
     364             :     else
     365             :         aResult = *pComment;
     366             : 
     367           0 :     return aResult;
     368             : }
     369             : 
     370             : static SwUndoId
     371           0 : lcl_GetSwUndoId(SwFrmFmt *const pFrmFmt)
     372             : {
     373           0 :     if (RES_DRAWFRMFMT != pFrmFmt->Which())
     374             :     {
     375           0 :         const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt();
     376             :         OSL_ENSURE( rCntnt.GetCntntIdx(), "Fly without content" );
     377             : 
     378           0 :         SwNodeIndex firstNode(*rCntnt.GetCntntIdx(), 1);
     379           0 :         SwNoTxtNode *const pNoTxtNode(firstNode.GetNode().GetNoTxtNode());
     380           0 :         if (pNoTxtNode && pNoTxtNode->IsGrfNode())
     381             :         {
     382           0 :             return UNDO_DELGRF;
     383             :         }
     384           0 :         else if (pNoTxtNode && pNoTxtNode->IsOLENode())
     385             :         {
     386             :             // surprisingly not UNDO_DELOLE, which does not seem to work
     387           0 :             return UNDO_DELETE;
     388           0 :         }
     389             :     }
     390           0 :     return UNDO_DELLAYFMT;
     391             : }
     392             : 
     393           0 : SwUndoDelLayFmt::SwUndoDelLayFmt( SwFrmFmt* pFormat )
     394             :     : SwUndoFlyBase( pFormat, lcl_GetSwUndoId(pFormat) )
     395           0 :     , bShowSelFrm( sal_True )
     396             : {
     397           0 :     SwDoc* pDoc = pFormat->GetDoc();
     398           0 :     DelFly( pDoc );
     399           0 : }
     400             : 
     401           0 : SwRewriter SwUndoDelLayFmt::GetRewriter() const
     402             : {
     403           0 :     SwRewriter aRewriter;
     404             : 
     405           0 :     SwDoc * pDoc = pFrmFmt->GetDoc();
     406             : 
     407           0 :     if (pDoc)
     408             :     {
     409           0 :         SwNodeIndex* pIdx = GetMvSttIdx();
     410           0 :         if( 1 == GetMvNodeCnt() && pIdx)
     411             :         {
     412           0 :             SwNode *const pNd = & pIdx->GetNode();
     413             : 
     414           0 :             if ( pNd->IsNoTxtNode() && pNd->IsOLENode())
     415             :             {
     416           0 :                 SwOLENode * pOLENd = pNd->GetOLENode();
     417             : 
     418           0 :                 aRewriter.AddRule(UndoArg1, pOLENd->GetDescription());
     419             :             }
     420             :         }
     421             :     }
     422             : 
     423           0 :     return aRewriter;
     424             : }
     425             : 
     426           0 : void SwUndoDelLayFmt::UndoImpl(::sw::UndoRedoContext & rContext)
     427             : {
     428           0 :     InsFly( rContext, bShowSelFrm );
     429           0 : }
     430             : 
     431           0 : void SwUndoDelLayFmt::RedoImpl(::sw::UndoRedoContext & rContext)
     432             : {
     433           0 :     SwDoc & rDoc(rContext.GetDoc());
     434           0 :     const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt();
     435           0 :     if( rCntnt.GetCntntIdx() )  // no content
     436             :     {
     437           0 :         RemoveIdxFromSection(rDoc, rCntnt.GetCntntIdx()->GetIndex());
     438             :     }
     439             : 
     440           0 :     DelFly(& rDoc);
     441           0 : }
     442             : 
     443           0 : void SwUndoDelLayFmt::RedoForRollback()
     444             : {
     445           0 :     const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt();
     446           0 :     if( rCntnt.GetCntntIdx() )  // no content
     447           0 :         RemoveIdxFromSection( *pFrmFmt->GetDoc(),
     448           0 :                                 rCntnt.GetCntntIdx()->GetIndex() );
     449             : 
     450           0 :     DelFly( pFrmFmt->GetDoc() );
     451           0 : }
     452             : 
     453           0 : SwUndoSetFlyFmt::SwUndoSetFlyFmt( SwFrmFmt& rFlyFmt, SwFrmFmt& rNewFrmFmt )
     454             :     : SwUndo( UNDO_SETFLYFRMFMT ), SwClient( &rFlyFmt ), pFrmFmt( &rFlyFmt ),
     455           0 :     pOldFmt( (SwFrmFmt*)rFlyFmt.DerivedFrom() ), pNewFmt( &rNewFrmFmt ),
     456           0 :     pItemSet( new SfxItemSet( *rFlyFmt.GetAttrSet().GetPool(),
     457           0 :                                 rFlyFmt.GetAttrSet().GetRanges() )),
     458             :     nOldNode( 0 ), nNewNode( 0 ),
     459             :     nOldCntnt( 0 ), nNewCntnt( 0 ),
     460           0 :     nOldAnchorTyp( 0 ), nNewAnchorTyp( 0 ), bAnchorChgd( sal_False )
     461             : {
     462           0 : }
     463             : 
     464           0 : SwRewriter SwUndoSetFlyFmt::GetRewriter() const
     465             : {
     466           0 :     SwRewriter aRewriter;
     467             : 
     468           0 :     if (pNewFmt)
     469           0 :         aRewriter.AddRule(UndoArg1, pNewFmt->GetName());
     470             : 
     471           0 :     return aRewriter;
     472             : }
     473             : 
     474           0 : SwUndoSetFlyFmt::~SwUndoSetFlyFmt()
     475             : {
     476           0 :     delete pItemSet;
     477           0 : }
     478             : 
     479           0 : void SwUndoSetFlyFmt::DeRegisterFromFormat( SwFmt& rFmt )
     480             : {
     481           0 :     rFmt.Remove(this);
     482           0 : }
     483             : 
     484           0 : void SwUndoSetFlyFmt::GetAnchor( SwFmtAnchor& rAnchor,
     485             :                                 sal_uLong nNode, xub_StrLen nCntnt )
     486             : {
     487           0 :     RndStdIds nAnchorTyp = rAnchor.GetAnchorId();
     488           0 :     if (FLY_AT_PAGE != nAnchorTyp)
     489             :     {
     490           0 :         SwNode* pNd = pFrmFmt->GetDoc()->GetNodes()[ nNode ];
     491             : 
     492           0 :         if( FLY_AT_FLY == nAnchorTyp
     493           0 :                 ? ( !pNd->IsStartNode() || SwFlyStartNode !=
     494           0 :                     ((SwStartNode*)pNd)->GetStartNodeType() )
     495           0 :                 : !pNd->IsTxtNode() )
     496             :         {
     497           0 :             pNd = 0;    // invalid position
     498             :         }
     499             :         else
     500             :         {
     501           0 :             SwPosition aPos( *pNd );
     502           0 :             if ((FLY_AS_CHAR == nAnchorTyp) ||
     503             :                 (FLY_AT_CHAR == nAnchorTyp))
     504             :             {
     505           0 :                 if ( nCntnt > static_cast<SwTxtNode*>(pNd)->GetTxt().Len() )
     506             :                 {
     507           0 :                     pNd = 0;    // invalid position
     508             :                 }
     509             :                 else
     510             :                 {
     511           0 :                     aPos.nContent.Assign(static_cast<SwTxtNode*>(pNd), nCntnt);
     512             :                 }
     513             :             }
     514           0 :             if ( pNd )
     515             :             {
     516           0 :                 rAnchor.SetAnchor( &aPos );
     517           0 :             }
     518             :         }
     519             : 
     520           0 :         if( !pNd )
     521             :         {
     522             :             // invalid position - assign first page
     523           0 :             rAnchor.SetType( FLY_AT_PAGE );
     524           0 :             rAnchor.SetPageNum( 1 );
     525             :         }
     526             :     }
     527             :     else
     528           0 :         rAnchor.SetPageNum( nCntnt );
     529           0 : }
     530             : 
     531           0 : void SwUndoSetFlyFmt::UndoImpl(::sw::UndoRedoContext & rContext)
     532             : {
     533           0 :     SwDoc & rDoc = rContext.GetDoc();
     534             : 
     535             :     // Is the new Format still existent?
     536           0 :     if( USHRT_MAX != rDoc.GetFrmFmts()->GetPos( (const SwFrmFmt*)pOldFmt ) )
     537             :     {
     538           0 :         if( bAnchorChgd )
     539           0 :             pFrmFmt->DelFrms();
     540             : 
     541           0 :         if( pFrmFmt->DerivedFrom() != pOldFmt )
     542           0 :             pFrmFmt->SetDerivedFrom( pOldFmt );
     543             : 
     544           0 :         SfxItemIter aIter( *pItemSet );
     545           0 :         const SfxPoolItem* pItem = aIter.GetCurItem();
     546           0 :         while( pItem )
     547             :         {
     548           0 :             if( IsInvalidItem( pItem ))
     549             :                 pFrmFmt->ResetFmtAttr( pItemSet->GetWhichByPos(
     550           0 :                                         aIter.GetCurPos() ));
     551             :             else
     552           0 :                 pFrmFmt->SetFmtAttr( *pItem );
     553             : 
     554           0 :             if( aIter.IsAtEnd() )
     555           0 :                 break;
     556           0 :             pItem = aIter.NextItem();
     557             :         }
     558             : 
     559           0 :         if( bAnchorChgd )
     560             :         {
     561           0 :             const SwFmtAnchor& rOldAnch = pFrmFmt->GetAnchor();
     562           0 :             if (FLY_AS_CHAR == rOldAnch.GetAnchorId())
     563             :             {
     564             :                 // With InCntnts it's tricky: the text attribute needs to be
     565             :                 // deleted. Unfortunately, this not only destroys the Frms but
     566             :                 // also the format. To prevent that, first detach the
     567             :                 // connection between attribute and format.
     568           0 :                 const SwPosition *pPos = rOldAnch.GetCntntAnchor();
     569           0 :                 SwTxtNode *pTxtNode = pPos->nNode.GetNode().GetTxtNode();
     570             :                 OSL_ENSURE( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." );
     571           0 :                 const xub_StrLen nIdx = pPos->nContent.GetIndex();
     572             :                 SwTxtAttr * pHnt = pTxtNode->GetTxtAttrForCharAt(
     573           0 :                         nIdx, RES_TXTATR_FLYCNT );
     574             :                 OSL_ENSURE( pHnt && pHnt->Which() == RES_TXTATR_FLYCNT,
     575             :                             "Missing FlyInCnt-Hint." );
     576             :                 OSL_ENSURE( pHnt && pHnt->GetFlyCnt().GetFrmFmt() == pFrmFmt,
     577             :                             "Wrong TxtFlyCnt-Hint." );
     578           0 :                 const_cast<SwFmtFlyCnt&>(pHnt->GetFlyCnt()).SetFlyFmt();
     579             : 
     580             :                 // Connection is now detached, therefore the attribute can be
     581             :                 // deleted
     582           0 :                 pTxtNode->DeleteAttributes( RES_TXTATR_FLYCNT, nIdx, nIdx );
     583             :             }
     584             : 
     585             :             // reposition anchor
     586           0 :             SwFmtAnchor aNewAnchor( (RndStdIds) nOldAnchorTyp );
     587           0 :             GetAnchor( aNewAnchor, nOldNode, nOldCntnt );
     588           0 :             pFrmFmt->SetFmtAttr( aNewAnchor );
     589             : 
     590           0 :             if (FLY_AS_CHAR == aNewAnchor.GetAnchorId())
     591             :             {
     592           0 :                 SwPosition* pPos = (SwPosition*)aNewAnchor.GetCntntAnchor();
     593           0 :                 SwFmtFlyCnt aFmt( pFrmFmt );
     594           0 :                 pPos->nNode.GetNode().GetTxtNode()->InsertItem( aFmt,
     595           0 :                     nOldCntnt, 0 );
     596             :             }
     597             : 
     598           0 :             pFrmFmt->MakeFrms();
     599             :         }
     600           0 :         rContext.SetSelections(pFrmFmt, 0);
     601             :     }
     602           0 : }
     603             : 
     604           0 : void SwUndoSetFlyFmt::RedoImpl(::sw::UndoRedoContext & rContext)
     605             : {
     606           0 :     SwDoc & rDoc = rContext.GetDoc();
     607             : 
     608             :     // Is the new Format still existent?
     609           0 :     if( USHRT_MAX != rDoc.GetFrmFmts()->GetPos( (const SwFrmFmt*)pNewFmt ) )
     610             :     {
     611             : 
     612           0 :         if( bAnchorChgd )
     613             :         {
     614           0 :             SwFmtAnchor aNewAnchor( (RndStdIds) nNewAnchorTyp );
     615           0 :             GetAnchor( aNewAnchor, nNewNode, nNewCntnt );
     616           0 :             SfxItemSet aSet( rDoc.GetAttrPool(), aFrmFmtSetRange );
     617           0 :             aSet.Put( aNewAnchor );
     618           0 :             rDoc.SetFrmFmtToFly( *pFrmFmt, *pNewFmt, &aSet );
     619             :         }
     620             :         else
     621           0 :             rDoc.SetFrmFmtToFly( *pFrmFmt, *pNewFmt, 0 );
     622             : 
     623           0 :         rContext.SetSelections(pFrmFmt, 0);
     624             :     }
     625           0 : }
     626             : 
     627           0 : void SwUndoSetFlyFmt::PutAttr( sal_uInt16 nWhich, const SfxPoolItem* pItem )
     628             : {
     629           0 :     if( pItem && pItem != GetDfltAttr( nWhich ) )
     630             :     {
     631             :         // Special treatment for this anchor
     632           0 :         if( RES_ANCHOR == nWhich )
     633             :         {
     634             :             // only keep the first change
     635             :             OSL_ENSURE( !bAnchorChgd, "multiple changes of an anchor are not allowed!" );
     636             : 
     637           0 :             bAnchorChgd = sal_True;
     638             : 
     639           0 :             const SwFmtAnchor* pAnchor = (SwFmtAnchor*)pItem;
     640           0 :             switch( nOldAnchorTyp = static_cast<sal_uInt16>(pAnchor->GetAnchorId()) )
     641             :             {
     642             :             case FLY_AS_CHAR:
     643             :             case FLY_AT_CHAR:
     644           0 :                 nOldCntnt = pAnchor->GetCntntAnchor()->nContent.GetIndex();
     645             :             case FLY_AT_PARA:
     646             :             case FLY_AT_FLY:
     647           0 :                 nOldNode = pAnchor->GetCntntAnchor()->nNode.GetIndex();
     648           0 :                 break;
     649             : 
     650             :             default:
     651           0 :                 nOldCntnt = pAnchor->GetPageNum();
     652             :             }
     653             : 
     654           0 :             pAnchor = (SwFmtAnchor*)&pFrmFmt->GetAnchor();
     655           0 :             switch( nNewAnchorTyp = static_cast<sal_uInt16>(pAnchor->GetAnchorId()) )
     656             :             {
     657             :             case FLY_AS_CHAR:
     658             :             case FLY_AT_CHAR:
     659           0 :                 nNewCntnt = pAnchor->GetCntntAnchor()->nContent.GetIndex();
     660             :             case FLY_AT_PARA:
     661             :             case FLY_AT_FLY:
     662           0 :                 nNewNode = pAnchor->GetCntntAnchor()->nNode.GetIndex();
     663           0 :                 break;
     664             : 
     665             :             default:
     666           0 :                 nNewCntnt = pAnchor->GetPageNum();
     667             :             }
     668             :         }
     669             :         else
     670           0 :             pItemSet->Put( *pItem );
     671             :     }
     672             :     else
     673           0 :         pItemSet->InvalidateItem( nWhich );
     674           0 : }
     675             : 
     676           0 : void SwUndoSetFlyFmt::Modify( const SfxPoolItem* pOld, const SfxPoolItem* )
     677             : {
     678           0 :     if( pOld )
     679             :     {
     680           0 :         sal_uInt16 nWhich = pOld->Which();
     681             : 
     682           0 :         if( nWhich < POOLATTR_END )
     683           0 :             PutAttr( nWhich, pOld );
     684           0 :         else if( RES_ATTRSET_CHG == nWhich )
     685             :         {
     686           0 :             SfxItemIter aIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
     687           0 :             const SfxPoolItem* pItem = aIter.GetCurItem();
     688           0 :             while( pItem )
     689             :             {
     690           0 :                 PutAttr( pItem->Which(), pItem );
     691           0 :                 if( aIter.IsAtEnd() )
     692           0 :                     break;
     693           0 :                 pItem = aIter.NextItem();
     694           0 :             }
     695             :         }
     696             :     }
     697           0 : }
     698             : 
     699             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10