LCOV - code coverage report
Current view: top level - libreoffice/sw/source/core/doc - docfly.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 141 460 30.7 %
Date: 2012-12-17 Functions: 9 14 64.3 %
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             : 
      21             : #include <hintids.hxx>
      22             : #include <svl/itemiter.hxx>
      23             : #include <svx/svdobj.hxx>
      24             : #include <svx/svdpage.hxx>
      25             : #include <svx/svdmodel.hxx>
      26             : #include <svx/svdocapt.hxx>
      27             : #include <svx/svdmark.hxx>
      28             : #include <fmtfsize.hxx>
      29             : #include <fmtornt.hxx>
      30             : #include <fmtsrnd.hxx>
      31             : #include <dcontact.hxx>
      32             : 
      33             : #include <ndgrf.hxx>
      34             : #include <doc.hxx>
      35             : #include <IDocumentUndoRedo.hxx>
      36             : #include <ndindex.hxx>
      37             : #include <docary.hxx>
      38             : #include <fmtcntnt.hxx>
      39             : #include <fmtanchr.hxx>
      40             : #include <txtflcnt.hxx>
      41             : #include <fmtflcnt.hxx>
      42             : #include <txtfrm.hxx>
      43             : #include <pagefrm.hxx>
      44             : #include <rootfrm.hxx>
      45             : #include <flyfrms.hxx>
      46             : #include <frmtool.hxx>
      47             : #include <frmfmt.hxx>
      48             : #include <ndtxt.hxx>
      49             : #include <pam.hxx>
      50             : #include <tblsel.hxx>
      51             : #include <swundo.hxx>
      52             : #include <swtable.hxx>
      53             : #include <crstate.hxx>
      54             : #include <UndoCore.hxx>
      55             : #include <UndoAttribute.hxx>
      56             : #include <fmtcnct.hxx>
      57             : #include <dflyobj.hxx>
      58             : #include <undoflystrattr.hxx>
      59             : #include <switerator.hxx>
      60             : 
      61             : extern sal_uInt16 GetHtmlMode( const SwDocShell* );
      62             : 
      63             : using namespace ::com::sun::star;
      64             : 
      65          10 : sal_uInt16 SwDoc::GetFlyCount( FlyCntType eType ) const
      66             : {
      67          10 :     const SwFrmFmts& rFmts = *GetSpzFrmFmts();
      68          10 :     sal_uInt16 nSize = rFmts.size();
      69          10 :     sal_uInt16 nCount = 0;
      70             :     const SwNodeIndex* pIdx;
      71          26 :     for ( sal_uInt16 i = 0; i < nSize; i++)
      72             :     {
      73          16 :         const SwFrmFmt* pFlyFmt = rFmts[ i ];
      74          48 :         if( RES_FLYFRMFMT == pFlyFmt->Which()
      75          16 :             && 0 != ( pIdx = pFlyFmt->GetCntnt().GetCntntIdx() )
      76          16 :             && pIdx->GetNodes().IsDocNodes()
      77             :             )
      78             :         {
      79          16 :             const SwNode* pNd = GetNodes()[ pIdx->GetIndex() + 1 ];
      80             : 
      81          16 :             switch( eType )
      82             :             {
      83             :             case FLYCNTTYPE_FRM:
      84          14 :                 if(!pNd->IsNoTxtNode())
      85          12 :                     nCount++;
      86          14 :                 break;
      87             : 
      88             :             case FLYCNTTYPE_GRF:
      89           2 :                 if( pNd->IsGrfNode() )
      90           2 :                     nCount++;
      91           2 :                 break;
      92             : 
      93             :             case FLYCNTTYPE_OLE:
      94           0 :                 if(pNd->IsOLENode())
      95           0 :                     nCount++;
      96           0 :                 break;
      97             : 
      98             :             default:
      99           0 :                 nCount++;
     100             :             }
     101             :         }
     102             :     }
     103          10 :     return nCount;
     104             : }
     105             : 
     106             : // If you change this, also update SwXFrameEnumeration in unocoll.
     107          14 : SwFrmFmt* SwDoc::GetFlyNum( sal_uInt16 nIdx, FlyCntType eType )
     108             : {
     109          14 :     SwFrmFmts& rFmts = *GetSpzFrmFmts();
     110          14 :     SwFrmFmt* pRetFmt = 0;
     111          14 :     sal_uInt16 nSize = rFmts.size();
     112             :     const SwNodeIndex* pIdx;
     113          14 :     sal_uInt16 nCount = 0;
     114          28 :     for( sal_uInt16 i = 0; !pRetFmt && i < nSize; ++i )
     115             :     {
     116          14 :         SwFrmFmt* pFlyFmt = rFmts[ i ];
     117          42 :         if( RES_FLYFRMFMT == pFlyFmt->Which()
     118          14 :             && 0 != ( pIdx = pFlyFmt->GetCntnt().GetCntntIdx() )
     119          14 :             && pIdx->GetNodes().IsDocNodes()
     120             :             )
     121             :         {
     122          14 :             const SwNode* pNd = GetNodes()[ pIdx->GetIndex() + 1 ];
     123          14 :             switch( eType )
     124             :             {
     125             :             case FLYCNTTYPE_FRM:
     126          12 :                 if( !pNd->IsNoTxtNode() && nIdx == nCount++)
     127          12 :                     pRetFmt = pFlyFmt;
     128          12 :                 break;
     129             :             case FLYCNTTYPE_GRF:
     130           2 :                 if(pNd->IsGrfNode() && nIdx == nCount++ )
     131           2 :                     pRetFmt = pFlyFmt;
     132           2 :                 break;
     133             :             case FLYCNTTYPE_OLE:
     134           0 :                 if(pNd->IsOLENode() && nIdx == nCount++)
     135           0 :                     pRetFmt = pFlyFmt;
     136           0 :                 break;
     137             :             default:
     138           0 :                 if(nIdx == nCount++)
     139           0 :                     pRetFmt = pFlyFmt;
     140             :             }
     141             :         }
     142             :     }
     143          14 :     return pRetFmt;
     144             : }
     145             : 
     146          60 : static Point lcl_FindAnchorLayPos( SwDoc& rDoc, const SwFmtAnchor& rAnch,
     147             :                             const SwFrmFmt* pFlyFmt )
     148             : {
     149          60 :     Point aRet;
     150          60 :     if( rDoc.GetCurrentViewShell() )    //swmod 071107//swmod 071225
     151           0 :         switch( rAnch.GetAnchorId() )
     152             :         {
     153             :         case FLY_AS_CHAR:
     154           0 :             if( pFlyFmt && rAnch.GetCntntAnchor() )
     155             :             {
     156           0 :                 const SwFrm* pOld = ((SwFlyFrmFmt*)pFlyFmt)->GetFrm( &aRet, sal_False );
     157           0 :                 if( pOld )
     158           0 :                     aRet = pOld->Frm().Pos();
     159             :             }
     160           0 :             break;
     161             : 
     162             :         case FLY_AT_PARA:
     163             :         case FLY_AT_CHAR: // LAYER_IMPL
     164           0 :             if( rAnch.GetCntntAnchor() )
     165             :             {
     166           0 :                 const SwPosition *pPos = rAnch.GetCntntAnchor();
     167           0 :                 const SwCntntNode* pNd = pPos->nNode.GetNode().GetCntntNode();
     168           0 :                 const SwFrm* pOld = pNd ? pNd->getLayoutFrm( rDoc.GetCurrentLayout(), &aRet, 0, sal_False ) : 0;
     169           0 :                 if( pOld )
     170           0 :                     aRet = pOld->Frm().Pos();
     171             :             }
     172           0 :             break;
     173             : 
     174             :         case FLY_AT_FLY: // LAYER_IMPL
     175           0 :             if( rAnch.GetCntntAnchor() )
     176             :             {
     177           0 :                 const SwFlyFrmFmt* pFmt = (SwFlyFrmFmt*)rAnch.GetCntntAnchor()->
     178           0 :                                                 nNode.GetNode().GetFlyFmt();
     179           0 :                 const SwFrm* pOld = pFmt ? pFmt->GetFrm( &aRet, sal_False ) : 0;
     180           0 :                 if( pOld )
     181           0 :                     aRet = pOld->Frm().Pos();
     182             :             }
     183           0 :             break;
     184             : 
     185             :         case FLY_AT_PAGE:
     186             :             {
     187           0 :                 sal_uInt16 nPgNum = rAnch.GetPageNum();
     188           0 :                 const SwPageFrm *pPage = (SwPageFrm*)rDoc.GetCurrentLayout()->Lower();
     189           0 :                 for( sal_uInt16 i = 1; (i <= nPgNum) && pPage; ++i,
     190           0 :                                     pPage = (const SwPageFrm*)pPage->GetNext() )
     191           0 :                     if( i == nPgNum )
     192             :                     {
     193           0 :                         aRet = pPage->Frm().Pos();
     194           0 :                         break;
     195             :                     }
     196             :             }
     197           0 :             break;
     198             :         default:
     199           0 :             break;
     200             :         }
     201          60 :     return aRet;
     202             : }
     203             : 
     204             : #define MAKEFRMS 0
     205             : #define IGNOREANCHOR 1
     206             : #define DONTMAKEFRMS 2
     207             : 
     208          52 : sal_Int8 SwDoc::SetFlyFrmAnchor( SwFrmFmt& rFmt, SfxItemSet& rSet, bool bNewFrms )
     209             : {
     210             :     // Changing anchors is almost always allowed.
     211             :     // Exception: Paragraph and character bound frames must not become
     212             :     // page bound, if they are located in the header or footer.
     213          52 :     const SwFmtAnchor &rOldAnch = rFmt.GetAnchor();
     214          52 :     const RndStdIds nOld = rOldAnch.GetAnchorId();
     215             : 
     216          52 :     SwFmtAnchor aNewAnch( (SwFmtAnchor&)rSet.Get( RES_ANCHOR ) );
     217          52 :     RndStdIds nNew = aNewAnch.GetAnchorId();
     218             : 
     219             :     // Is the new anchor valid?
     220          52 :     if( !aNewAnch.GetCntntAnchor() && (FLY_AT_FLY == nNew ||
     221             :         (FLY_AT_PARA == nNew) || (FLY_AS_CHAR == nNew) ||
     222             :         (FLY_AT_CHAR == nNew) ))
     223             :     {
     224           0 :         return IGNOREANCHOR;
     225             :     }
     226             : 
     227          52 :     if( nOld == nNew )
     228          22 :         return DONTMAKEFRMS;
     229             : 
     230             : 
     231          30 :     Point aOldAnchorPos( ::lcl_FindAnchorLayPos( *this, rOldAnch, &rFmt ));
     232          30 :     Point aNewAnchorPos( ::lcl_FindAnchorLayPos( *this, aNewAnch, 0 ));
     233             : 
     234             :     // Destroy the old Frames.
     235             :     // The Views are hidden implicitly, so hiding them another time would be
     236             :     // kind of a show!
     237          30 :     rFmt.DelFrms();
     238             : 
     239          30 :     if ( FLY_AS_CHAR == nOld )
     240             :     {
     241             :         // We need to handle InCntnts in a special way:
     242             :         // The TxtAttribut needs to be destroyed which, unfortunately, also
     243             :         // destroys the format. To avoid that, we disconnect the format from
     244             :         // the attribute.
     245           0 :         const SwPosition *pPos = rOldAnch.GetCntntAnchor();
     246           0 :         SwTxtNode *pTxtNode = pPos->nNode.GetNode().GetTxtNode();
     247             :         OSL_ENSURE( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." );
     248           0 :         const xub_StrLen nIdx = pPos->nContent.GetIndex();
     249             :         SwTxtAttr * const  pHnt =
     250           0 :             pTxtNode->GetTxtAttrForCharAt( nIdx, RES_TXTATR_FLYCNT );
     251             :         OSL_ENSURE( pHnt && pHnt->Which() == RES_TXTATR_FLYCNT,
     252             :                     "Missing FlyInCnt-Hint." );
     253             :         OSL_ENSURE( pHnt && pHnt->GetFlyCnt().GetFrmFmt() == &rFmt,
     254             :                     "Wrong TxtFlyCnt-Hint." );
     255           0 :         if (pHnt)
     256           0 :             const_cast<SwFmtFlyCnt&>(pHnt->GetFlyCnt()).SetFlyFmt();
     257             : 
     258             :         // They are disconnected. We now have to destroy the attribute.
     259           0 :         pTxtNode->DeleteAttributes( RES_TXTATR_FLYCNT, nIdx, nIdx );
     260             :     }
     261             : 
     262             :     // We can finally set the attribute. It needs to be the first one!
     263             :     // Undo depends on it!
     264          30 :     rFmt.SetFmtAttr( aNewAnch );
     265             : 
     266             :     // Correct the position
     267             :     const SfxPoolItem* pItem;
     268          30 :     switch( nNew )
     269             :     {
     270             :     case FLY_AS_CHAR:
     271             :             // If no position attributes are received, we have to make sure
     272             :             // that no forbidden automatic alignment is left.
     273             :         {
     274           0 :             const SwPosition *pPos = aNewAnch.GetCntntAnchor();
     275           0 :             SwTxtNode *pNd = pPos->nNode.GetNode().GetTxtNode();
     276             :             OSL_ENSURE( pNd, "Crsr does not point to TxtNode." );
     277             : 
     278           0 :             SwFmtFlyCnt aFmt( static_cast<SwFlyFrmFmt*>(&rFmt) );
     279           0 :             pNd->InsertItem( aFmt, pPos->nContent.GetIndex(), 0 );
     280             :         }
     281             : 
     282           0 :         if( SFX_ITEM_SET != rSet.GetItemState( RES_VERT_ORIENT, sal_False, &pItem ))
     283             :         {
     284           0 :             SwFmtVertOrient aOldV( rFmt.GetVertOrient() );
     285           0 :             bool bSet = true;
     286           0 :             switch( aOldV.GetVertOrient() )
     287             :             {
     288           0 :             case text::VertOrientation::LINE_TOP:     aOldV.SetVertOrient( text::VertOrientation::TOP );   break;
     289           0 :             case text::VertOrientation::LINE_CENTER:  aOldV.SetVertOrient( text::VertOrientation::CENTER); break;
     290           0 :             case text::VertOrientation::LINE_BOTTOM:  aOldV.SetVertOrient( text::VertOrientation::BOTTOM); break;
     291           0 :             case text::VertOrientation::NONE:         aOldV.SetVertOrient( text::VertOrientation::CENTER); break;
     292             :             default:
     293           0 :                 bSet = false;
     294             :             }
     295           0 :             if( bSet )
     296           0 :                 rSet.Put( aOldV );
     297             :         }
     298           0 :         break;
     299             : 
     300             :     case FLY_AT_PARA:
     301             :     case FLY_AT_CHAR:   // LAYER_IMPL
     302             :     case FLY_AT_FLY:    // LAYER_IMPL
     303             :     case FLY_AT_PAGE:
     304             :         {
     305             :             // If no position attributes are coming in, we correct the position in a way
     306             :             // such that the fly's document coordinates are preserved.
     307             :             // If only the alignment changes in the position attributes (text::RelOrientation::FRAME
     308             :             // vs. text::RelOrientation::PRTAREA), we also correct the position.
     309          30 :             if( SFX_ITEM_SET != rSet.GetItemState( RES_HORI_ORIENT, sal_False, &pItem ))
     310          30 :                 pItem = 0;
     311             : 
     312          30 :             SwFmtHoriOrient aOldH( rFmt.GetHoriOrient() );
     313             : 
     314          30 :             if( text::HoriOrientation::NONE == aOldH.GetHoriOrient() && ( !pItem ||
     315           0 :                 aOldH.GetPos() == ((SwFmtHoriOrient*)pItem)->GetPos() ))
     316             :             {
     317          24 :                 SwTwips nPos = (FLY_AS_CHAR == nOld) ? 0 : aOldH.GetPos();
     318          24 :                 nPos += aOldAnchorPos.X() - aNewAnchorPos.X();
     319             : 
     320          24 :                 if( pItem )
     321             :                 {
     322           0 :                     SwFmtHoriOrient* pH = (SwFmtHoriOrient*)pItem;
     323           0 :                     aOldH.SetHoriOrient( pH->GetHoriOrient() );
     324           0 :                     aOldH.SetRelationOrient( pH->GetRelationOrient() );
     325             :                 }
     326          24 :                 aOldH.SetPos( nPos );
     327          24 :                 rSet.Put( aOldH );
     328             :             }
     329             : 
     330          30 :             if( SFX_ITEM_SET != rSet.GetItemState( RES_VERT_ORIENT, sal_False, &pItem ))
     331          30 :                 pItem = 0;
     332          30 :             SwFmtVertOrient aOldV( rFmt.GetVertOrient() );
     333             : 
     334             :             // #i28922# - correction: compare <aOldV.GetVertOrient() with
     335             :             // <text::VertOrientation::NONE>
     336          30 :             if( text::VertOrientation::NONE == aOldV.GetVertOrient() && (!pItem ||
     337           0 :                 aOldV.GetPos() == ((SwFmtVertOrient*)pItem)->GetPos() ) )
     338             :             {
     339          22 :                 SwTwips nPos = (FLY_AS_CHAR == nOld) ? 0 : aOldV.GetPos();
     340          22 :                 nPos += aOldAnchorPos.Y() - aNewAnchorPos.Y();
     341          22 :                 if( pItem )
     342             :                 {
     343           0 :                     SwFmtVertOrient* pV = (SwFmtVertOrient*)pItem;
     344           0 :                     aOldV.SetVertOrient( pV->GetVertOrient() );
     345           0 :                     aOldV.SetRelationOrient( pV->GetRelationOrient() );
     346             :                 }
     347          22 :                 aOldV.SetPos( nPos );
     348          22 :                 rSet.Put( aOldV );
     349          30 :             }
     350             :         }
     351          30 :         break;
     352             :     default:
     353           0 :         break;
     354             :     }
     355             : 
     356          30 :     if( bNewFrms )
     357           0 :         rFmt.MakeFrms();
     358             : 
     359          30 :     return MAKEFRMS;
     360             : }
     361             : 
     362             : static bool
     363          52 : lcl_SetFlyFrmAttr(SwDoc & rDoc,
     364             :         sal_Int8 (SwDoc::*pSetFlyFrmAnchor)(SwFrmFmt &, SfxItemSet &, bool),
     365             :         SwFrmFmt & rFlyFmt, SfxItemSet & rSet)
     366             : {
     367             :     // #i32968# Inserting columns in the frame causes MakeFrmFmt to put two
     368             :     // objects of type SwUndoFrmFmt on the undo stack. We don't want them.
     369          52 :     ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
     370             : 
     371             :     // Is the anchor attribute included?
     372             :     // If so, we pass it to a special method, which returns sal_True
     373             :     // if the Fly needs to be created anew, because we e.g change the FlyType.
     374             :     sal_Int8 const nMakeFrms =
     375          52 :         (SFX_ITEM_SET == rSet.GetItemState( RES_ANCHOR, sal_False ))
     376          52 :              ?  (rDoc.*pSetFlyFrmAnchor)( rFlyFmt, rSet, false )
     377         104 :              :  DONTMAKEFRMS;
     378             : 
     379             :     const SfxPoolItem* pItem;
     380          52 :     SfxItemIter aIter( rSet );
     381          52 :     SfxItemSet aTmpSet( rDoc.GetAttrPool(), aFrmFmtSetRange );
     382          52 :     sal_uInt16 nWhich = aIter.GetCurItem()->Which();
     383           0 :     do {
     384          52 :         switch( nWhich )
     385             :         {
     386             :         case RES_FILL_ORDER:
     387             :         case RES_BREAK:
     388             :         case RES_PAGEDESC:
     389             :         case RES_CNTNT:
     390             :         case RES_FOOTER:
     391             :             OSL_FAIL( "Unknown Fly attribute." );
     392             :             // no break;
     393             :         case RES_CHAIN:
     394           0 :             rSet.ClearItem( nWhich );
     395           0 :             break;
     396             :         case RES_ANCHOR:
     397          52 :             if( DONTMAKEFRMS != nMakeFrms )
     398          30 :                 break;
     399             : 
     400             :         default:
     401          66 :             if( !IsInvalidItem( aIter.GetCurItem() ) && ( SFX_ITEM_SET !=
     402          22 :                 rFlyFmt.GetAttrSet().GetItemState( nWhich, sal_True, &pItem ) ||
     403          22 :                 *pItem != *aIter.GetCurItem() ))
     404           0 :                 aTmpSet.Put( *aIter.GetCurItem() );
     405          22 :             break;
     406             :         }
     407             : 
     408          52 :         if( aIter.IsAtEnd() )
     409          52 :             break;
     410             : 
     411           0 :     } while( 0 != ( nWhich = aIter.NextItem()->Which() ) );
     412             : 
     413          52 :     if( aTmpSet.Count() )
     414           0 :         rFlyFmt.SetFmtAttr( aTmpSet );
     415             : 
     416          52 :     if( MAKEFRMS == nMakeFrms )
     417          30 :         rFlyFmt.MakeFrms();
     418             : 
     419          52 :     return aTmpSet.Count() || MAKEFRMS == nMakeFrms;
     420             : }
     421             : 
     422          52 : bool SwDoc::SetFlyFrmAttr( SwFrmFmt& rFlyFmt, SfxItemSet& rSet )
     423             : {
     424          52 :     if( !rSet.Count() )
     425           0 :         return false;
     426             : 
     427          52 :     ::std::auto_ptr<SwUndoFmtAttrHelper> pSaveUndo;
     428             : 
     429          52 :     if (GetIDocumentUndoRedo().DoesUndo())
     430             :     {
     431           0 :         GetIDocumentUndoRedo().ClearRedo(); // AppendUndo far below, so leave it
     432           0 :         pSaveUndo.reset( new SwUndoFmtAttrHelper( rFlyFmt ) );
     433             :     }
     434             : 
     435             :     bool const bRet =
     436          52 :         lcl_SetFlyFrmAttr(*this, &SwDoc::SetFlyFrmAnchor, rFlyFmt, rSet);
     437             : 
     438          52 :     if ( pSaveUndo.get() )
     439             :     {
     440           0 :         if ( pSaveUndo->GetUndo() )
     441             :         {
     442           0 :             GetIDocumentUndoRedo().AppendUndo( pSaveUndo->ReleaseUndo() );
     443             :         }
     444             :     }
     445             : 
     446          52 :     SetModified();
     447             : 
     448          52 :     return bRet;
     449             : }
     450             : 
     451             : // #i73249#
     452          42 : void SwDoc::SetFlyFrmTitle( SwFlyFrmFmt& rFlyFrmFmt,
     453             :                             const String& sNewTitle )
     454             : {
     455          42 :     if ( rFlyFrmFmt.GetObjTitle() == sNewTitle )
     456             :     {
     457          42 :         return;
     458             :     }
     459             : 
     460           0 :     ::sw::DrawUndoGuard const drawUndoGuard(GetIDocumentUndoRedo());
     461             : 
     462           0 :     if (GetIDocumentUndoRedo().DoesUndo())
     463             :     {
     464           0 :         GetIDocumentUndoRedo().AppendUndo( new SwUndoFlyStrAttr( rFlyFrmFmt,
     465             :                                           UNDO_FLYFRMFMT_TITLE,
     466             :                                           rFlyFrmFmt.GetObjTitle(),
     467           0 :                                           sNewTitle ) );
     468             :     }
     469             : 
     470           0 :     rFlyFrmFmt.SetObjTitle( sNewTitle, true );
     471             : 
     472           0 :     SetModified();
     473             : }
     474             : 
     475          42 : void SwDoc::SetFlyFrmDescription( SwFlyFrmFmt& rFlyFrmFmt,
     476             :                                   const String& sNewDescription )
     477             : {
     478          42 :     if ( rFlyFrmFmt.GetObjDescription() == sNewDescription )
     479             :     {
     480          42 :         return;
     481             :     }
     482             : 
     483          20 :     ::sw::DrawUndoGuard const drawUndoGuard(GetIDocumentUndoRedo());
     484             : 
     485          20 :     if (GetIDocumentUndoRedo().DoesUndo())
     486             :     {
     487           0 :         GetIDocumentUndoRedo().AppendUndo( new SwUndoFlyStrAttr( rFlyFrmFmt,
     488             :                                           UNDO_FLYFRMFMT_DESCRIPTION,
     489             :                                           rFlyFrmFmt.GetObjDescription(),
     490           0 :                                           sNewDescription ) );
     491             :     }
     492             : 
     493          20 :     rFlyFrmFmt.SetObjDescription( sNewDescription, true );
     494             : 
     495          20 :     SetModified();
     496             : }
     497             : 
     498           2 : bool SwDoc::SetFrmFmtToFly( SwFrmFmt& rFmt, SwFrmFmt& rNewFmt,
     499             :                             SfxItemSet* pSet, bool bKeepOrient )
     500             : {
     501           2 :     bool bChgAnchor = false, bFrmSz = false;
     502             : 
     503           2 :     const SwFmtFrmSize aFrmSz( rFmt.GetFrmSize() );
     504           2 :     const SwFmtVertOrient aVert( rFmt.GetVertOrient() );
     505           2 :     const SwFmtHoriOrient aHori( rFmt.GetHoriOrient() );
     506             : 
     507           2 :     SwUndoSetFlyFmt* pUndo = 0;
     508           2 :     bool const bUndo = GetIDocumentUndoRedo().DoesUndo();
     509           2 :     if (bUndo)
     510             :     {
     511           0 :         pUndo = new SwUndoSetFlyFmt( rFmt, rNewFmt );
     512           0 :         GetIDocumentUndoRedo().AppendUndo(pUndo);
     513             :     }
     514             : 
     515             :     // #i32968# Inserting columns in the section causes MakeFrmFmt to put
     516             :     // 2 objects of type SwUndoFrmFmt on the undo stack. We don't want them.
     517           2 :     ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo());
     518             : 
     519             :     // Set the column first, or we'll have trouble with
     520             :     //Set/Reset/Synch. and so on
     521             :     const SfxPoolItem* pItem;
     522           2 :     if( SFX_ITEM_SET != rNewFmt.GetAttrSet().GetItemState( RES_COL ))
     523           2 :         rFmt.ResetFmtAttr( RES_COL );
     524             : 
     525           2 :     if( rFmt.DerivedFrom() != &rNewFmt )
     526             :     {
     527           0 :         rFmt.SetDerivedFrom( &rNewFmt );
     528             : 
     529             :         // 1. If not automatic = ignore; else = dispose
     530             :         // 2. Dispose of it!
     531           0 :         if( SFX_ITEM_SET == rNewFmt.GetAttrSet().GetItemState( RES_FRM_SIZE, sal_False ))
     532             :         {
     533           0 :             rFmt.ResetFmtAttr( RES_FRM_SIZE );
     534           0 :             bFrmSz = true;
     535             :         }
     536             : 
     537           0 :         const SfxItemSet* pAsk = pSet;
     538           0 :         if( !pAsk ) pAsk = &rNewFmt.GetAttrSet();
     539           0 :         if( SFX_ITEM_SET == pAsk->GetItemState( RES_ANCHOR, sal_False, &pItem )
     540           0 :             && ((SwFmtAnchor*)pItem)->GetAnchorId() !=
     541           0 :                 rFmt.GetAnchor().GetAnchorId() )
     542             :         {
     543           0 :             if( pSet )
     544           0 :                 bChgAnchor = MAKEFRMS == SetFlyFrmAnchor( rFmt, *pSet, false );
     545             :             else
     546             :             {
     547             :                 // Needs to have the FlyFmt range, because we set attributes in it,
     548             :                 // in SetFlyFrmAnchor.
     549           0 :                 SfxItemSet aFlySet( *rNewFmt.GetAttrSet().GetPool(),
     550           0 :                                     rNewFmt.GetAttrSet().GetRanges() );
     551           0 :                 aFlySet.Put( *pItem );
     552           0 :                 bChgAnchor = MAKEFRMS == SetFlyFrmAnchor( rFmt, aFlySet, false);
     553             :             }
     554             :         }
     555             :     }
     556             : 
     557             :     // Only reset vertical and horizontal orientation, if we have automatic alignment
     558             :     // set in the template. Otherwise use the old value.
     559             :     // If we update the frame template the Fly should NOT lose its orientation (which
     560             :     // is not being updated!).
     561             :     // text::HoriOrientation::NONE and text::VertOrientation::NONE are allowed now
     562           2 :     if (!bKeepOrient)
     563             :     {
     564           2 :         rFmt.ResetFmtAttr(RES_VERT_ORIENT);
     565           2 :         rFmt.ResetFmtAttr(RES_HORI_ORIENT);
     566             :     }
     567             : 
     568           2 :     rFmt.ResetFmtAttr( RES_PRINT, RES_SURROUND );
     569           2 :     rFmt.ResetFmtAttr( RES_LR_SPACE, RES_UL_SPACE );
     570           2 :     rFmt.ResetFmtAttr( RES_BACKGROUND, RES_COL );
     571           2 :     rFmt.ResetFmtAttr( RES_URL, RES_EDIT_IN_READONLY );
     572             : 
     573           2 :     if( !bFrmSz )
     574           2 :         rFmt.SetFmtAttr( aFrmSz );
     575             : 
     576           2 :     if( bChgAnchor )
     577           0 :         rFmt.MakeFrms();
     578             : 
     579           2 :     if( pUndo )
     580           0 :         pUndo->DeRegisterFromFormat( rFmt );
     581             : 
     582           2 :     SetModified();
     583             : 
     584           2 :     return bChgAnchor;
     585             : }
     586             : 
     587           0 : void SwDoc::GetGrfNms( const SwFlyFrmFmt& rFmt, String* pGrfName,
     588             :                         String* pFltName ) const
     589             : {
     590           0 :     SwNodeIndex aIdx( *rFmt.GetCntnt().GetCntntIdx(), 1 );
     591           0 :     const SwGrfNode* pGrfNd = aIdx.GetNode().GetGrfNode();
     592           0 :     if( pGrfNd && pGrfNd->IsLinkedFile() )
     593           0 :         pGrfNd->GetFileFilterNms( pGrfName, pFltName );
     594           0 : }
     595             : 
     596           0 : bool SwDoc::ChgAnchor( const SdrMarkList& _rMrkList,
     597             :                            RndStdIds _eAnchorType,
     598             :                            const bool _bSameOnly,
     599             :                            const bool _bPosCorr )
     600             : {
     601             :     OSL_ENSURE( GetCurrentLayout(), "No layout!" );
     602             : 
     603           0 :     if ( !_rMrkList.GetMarkCount() ||
     604           0 :          _rMrkList.GetMark( 0 )->GetMarkedSdrObj()->GetUpGroup() )
     605             :     {
     606           0 :         return false;
     607             :     }
     608             : 
     609           0 :     GetIDocumentUndoRedo().StartUndo( UNDO_INSATTR, NULL );
     610             : 
     611           0 :     bool bUnmark = false;
     612           0 :     for ( sal_uInt16 i = 0; i < _rMrkList.GetMarkCount(); ++i )
     613             :     {
     614           0 :         SdrObject* pObj = _rMrkList.GetMark( i )->GetMarkedSdrObj();
     615           0 :         if ( !pObj->ISA(SwVirtFlyDrawObj) )
     616             :         {
     617           0 :             SwDrawContact* pContact = static_cast<SwDrawContact*>(GetUserCall(pObj));
     618             : 
     619             :             // consider, that drawing object has
     620             :             // no user call. E.g.: a 'virtual' drawing object is disconnected by
     621             :             // the anchor type change of the 'master' drawing object.
     622             :             // Continue with next selected object and assert, if this isn't excepted.
     623           0 :             if ( !pContact )
     624             :             {
     625             : #if OSL_DEBUG_LEVEL > 0
     626             :                 bool bNoUserCallExcepted =
     627             :                         pObj->ISA(SwDrawVirtObj) &&
     628             :                         !static_cast<SwDrawVirtObj*>(pObj)->IsConnected();
     629             :                 OSL_ENSURE( bNoUserCallExcepted, "SwDoc::ChgAnchor(..) - no contact at selected drawing object" );
     630             : #endif
     631           0 :                 continue;
     632             :             }
     633             : 
     634             :             // #i26791#
     635           0 :             const SwFrm* pOldAnchorFrm = pContact->GetAnchorFrm( pObj );
     636           0 :             const SwFrm* pNewAnchorFrm = pOldAnchorFrm;
     637             : 
     638             :             // #i54336#
     639             :             // Instead of only keeping the index position for an as-character
     640             :             // anchored object the complete <SwPosition> is kept, because the
     641             :             // anchor index position could be moved, if the object again is
     642             :             // anchored as character.
     643           0 :             const SwPosition* pOldAsCharAnchorPos( 0L );
     644           0 :             const RndStdIds eOldAnchorType = pContact->GetAnchorId();
     645           0 :             if ( !_bSameOnly && eOldAnchorType == FLY_AS_CHAR )
     646             :             {
     647           0 :                 pOldAsCharAnchorPos = new SwPosition( pContact->GetCntntAnchor() );
     648             :             }
     649             : 
     650           0 :             if ( _bSameOnly )
     651           0 :                 _eAnchorType = eOldAnchorType;
     652             : 
     653           0 :             SwFmtAnchor aNewAnch( _eAnchorType );
     654           0 :             Rectangle aObjRect( pContact->GetAnchoredObj( pObj )->GetObjRect().SVRect() );
     655           0 :             const Point aPt( aObjRect.TopLeft() );
     656             : 
     657           0 :             switch ( _eAnchorType )
     658             :             {
     659             :             case FLY_AT_PARA:
     660             :             case FLY_AT_CHAR:
     661             :                 {
     662             :                     const Point aNewPoint = pOldAnchorFrm &&
     663           0 :                                             ( pOldAnchorFrm->IsVertical() ||
     664           0 :                                               pOldAnchorFrm->IsRightToLeft() )
     665             :                                             ? aObjRect.TopRight()
     666           0 :                                             : aPt;
     667             : 
     668             :                     // allow drawing objects in header/footer
     669           0 :                     pNewAnchorFrm = ::FindAnchor( pOldAnchorFrm, aNewPoint, false );
     670           0 :                     if ( pNewAnchorFrm->IsTxtFrm() && ((SwTxtFrm*)pNewAnchorFrm)->IsFollow() )
     671             :                     {
     672           0 :                         pNewAnchorFrm = ((SwTxtFrm*)pNewAnchorFrm)->FindMaster();
     673             :                     }
     674           0 :                     if ( pNewAnchorFrm->IsProtected() )
     675             :                     {
     676           0 :                         pNewAnchorFrm = 0;
     677             :                     }
     678             :                     else
     679             :                     {
     680           0 :                         SwPosition aPos( *((SwCntntFrm*)pNewAnchorFrm)->GetNode() );
     681           0 :                         aNewAnch.SetType( _eAnchorType );
     682           0 :                         aNewAnch.SetAnchor( &aPos );
     683             :                     }
     684             :                 }
     685           0 :                 break;
     686             : 
     687             :             case FLY_AT_FLY: // LAYER_IMPL
     688             :                 {
     689             :                     // Search the closest SwFlyFrm starting from the upper left corner.
     690             :                     SwFrm *pTxtFrm;
     691             :                     {
     692           0 :                         SwCrsrMoveState aState( MV_SETONLYTEXT );
     693           0 :                         SwPosition aPos( GetNodes() );
     694           0 :                         Point aPoint( aPt );
     695           0 :                         aPoint.X() -= 1;
     696           0 :                         GetCurrentLayout()->GetCrsrOfst( &aPos, aPoint, &aState );
     697             :                         // consider that drawing objects can be in
     698             :                         // header/footer. Thus, <GetFrm()> by left-top-corner
     699           0 :                         pTxtFrm = aPos.nNode.GetNode().
     700           0 :                                         GetCntntNode()->getLayoutFrm( GetCurrentLayout(), &aPt, 0, sal_False );
     701             :                     }
     702           0 :                     const SwFrm *pTmp = ::FindAnchor( pTxtFrm, aPt );
     703           0 :                     pNewAnchorFrm = pTmp->FindFlyFrm();
     704           0 :                     if( pNewAnchorFrm && !pNewAnchorFrm->IsProtected() )
     705             :                     {
     706           0 :                         const SwFrmFmt *pTmpFmt = ((SwFlyFrm*)pNewAnchorFrm)->GetFmt();
     707           0 :                         const SwFmtCntnt& rCntnt = pTmpFmt->GetCntnt();
     708           0 :                         SwPosition aPos( *rCntnt.GetCntntIdx() );
     709           0 :                         aNewAnch.SetAnchor( &aPos );
     710           0 :                         break;
     711             :                     }
     712             : 
     713           0 :                     aNewAnch.SetType( FLY_AT_PAGE );
     714             :                     // no break
     715             :                 }
     716             :             case FLY_AT_PAGE:
     717             :                 {
     718           0 :                     pNewAnchorFrm = GetCurrentLayout()->Lower();
     719           0 :                     while ( pNewAnchorFrm && !pNewAnchorFrm->Frm().IsInside( aPt ) )
     720           0 :                         pNewAnchorFrm = pNewAnchorFrm->GetNext();
     721           0 :                     if ( !pNewAnchorFrm )
     722           0 :                         continue;
     723             : 
     724           0 :                     aNewAnch.SetPageNum( ((SwPageFrm*)pNewAnchorFrm)->GetPhyPageNum());
     725             :                 }
     726           0 :                 break;
     727             :             case FLY_AS_CHAR:
     728           0 :                 if( _bSameOnly )    // Change of position/size
     729             :                 {
     730           0 :                     if( !pOldAnchorFrm )
     731             :                     {
     732           0 :                         pContact->ConnectToLayout();
     733           0 :                         pOldAnchorFrm = pContact->GetAnchorFrm();
     734             :                     }
     735           0 :                     ((SwTxtFrm*)pOldAnchorFrm)->Prepare();
     736             :                 }
     737             :                 else            // Change of anchors
     738             :                 {
     739             :                     // allow drawing objects in header/footer
     740           0 :                     pNewAnchorFrm = ::FindAnchor( pOldAnchorFrm, aPt, false );
     741           0 :                     if( pNewAnchorFrm->IsProtected() )
     742             :                     {
     743           0 :                         pNewAnchorFrm = 0;
     744             :                         break;
     745             :                     }
     746             : 
     747           0 :                     bUnmark = ( 0 != i );
     748           0 :                     Point aPoint( aPt );
     749           0 :                     aPoint.X() -= 1;    // Do not load in the DrawObj!
     750           0 :                     aNewAnch.SetType( FLY_AS_CHAR );
     751           0 :                     SwPosition aPos( *((SwCntntFrm*)pNewAnchorFrm)->GetNode() );
     752           0 :                     if ( pNewAnchorFrm->Frm().IsInside( aPoint ) )
     753             :                     {
     754             :                     // We need to find a TextNode, because only there we can anchor a
     755             :                     // content-bound DrawObject.
     756           0 :                         SwCrsrMoveState aState( MV_SETONLYTEXT );
     757           0 :                         GetCurrentLayout()->GetCrsrOfst( &aPos, aPoint, &aState );  //swmod 080218
     758             :                     }
     759             :                     else
     760             :                     {
     761             :                         SwCntntNode &rCNd = (SwCntntNode&)
     762           0 :                             *((SwCntntFrm*)pNewAnchorFrm)->GetNode();
     763           0 :                         if ( pNewAnchorFrm->Frm().Bottom() < aPt.Y() )
     764           0 :                             rCNd.MakeStartIndex( &aPos.nContent );
     765             :                         else
     766           0 :                             rCNd.MakeEndIndex( &aPos.nContent );
     767             :                     }
     768           0 :                     aNewAnch.SetAnchor( &aPos );
     769           0 :                     SetAttr( aNewAnch, *pContact->GetFmt() );
     770             :                     // #i26791# - adjust vertical positioning to 'center to
     771             :                     // baseline'
     772           0 :                     SetAttr( SwFmtVertOrient( 0, text::VertOrientation::CENTER, text::RelOrientation::FRAME ), *pContact->GetFmt() );
     773           0 :                     SwTxtNode *pNd = aPos.nNode.GetNode().GetTxtNode();
     774             :                     OSL_ENSURE( pNd, "Cursor not positioned at TxtNode." );
     775             : 
     776           0 :                     SwFmtFlyCnt aFmt( pContact->GetFmt() );
     777           0 :                     pNd->InsertItem( aFmt, aPos.nContent.GetIndex(), 0 );
     778             :                 }
     779           0 :                 break;
     780             :             default:
     781             :                 OSL_ENSURE( !this, "unexpected AnchorId." );
     782             :             }
     783             : 
     784           0 :             if ( (FLY_AS_CHAR != _eAnchorType) &&
     785             :                  pNewAnchorFrm &&
     786           0 :                  ( !_bSameOnly || pNewAnchorFrm != pOldAnchorFrm ) )
     787             :             {
     788             :                 // #i26791# - Direct object positioning no longer needed. Apply
     789             :                 // of attributes (method call <SetAttr(..)>) takes care of the
     790             :                 // invalidation of the object position.
     791           0 :                 SetAttr( aNewAnch, *pContact->GetFmt() );
     792           0 :                 if ( _bPosCorr )
     793             :                 {
     794             :                     // #i33313# - consider not connected 'virtual' drawing
     795             :                     // objects
     796           0 :                     if ( pObj->ISA(SwDrawVirtObj) &&
     797           0 :                          !static_cast<SwDrawVirtObj*>(pObj)->IsConnected() )
     798             :                     {
     799           0 :                         SwRect aNewObjRect( aObjRect );
     800           0 :                         static_cast<SwAnchoredDrawObject*>(pContact->GetAnchoredObj( 0L ))
     801             :                                         ->AdjustPositioningAttr( pNewAnchorFrm,
     802           0 :                                                                  &aNewObjRect );
     803             : 
     804             :                     }
     805             :                     else
     806             :                     {
     807           0 :                         static_cast<SwAnchoredDrawObject*>(pContact->GetAnchoredObj( pObj ))
     808           0 :                                     ->AdjustPositioningAttr( pNewAnchorFrm );
     809             :                     }
     810             :                 }
     811             :             }
     812             : 
     813             :             // #i54336#
     814           0 :             if ( pNewAnchorFrm && pOldAsCharAnchorPos )
     815             :             {
     816             :                 // We need to handle InCntnts in a special way:
     817             :                 // The TxtAttribut needs to be destroyed which, unfortunately, also
     818             :                 // destroys the format. To avoid that, we disconnect the format from
     819             :                 // the attribute.
     820           0 :                 const xub_StrLen nIndx( pOldAsCharAnchorPos->nContent.GetIndex() );
     821           0 :                 SwTxtNode* pTxtNode( pOldAsCharAnchorPos->nNode.GetNode().GetTxtNode() );
     822             :                 OSL_ENSURE( pTxtNode, "<SwDoc::ChgAnchor(..)> - missing previous anchor text node for as-character anchored object" );
     823             :                 OSL_ENSURE( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." );
     824             :                 SwTxtAttr * const pHnt =
     825           0 :                     pTxtNode->GetTxtAttrForCharAt( nIndx, RES_TXTATR_FLYCNT );
     826           0 :                 const_cast<SwFmtFlyCnt&>(pHnt->GetFlyCnt()).SetFlyFmt();
     827             : 
     828             :                 // They are disconnected. We now have to destroy the attribute.
     829           0 :                 pTxtNode->DeleteAttributes( RES_TXTATR_FLYCNT, nIndx, nIndx );
     830           0 :                 delete pOldAsCharAnchorPos;
     831           0 :             }
     832             :         }
     833             :     }
     834             : 
     835           0 :     GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
     836           0 :     SetModified();
     837             : 
     838           0 :     return bUnmark;
     839             : }
     840             : 
     841           0 : int SwDoc::Chainable( const SwFrmFmt &rSource, const SwFrmFmt &rDest )
     842             : {
     843             :     // The Source must not yet have a Follow.
     844           0 :     const SwFmtChain &rOldChain = rSource.GetChain();
     845           0 :     if ( rOldChain.GetNext() )
     846           0 :         return SW_CHAIN_SOURCE_CHAINED;
     847             : 
     848             :     // Target must not be equal to Source and we also must not have a closed chain.
     849           0 :     const SwFrmFmt *pFmt = &rDest;
     850           0 :     do {
     851           0 :         if( pFmt == &rSource )
     852           0 :             return SW_CHAIN_SELF;
     853           0 :         pFmt = pFmt->GetChain().GetNext();
     854             :     } while ( pFmt );
     855             : 
     856             :     // There must not be a chaining from outside to inside or the other way around.
     857           0 :     if( rDest.IsLowerOf( rSource ) || rSource .IsLowerOf( rDest ) )
     858           0 :         return SW_CHAIN_SELF;
     859             : 
     860             :     // The Target must not yet have a Master.
     861           0 :     const SwFmtChain &rChain = rDest.GetChain();
     862           0 :     if( rChain.GetPrev() )
     863           0 :         return SW_CHAIN_IS_IN_CHAIN;
     864             : 
     865             :     // Target must be empty.
     866           0 :     const SwNodeIndex* pCntIdx = rDest.GetCntnt().GetCntntIdx();
     867           0 :     if( !pCntIdx )
     868           0 :         return SW_CHAIN_NOT_FOUND;
     869             : 
     870           0 :     SwNodeIndex aNxtIdx( *pCntIdx, 1 );
     871           0 :     const SwTxtNode* pTxtNd = aNxtIdx.GetNode().GetTxtNode();
     872           0 :     if( !pTxtNd )
     873           0 :         return SW_CHAIN_NOT_FOUND;
     874             : 
     875           0 :     const sal_uLong nFlySttNd = pCntIdx->GetIndex();
     876           0 :     if( 2 != ( pCntIdx->GetNode().EndOfSectionIndex() - nFlySttNd ) ||
     877           0 :         pTxtNd->GetTxt().Len() )
     878           0 :         return SW_CHAIN_NOT_EMPTY;
     879             : 
     880           0 :     sal_uInt16 nArrLen = GetSpzFrmFmts()->size();
     881           0 :     for( sal_uInt16 n = 0; n < nArrLen; ++n )
     882             :     {
     883           0 :         const SwFmtAnchor& rAnchor = (*GetSpzFrmFmts())[ n ]->GetAnchor();
     884             :         sal_uLong nTstSttNd;
     885             :         // #i20622# - to-frame anchored objects are allowed.
     886           0 :         if ( ((rAnchor.GetAnchorId() == FLY_AT_PARA) ||
     887           0 :               (rAnchor.GetAnchorId() == FLY_AT_CHAR)) &&
     888           0 :              0 != rAnchor.GetCntntAnchor() &&
     889             :              nFlySttNd <= ( nTstSttNd =
     890           0 :                          rAnchor.GetCntntAnchor()->nNode.GetIndex() ) &&
     891             :              nTstSttNd < nFlySttNd + 2 )
     892             :         {
     893           0 :             return SW_CHAIN_NOT_EMPTY;
     894             :         }
     895             :     }
     896             : 
     897             :     // We also need to consider the right area.
     898             :     // Both Flys need to be located in the same area (Body, Header/Footer, Fly).
     899             :     // If the Source is not the selected frame, it's enough to find a suitable
     900             :     // one. e.g. if it's requested by the API.
     901             : 
     902             :     // both in the same fly, header, footer or on the page?
     903           0 :     const SwFmtAnchor &rSrcAnchor = rSource.GetAnchor(),
     904           0 :                       &rDstAnchor = rDest.GetAnchor();
     905           0 :     sal_uLong nEndOfExtras = GetNodes().GetEndOfExtras().GetIndex();
     906           0 :     bool bAllowed = false;
     907           0 :     if ( FLY_AT_PAGE == rSrcAnchor.GetAnchorId() )
     908             :     {
     909           0 :         if ( (FLY_AT_PAGE == rDstAnchor.GetAnchorId()) ||
     910           0 :             ( rDstAnchor.GetCntntAnchor() &&
     911           0 :               rDstAnchor.GetCntntAnchor()->nNode.GetIndex() > nEndOfExtras ))
     912           0 :             bAllowed = true;
     913             :     }
     914           0 :     else if( rSrcAnchor.GetCntntAnchor() && rDstAnchor.GetCntntAnchor() )
     915             :     {
     916           0 :         const SwNodeIndex &rSrcIdx = rSrcAnchor.GetCntntAnchor()->nNode,
     917           0 :                             &rDstIdx = rDstAnchor.GetCntntAnchor()->nNode;
     918           0 :         const SwStartNode* pSttNd = 0;
     919           0 :         if( rSrcIdx == rDstIdx ||
     920             :             ( !pSttNd &&
     921           0 :                 0 != ( pSttNd = rSrcIdx.GetNode().FindFlyStartNode() ) &&
     922           0 :                 pSttNd == rDstIdx.GetNode().FindFlyStartNode() ) ||
     923             :             ( !pSttNd &&
     924           0 :                 0 != ( pSttNd = rSrcIdx.GetNode().FindFooterStartNode() ) &&
     925           0 :                 pSttNd == rDstIdx.GetNode().FindFooterStartNode() ) ||
     926             :             ( !pSttNd &&
     927           0 :                 0 != ( pSttNd = rSrcIdx.GetNode().FindHeaderStartNode() ) &&
     928           0 :                 pSttNd == rDstIdx.GetNode().FindHeaderStartNode() ) ||
     929           0 :             ( !pSttNd && rDstIdx.GetIndex() > nEndOfExtras &&
     930           0 :                             rSrcIdx.GetIndex() > nEndOfExtras ))
     931           0 :             bAllowed = true;
     932             :     }
     933             : 
     934           0 :     return bAllowed ? SW_CHAIN_OK : SW_CHAIN_WRONG_AREA;
     935             : }
     936             : 
     937           0 : int SwDoc::Chain( SwFrmFmt &rSource, const SwFrmFmt &rDest )
     938             : {
     939           0 :     int nErr = Chainable( rSource, rDest );
     940           0 :     if ( !nErr )
     941             :     {
     942           0 :         GetIDocumentUndoRedo().StartUndo( UNDO_CHAINE, NULL );
     943             : 
     944           0 :         SwFlyFrmFmt& rDestFmt = (SwFlyFrmFmt&)rDest;
     945             : 
     946             :         // Attach Follow to the Master.
     947           0 :         SwFmtChain aChain = rDestFmt.GetChain();
     948           0 :         aChain.SetPrev( &(SwFlyFrmFmt&)rSource );
     949           0 :         SetAttr( aChain, rDestFmt );
     950             : 
     951           0 :         SfxItemSet aSet( GetAttrPool(), RES_FRM_SIZE, RES_FRM_SIZE,
     952           0 :                                         RES_CHAIN,  RES_CHAIN, 0 );
     953             : 
     954             :         // Attach Follow to the Master.
     955           0 :         aChain.SetPrev( &(SwFlyFrmFmt&)rSource );
     956           0 :         SetAttr( aChain, rDestFmt );
     957             : 
     958             :         // Attach Master to the Follow.
     959             :         // Make sure that the Master has a fixed height.
     960           0 :         aChain = rSource.GetChain();
     961           0 :         aChain.SetNext( &rDestFmt );
     962           0 :         aSet.Put( aChain );
     963             : 
     964           0 :         SwFmtFrmSize aSize( rSource.GetFrmSize() );
     965           0 :         if ( aSize.GetHeightSizeType() != ATT_FIX_SIZE )
     966             :         {
     967           0 :             SwFlyFrm *pFly = SwIterator<SwFlyFrm,SwFmt>::FirstElement( rSource );
     968           0 :             if ( pFly )
     969           0 :                 aSize.SetHeight( pFly->Frm().Height() );
     970           0 :             aSize.SetHeightSizeType( ATT_FIX_SIZE );
     971           0 :             aSet.Put( aSize );
     972             :         }
     973           0 :         SetAttr( aSet, rSource );
     974             : 
     975           0 :         GetIDocumentUndoRedo().EndUndo( UNDO_CHAINE, NULL );
     976             :     }
     977           0 :     return nErr;
     978             : }
     979             : 
     980           0 : void SwDoc::Unchain( SwFrmFmt &rFmt )
     981             : {
     982           0 :     SwFmtChain aChain( rFmt.GetChain() );
     983           0 :     if ( aChain.GetNext() )
     984             :     {
     985           0 :         GetIDocumentUndoRedo().StartUndo( UNDO_UNCHAIN, NULL );
     986           0 :         SwFrmFmt *pFollow = aChain.GetNext();
     987           0 :         aChain.SetNext( 0 );
     988           0 :         SetAttr( aChain, rFmt );
     989           0 :         aChain = pFollow->GetChain();
     990           0 :         aChain.SetPrev( 0 );
     991           0 :         SetAttr( aChain, *pFollow );
     992           0 :         GetIDocumentUndoRedo().EndUndo( UNDO_UNCHAIN, NULL );
     993           0 :     }
     994           0 : }
     995             : 
     996             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10