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

Generated by: LCOV version 1.10