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

Generated by: LCOV version 1.11