LCOV - code coverage report
Current view: top level - sw/source/core/doc - docfly.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 321 505 63.6 %
Date: 2014-11-03 Functions: 15 17 88.2 %
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 <switerator.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         592 : sal_uInt16 SwDoc::GetFlyCount( FlyCntType eType, bool bIgnoreTextBoxes ) const
      76             : {
      77         592 :     const SwFrmFmts& rFmts = *GetSpzFrmFmts();
      78         592 :     sal_uInt16 nSize = rFmts.size();
      79         592 :     sal_uInt16 nCount = 0;
      80             :     const SwNodeIndex* pIdx;
      81             : 
      82         592 :     std::set<const SwFrmFmt*> aTextBoxes;
      83         592 :     if (bIgnoreTextBoxes)
      84         536 :         aTextBoxes = SwTextBoxHelper::findTextBoxes(this);
      85             : 
      86        1128 :     for ( sal_uInt16 i = 0; i < nSize; i++)
      87             :     {
      88         536 :         const SwFrmFmt* pFlyFmt = rFmts[ i ];
      89             : 
      90         536 :         if (bIgnoreTextBoxes && aTextBoxes.find(pFlyFmt) != aTextBoxes.end())
      91           8 :             continue;
      92             : 
      93        1056 :         if( RES_FLYFRMFMT == pFlyFmt->Which()
      94         258 :             && 0 != ( pIdx = pFlyFmt->GetCntnt().GetCntntIdx() )
      95         786 :             && pIdx->GetNodes().IsDocNodes()
      96             :             )
      97             :         {
      98         258 :             const SwNode* pNd = GetNodes()[ pIdx->GetIndex() + 1 ];
      99             : 
     100         258 :             switch( eType )
     101             :             {
     102             :             case FLYCNTTYPE_FRM:
     103         196 :                 if(!pNd->IsNoTxtNode())
     104         174 :                     nCount++;
     105         196 :                 break;
     106             : 
     107             :             case FLYCNTTYPE_GRF:
     108          30 :                 if( pNd->IsGrfNode() )
     109          12 :                     nCount++;
     110          30 :                 break;
     111             : 
     112             :             case FLYCNTTYPE_OLE:
     113          32 :                 if(pNd->IsOLENode())
     114          14 :                     nCount++;
     115          32 :                 break;
     116             : 
     117             :             default:
     118           0 :                 nCount++;
     119             :             }
     120             :         }
     121             :     }
     122         592 :     return nCount;
     123             : }
     124             : 
     125             : /// @attention If you change this, also update SwXFrameEnumeration in unocoll.
     126         158 : SwFrmFmt* SwDoc::GetFlyNum( sal_uInt16 nIdx, FlyCntType eType, bool bIgnoreTextBoxes )
     127             : {
     128         158 :     SwFrmFmts& rFmts = *GetSpzFrmFmts();
     129         158 :     SwFrmFmt* pRetFmt = 0;
     130         158 :     sal_uInt16 nSize = rFmts.size();
     131             :     const SwNodeIndex* pIdx;
     132         158 :     sal_uInt16 nCount = 0;
     133             : 
     134         158 :     std::set<const SwFrmFmt*> aTextBoxes;
     135         158 :     if (bIgnoreTextBoxes)
     136          62 :         aTextBoxes = SwTextBoxHelper::findTextBoxes(this);
     137             : 
     138         406 :     for( sal_uInt16 i = 0; !pRetFmt && i < nSize; ++i )
     139             :     {
     140         248 :         SwFrmFmt* pFlyFmt = rFmts[ i ];
     141             : 
     142         248 :         if (bIgnoreTextBoxes && aTextBoxes.find(pFlyFmt) != aTextBoxes.end())
     143           0 :             continue;
     144             : 
     145         496 :         if( RES_FLYFRMFMT == pFlyFmt->Which()
     146         198 :             && 0 != ( pIdx = pFlyFmt->GetCntnt().GetCntntIdx() )
     147         446 :             && pIdx->GetNodes().IsDocNodes()
     148             :             )
     149             :         {
     150         198 :             const SwNode* pNd = GetNodes()[ pIdx->GetIndex() + 1 ];
     151         198 :             switch( eType )
     152             :             {
     153             :             case FLYCNTTYPE_FRM:
     154         124 :                 if( !pNd->IsNoTxtNode() && nIdx == nCount++)
     155          98 :                     pRetFmt = pFlyFmt;
     156         124 :                 break;
     157             :             case FLYCNTTYPE_GRF:
     158          16 :                 if(pNd->IsGrfNode() && nIdx == nCount++ )
     159          10 :                     pRetFmt = pFlyFmt;
     160          16 :                 break;
     161             :             case FLYCNTTYPE_OLE:
     162          58 :                 if(pNd->IsOLENode() && nIdx == nCount++)
     163          44 :                     pRetFmt = pFlyFmt;
     164          58 :                 break;
     165             :             default:
     166           0 :                 if(nIdx == nCount++)
     167           0 :                     pRetFmt = pFlyFmt;
     168             :             }
     169             :         }
     170             :     }
     171         158 :     return pRetFmt;
     172             : }
     173             : 
     174         532 : static Point lcl_FindAnchorLayPos( SwDoc& rDoc, const SwFmtAnchor& rAnch,
     175             :                             const SwFrmFmt* pFlyFmt )
     176             : {
     177         532 :     Point aRet;
     178         532 :     if( rDoc.getIDocumentLayoutAccess().GetCurrentViewShell() )
     179          40 :         switch( rAnch.GetAnchorId() )
     180             :         {
     181             :         case FLY_AS_CHAR:
     182           8 :             if( pFlyFmt && rAnch.GetCntntAnchor() )
     183             :             {
     184           2 :                 const SwFrm* pOld = ((SwFlyFrmFmt*)pFlyFmt)->GetFrm( &aRet, false );
     185           2 :                 if( pOld )
     186           2 :                     aRet = pOld->Frm().Pos();
     187             :             }
     188           8 :             break;
     189             : 
     190             :         case FLY_AT_PARA:
     191             :         case FLY_AT_CHAR: // LAYER_IMPL
     192          20 :             if( rAnch.GetCntntAnchor() )
     193             :             {
     194          20 :                 const SwPosition *pPos = rAnch.GetCntntAnchor();
     195          20 :                 const SwCntntNode* pNd = pPos->nNode.GetNode().GetCntntNode();
     196          20 :                 const SwFrm* pOld = pNd ? pNd->getLayoutFrm( rDoc.getIDocumentLayoutAccess().GetCurrentLayout(), &aRet, 0, false ) : 0;
     197          20 :                 if( pOld )
     198          20 :                     aRet = pOld->Frm().Pos();
     199             :             }
     200          20 :             break;
     201             : 
     202             :         case FLY_AT_FLY: // LAYER_IMPL
     203           0 :             if( rAnch.GetCntntAnchor() )
     204             :             {
     205           0 :                 const SwFlyFrmFmt* pFmt = (SwFlyFrmFmt*)rAnch.GetCntntAnchor()->
     206           0 :                                                 nNode.GetNode().GetFlyFmt();
     207           0 :                 const SwFrm* pOld = pFmt ? pFmt->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          12 :                 sal_uInt16 nPgNum = rAnch.GetPageNum();
     216          12 :                 const SwPageFrm *pPage = (SwPageFrm*)rDoc.getIDocumentLayoutAccess().GetCurrentLayout()->Lower();
     217          12 :                 for( sal_uInt16 i = 1; (i <= nPgNum) && pPage; ++i,
     218           0 :                                     pPage = (const SwPageFrm*)pPage->GetNext() )
     219          12 :                     if( i == nPgNum )
     220             :                     {
     221          12 :                         aRet = pPage->Frm().Pos();
     222          12 :                         break;
     223             :                     }
     224             :             }
     225          12 :             break;
     226             :         default:
     227           0 :             break;
     228             :         }
     229         532 :     return aRet;
     230             : }
     231             : 
     232             : #define MAKEFRMS 0
     233             : #define IGNOREANCHOR 1
     234             : #define DONTMAKEFRMS 2
     235             : 
     236         528 : sal_Int8 SwDoc::SetFlyFrmAnchor( SwFrmFmt& rFmt, 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         528 :     const SwFmtAnchor &rOldAnch = rFmt.GetAnchor();
     242         528 :     const RndStdIds nOld = rOldAnch.GetAnchorId();
     243             : 
     244         528 :     SwFmtAnchor aNewAnch( (SwFmtAnchor&)rSet.Get( RES_ANCHOR ) );
     245         528 :     RndStdIds nNew = aNewAnch.GetAnchorId();
     246             : 
     247             :     // Is the new anchor valid?
     248         530 :     if( !aNewAnch.GetCntntAnchor() && (FLY_AT_FLY == nNew ||
     249           4 :         (FLY_AT_PARA == nNew) || (FLY_AS_CHAR == nNew) ||
     250             :         (FLY_AT_CHAR == nNew) ))
     251             :     {
     252           2 :         return IGNOREANCHOR;
     253             :     }
     254             : 
     255         526 :     if( nOld == nNew )
     256         260 :         return DONTMAKEFRMS;
     257             : 
     258         266 :     Point aOldAnchorPos( ::lcl_FindAnchorLayPos( *this, rOldAnch, &rFmt ));
     259         266 :     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         266 :     rFmt.DelFrms();
     265             : 
     266         266 :     if ( FLY_AS_CHAR == nOld )
     267             :     {
     268             :         // We need to handle InCntnts in a special way:
     269             :         // The TxtAttribut needs to be destroyed which, unfortunately, also
     270             :         // destroys the format. To avoid that, we disconnect the format from
     271             :         // the attribute.
     272           2 :         const SwPosition *pPos = rOldAnch.GetCntntAnchor();
     273           2 :         SwTxtNode *pTxtNode = pPos->nNode.GetNode().GetTxtNode();
     274             :         OSL_ENSURE( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." );
     275           2 :         const sal_Int32 nIdx = pPos->nContent.GetIndex();
     276             :         SwTxtAttr * const  pHnt =
     277           2 :             pTxtNode->GetTxtAttrForCharAt( nIdx, RES_TXTATR_FLYCNT );
     278             :         OSL_ENSURE( pHnt && pHnt->Which() == RES_TXTATR_FLYCNT,
     279             :                     "Missing FlyInCnt-Hint." );
     280             :         OSL_ENSURE( pHnt && pHnt->GetFlyCnt().GetFrmFmt() == &rFmt,
     281             :                     "Wrong TxtFlyCnt-Hint." );
     282           2 :         if (pHnt)
     283           2 :             const_cast<SwFmtFlyCnt&>(pHnt->GetFlyCnt()).SetFlyFmt();
     284             : 
     285             :         // They are disconnected. We now have to destroy the attribute.
     286           2 :         pTxtNode->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         266 :     rFmt.SetFmtAttr( aNewAnch );
     292             : 
     293             :     // Correct the position
     294             :     const SfxPoolItem* pItem;
     295         266 :     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          14 :             const SwPosition *pPos = aNewAnch.GetCntntAnchor();
     302          14 :             SwTxtNode *pNd = pPos->nNode.GetNode().GetTxtNode();
     303             :             OSL_ENSURE( pNd, "Crsr does not point to TxtNode." );
     304             : 
     305          14 :             SwFmtFlyCnt aFmt( static_cast<SwFlyFrmFmt*>(&rFmt) );
     306          14 :             pNd->InsertItem( aFmt, pPos->nContent.GetIndex(), 0 );
     307             :         }
     308             : 
     309          14 :         if( SfxItemState::SET != rSet.GetItemState( RES_VERT_ORIENT, false, &pItem ))
     310             :         {
     311          14 :             SwFmtVertOrient aOldV( rFmt.GetVertOrient() );
     312          14 :             bool bSet = true;
     313          14 :             switch( aOldV.GetVertOrient() )
     314             :             {
     315           2 :             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          12 :                 bSet = false;
     321             :             }
     322          14 :             if( bSet )
     323           2 :                 rSet.Put( aOldV );
     324             :         }
     325          14 :         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         252 :             if( SfxItemState::SET != rSet.GetItemState( RES_HORI_ORIENT, false, &pItem ))
     337         252 :                 pItem = 0;
     338             : 
     339         252 :             SwFmtHoriOrient aOldH( rFmt.GetHoriOrient() );
     340             : 
     341         252 :             if( text::HoriOrientation::NONE == aOldH.GetHoriOrient() && ( !pItem ||
     342           0 :                 aOldH.GetPos() == ((SwFmtHoriOrient*)pItem)->GetPos() ))
     343             :             {
     344         178 :                 SwTwips nPos = (FLY_AS_CHAR == nOld) ? 0 : aOldH.GetPos();
     345         178 :                 nPos += aOldAnchorPos.getX() - aNewAnchorPos.getX();
     346             : 
     347         178 :                 if( pItem )
     348             :                 {
     349           0 :                     SwFmtHoriOrient* pH = (SwFmtHoriOrient*)pItem;
     350           0 :                     aOldH.SetHoriOrient( pH->GetHoriOrient() );
     351           0 :                     aOldH.SetRelationOrient( pH->GetRelationOrient() );
     352             :                 }
     353         178 :                 aOldH.SetPos( nPos );
     354         178 :                 rSet.Put( aOldH );
     355             :             }
     356             : 
     357         252 :             if( SfxItemState::SET != rSet.GetItemState( RES_VERT_ORIENT, false, &pItem ))
     358         252 :                 pItem = 0;
     359         504 :             SwFmtVertOrient aOldV( rFmt.GetVertOrient() );
     360             : 
     361             :             // #i28922# - correction: compare <aOldV.GetVertOrient() with
     362             :             // <text::VertOrientation::NONE>
     363         252 :             if( text::VertOrientation::NONE == aOldV.GetVertOrient() && (!pItem ||
     364           0 :                 aOldV.GetPos() == ((SwFmtVertOrient*)pItem)->GetPos() ) )
     365             :             {
     366         230 :                 SwTwips nPos = (FLY_AS_CHAR == nOld) ? 0 : aOldV.GetPos();
     367         230 :                 nPos += aOldAnchorPos.getY() - aNewAnchorPos.getY();
     368         230 :                 if( pItem )
     369             :                 {
     370           0 :                     SwFmtVertOrient* pV = (SwFmtVertOrient*)pItem;
     371           0 :                     aOldV.SetVertOrient( pV->GetVertOrient() );
     372           0 :                     aOldV.SetRelationOrient( pV->GetRelationOrient() );
     373             :                 }
     374         230 :                 aOldV.SetPos( nPos );
     375         230 :                 rSet.Put( aOldV );
     376         252 :             }
     377             :         }
     378         252 :         break;
     379             :     default:
     380           0 :         break;
     381             :     }
     382             : 
     383         266 :     if( bNewFrms )
     384           0 :         rFmt.MakeFrms();
     385             : 
     386         266 :     return MAKEFRMS;
     387             : }
     388             : 
     389             : static bool
     390         572 : lcl_SetFlyFrmAttr(SwDoc & rDoc,
     391             :         sal_Int8 (SwDoc::*pSetFlyFrmAnchor)(SwFrmFmt &, SfxItemSet &, bool),
     392             :         SwFrmFmt & rFlyFmt, SfxItemSet & rSet)
     393             : {
     394             :     // #i32968# Inserting columns in the frame causes MakeFrmFmt to put two
     395             :     // objects of type SwUndoFrmFmt on the undo stack. We don't want them.
     396         572 :     ::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 sal_True
     400             :     // if the Fly needs to be created anew, because we e.g change the FlyType.
     401             :     sal_Int8 const nMakeFrms =
     402         572 :         (SfxItemState::SET == rSet.GetItemState( RES_ANCHOR, false ))
     403         522 :              ?  (rDoc.*pSetFlyFrmAnchor)( rFlyFmt, rSet, false )
     404        1094 :              :  DONTMAKEFRMS;
     405             : 
     406             :     const SfxPoolItem* pItem;
     407        1144 :     SfxItemIter aIter( rSet );
     408        1144 :     SfxItemSet aTmpSet( rDoc.GetAttrPool(), aFrmFmtSetRange );
     409         572 :     sal_uInt16 nWhich = aIter.GetCurItem()->Which();
     410         140 :     do {
     411         712 :         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         522 :             if( DONTMAKEFRMS != nMakeFrms )
     425         262 :                 break;
     426             : 
     427             :         default:
     428        1054 :             if( !IsInvalidItem( aIter.GetCurItem() ) && ( SfxItemState::SET !=
     429         840 :                 rFlyFmt.GetAttrSet().GetItemState( nWhich, true, &pItem ) ||
     430         390 :                 *pItem != *aIter.GetCurItem() ))
     431         154 :                 aTmpSet.Put( *aIter.GetCurItem() );
     432         450 :             break;
     433             :         }
     434             : 
     435         712 :         if( aIter.IsAtEnd() )
     436         572 :             break;
     437             : 
     438         140 :     } while( 0 != ( nWhich = aIter.NextItem()->Which() ) );
     439             : 
     440         572 :     if( aTmpSet.Count() )
     441          84 :         rFlyFmt.SetFmtAttr( aTmpSet );
     442             : 
     443         572 :     if( MAKEFRMS == nMakeFrms )
     444         262 :         rFlyFmt.MakeFrms();
     445             : 
     446        1144 :     return aTmpSet.Count() || MAKEFRMS == nMakeFrms;
     447             : }
     448             : 
     449      693788 : void SwDoc::CheckForUniqueItemForLineFillNameOrIndex(SfxItemSet& rSet)
     450             : {
     451      693788 :     SwDrawModel* pDrawModel = getIDocumentDrawModelAccess().GetOrCreateDrawModel();
     452      693788 :     SfxItemIter aIter(rSet);
     453             : 
     454     4136448 :     for(const SfxPoolItem* pItem = aIter.FirstItem(); pItem; pItem = aIter.NextItem())
     455             :     {
     456     3442660 :         if (IsInvalidItem(pItem))
     457           0 :             continue;
     458     3442660 :         const SfxPoolItem* pResult = NULL;
     459             : 
     460     3442660 :         switch(pItem->Which())
     461             :         {
     462             :             case XATTR_FILLBITMAP:
     463             :             {
     464          28 :                 pResult = static_cast< const XFillBitmapItem* >(pItem)->checkForUniqueItem(pDrawModel);
     465          28 :                 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          38 :                 pResult = static_cast< const XFillGradientItem* >(pItem)->checkForUniqueItem(pDrawModel);
     485          38 :                 break;
     486             :             }
     487             :             case XATTR_FILLFLOATTRANSPARENCE:
     488             :             {
     489           0 :                 pResult = static_cast< const XFillFloatTransparenceItem* >(pItem)->checkForUniqueItem(pDrawModel);
     490           0 :                 break;
     491             :             }
     492             :             case XATTR_FILLHATCH:
     493             :             {
     494           0 :                 pResult = static_cast< const XFillHatchItem* >(pItem)->checkForUniqueItem(pDrawModel);
     495           0 :                 break;
     496             :             }
     497             :         }
     498             : 
     499     3442660 :         if(pResult)
     500             :         {
     501          30 :             rSet.Put(*pResult);
     502          30 :             delete pResult;
     503             :         }
     504      693788 :     }
     505      693788 : }
     506             : 
     507         572 : bool SwDoc::SetFlyFrmAttr( SwFrmFmt& rFlyFmt, SfxItemSet& rSet )
     508             : {
     509         572 :     if( !rSet.Count() )
     510           0 :         return false;
     511             : 
     512         572 :     boost::scoped_ptr<SwUndoFmtAttrHelper> pSaveUndo;
     513             : 
     514         572 :     if (GetIDocumentUndoRedo().DoesUndo())
     515             :     {
     516          38 :         GetIDocumentUndoRedo().ClearRedo(); // AppendUndo far below, so leave it
     517          38 :         pSaveUndo.reset( new SwUndoFmtAttrHelper( rFlyFmt ) );
     518             :     }
     519             : 
     520         572 :     bool const bRet = lcl_SetFlyFrmAttr(*this, &SwDoc::SetFlyFrmAnchor, rFlyFmt, rSet);
     521             : 
     522         572 :     if ( pSaveUndo.get() )
     523             :     {
     524          38 :         if ( pSaveUndo->GetUndo() )
     525             :         {
     526          36 :             GetIDocumentUndoRedo().AppendUndo( pSaveUndo->ReleaseUndo() );
     527             :         }
     528             :     }
     529             : 
     530         572 :     getIDocumentState().SetModified();
     531             : 
     532         572 :     SwTextBoxHelper::syncFlyFrmAttr(rFlyFmt, rSet);
     533             : 
     534         572 :     return bRet;
     535             : }
     536             : 
     537             : // #i73249#
     538         448 : void SwDoc::SetFlyFrmTitle( SwFlyFrmFmt& rFlyFrmFmt,
     539             :                             const OUString& sNewTitle )
     540             : {
     541         448 :     if ( rFlyFrmFmt.GetObjTitle() == sNewTitle )
     542             :     {
     543         894 :         return;
     544             :     }
     545             : 
     546           2 :     ::sw::DrawUndoGuard const drawUndoGuard(GetIDocumentUndoRedo());
     547             : 
     548           2 :     if (GetIDocumentUndoRedo().DoesUndo())
     549             :     {
     550           0 :         GetIDocumentUndoRedo().AppendUndo( new SwUndoFlyStrAttr( rFlyFrmFmt,
     551             :                                           UNDO_FLYFRMFMT_TITLE,
     552             :                                           rFlyFrmFmt.GetObjTitle(),
     553           0 :                                           sNewTitle ) );
     554             :     }
     555             : 
     556           2 :     rFlyFrmFmt.SetObjTitle( sNewTitle, true );
     557             : 
     558           2 :     getIDocumentState().SetModified();
     559             : }
     560             : 
     561         460 : void SwDoc::SetFlyFrmDescription( SwFlyFrmFmt& rFlyFrmFmt,
     562             :                                   const OUString& sNewDescription )
     563             : {
     564         460 :     if ( rFlyFrmFmt.GetObjDescription() == sNewDescription )
     565             :     {
     566         764 :         return;
     567             :     }
     568             : 
     569         156 :     ::sw::DrawUndoGuard const drawUndoGuard(GetIDocumentUndoRedo());
     570             : 
     571         156 :     if (GetIDocumentUndoRedo().DoesUndo())
     572             :     {
     573           0 :         GetIDocumentUndoRedo().AppendUndo( new SwUndoFlyStrAttr( rFlyFrmFmt,
     574             :                                           UNDO_FLYFRMFMT_DESCRIPTION,
     575             :                                           rFlyFrmFmt.GetObjDescription(),
     576           0 :                                           sNewDescription ) );
     577             :     }
     578             : 
     579         156 :     rFlyFrmFmt.SetObjDescription( sNewDescription, true );
     580             : 
     581         156 :     getIDocumentState().SetModified();
     582             : }
     583             : 
     584          36 : bool SwDoc::SetFrmFmtToFly( SwFrmFmt& rFmt, SwFrmFmt& rNewFmt,
     585             :                             SfxItemSet* pSet, bool bKeepOrient )
     586             : {
     587          36 :     bool bChgAnchor = false, bFrmSz = false;
     588             : 
     589          36 :     const SwFmtFrmSize aFrmSz( rFmt.GetFrmSize() );
     590          72 :     const SwFmtVertOrient aVert( rFmt.GetVertOrient() );
     591          72 :     const SwFmtHoriOrient aHori( rFmt.GetHoriOrient() );
     592             : 
     593          36 :     SwUndoSetFlyFmt* pUndo = 0;
     594          36 :     bool const bUndo = GetIDocumentUndoRedo().DoesUndo();
     595          36 :     if (bUndo)
     596             :     {
     597          16 :         pUndo = new SwUndoSetFlyFmt( rFmt, rNewFmt );
     598          16 :         GetIDocumentUndoRedo().AppendUndo(pUndo);
     599             :     }
     600             : 
     601             :     // #i32968# Inserting columns in the section causes MakeFrmFmt to put
     602             :     // 2 objects of type SwUndoFrmFmt on the undo stack. We don't want them.
     603          72 :     ::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          36 :     if( SfxItemState::SET != rNewFmt.GetAttrSet().GetItemState( RES_COL ))
     609          36 :         rFmt.ResetFmtAttr( RES_COL );
     610             : 
     611          36 :     if( rFmt.DerivedFrom() != &rNewFmt )
     612             :     {
     613          18 :         rFmt.SetDerivedFrom( &rNewFmt );
     614             : 
     615             :         // 1. If not automatic = ignore; else = dispose
     616             :         // 2. Dispose of it!
     617          18 :         if( SfxItemState::SET == rNewFmt.GetAttrSet().GetItemState( RES_FRM_SIZE, false ))
     618             :         {
     619           0 :             rFmt.ResetFmtAttr( RES_FRM_SIZE );
     620           0 :             bFrmSz = true;
     621             :         }
     622             : 
     623          18 :         const SfxItemSet* pAsk = pSet;
     624          18 :         if( !pAsk ) pAsk = &rNewFmt.GetAttrSet();
     625          36 :         if( SfxItemState::SET == pAsk->GetItemState( RES_ANCHOR, false, &pItem )
     626          26 :             && ((SwFmtAnchor*)pItem)->GetAnchorId() !=
     627           8 :                 rFmt.GetAnchor().GetAnchorId() )
     628             :         {
     629           6 :             if( pSet )
     630           4 :                 bChgAnchor = MAKEFRMS == SetFlyFrmAnchor( rFmt, *pSet, false );
     631             :             else
     632             :             {
     633             :                 // Needs to have the FlyFmt range, because we set attributes in it,
     634             :                 // in SetFlyFrmAnchor.
     635           2 :                 SfxItemSet aFlySet( *rNewFmt.GetAttrSet().GetPool(),
     636           4 :                                     rNewFmt.GetAttrSet().GetRanges() );
     637           2 :                 aFlySet.Put( *pItem );
     638           2 :                 bChgAnchor = MAKEFRMS == SetFlyFrmAnchor( rFmt, 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          36 :     if (!bKeepOrient)
     649             :     {
     650          36 :         rFmt.ResetFmtAttr(RES_VERT_ORIENT);
     651          36 :         rFmt.ResetFmtAttr(RES_HORI_ORIENT);
     652             :     }
     653             : 
     654          36 :     rFmt.ResetFmtAttr( RES_PRINT, RES_SURROUND );
     655          36 :     rFmt.ResetFmtAttr( RES_LR_SPACE, RES_UL_SPACE );
     656          36 :     rFmt.ResetFmtAttr( RES_BACKGROUND, RES_COL );
     657          36 :     rFmt.ResetFmtAttr( RES_URL, RES_EDIT_IN_READONLY );
     658             : 
     659          36 :     if( !bFrmSz )
     660          36 :         rFmt.SetFmtAttr( aFrmSz );
     661             : 
     662          36 :     if( bChgAnchor )
     663           4 :         rFmt.MakeFrms();
     664             : 
     665          36 :     if( pUndo )
     666          16 :         pUndo->DeRegisterFromFormat( rFmt );
     667             : 
     668          36 :     getIDocumentState().SetModified();
     669             : 
     670          72 :     return bChgAnchor;
     671             : }
     672             : 
     673          22 : void SwDoc::GetGrfNms( const SwFlyFrmFmt& rFmt, OUString* pGrfName,
     674             :                        OUString* pFltName ) const
     675             : {
     676          22 :     SwNodeIndex aIdx( *rFmt.GetCntnt().GetCntntIdx(), 1 );
     677          22 :     const SwGrfNode* pGrfNd = aIdx.GetNode().GetGrfNode();
     678          22 :     if( pGrfNd && pGrfNd->IsLinkedFile() )
     679          12 :         pGrfNd->GetFileFilterNms( pGrfName, pFltName );
     680          22 : }
     681             : 
     682           0 : 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           0 :     if ( !_rMrkList.GetMarkCount() ||
     690           0 :          _rMrkList.GetMark( 0 )->GetMarkedSdrObj()->GetUpGroup() )
     691             :     {
     692           0 :         return false;
     693             :     }
     694             : 
     695           0 :     GetIDocumentUndoRedo().StartUndo( UNDO_INSATTR, NULL );
     696             : 
     697           0 :     bool bUnmark = false;
     698           0 :     for ( size_t i = 0; i < _rMrkList.GetMarkCount(); ++i )
     699             :     {
     700           0 :         SdrObject* pObj = _rMrkList.GetMark( i )->GetMarkedSdrObj();
     701           0 :         if ( !pObj->ISA(SwVirtFlyDrawObj) )
     702             :         {
     703           0 :             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           0 :             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           0 :             const SwFrm* pOldAnchorFrm = pContact->GetAnchorFrm( pObj );
     722           0 :             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           0 :             boost::scoped_ptr<const SwPosition> xOldAsCharAnchorPos;
     730           0 :             const RndStdIds eOldAnchorType = pContact->GetAnchorId();
     731           0 :             if ( !_bSameOnly && eOldAnchorType == FLY_AS_CHAR )
     732             :             {
     733           0 :                 xOldAsCharAnchorPos.reset(new SwPosition(pContact->GetCntntAnchor()));
     734             :             }
     735             : 
     736           0 :             if ( _bSameOnly )
     737           0 :                 _eAnchorType = eOldAnchorType;
     738             : 
     739           0 :             SwFmtAnchor aNewAnch( _eAnchorType );
     740           0 :             Rectangle aObjRect( pContact->GetAnchoredObj( pObj )->GetObjRect().SVRect() );
     741           0 :             const Point aPt( aObjRect.TopLeft() );
     742             : 
     743           0 :             switch ( _eAnchorType )
     744             :             {
     745             :             case FLY_AT_PARA:
     746             :             case FLY_AT_CHAR:
     747             :                 {
     748           0 :                     const Point aNewPoint = ( pOldAnchorFrm->IsVertical() ||
     749           0 :                                               pOldAnchorFrm->IsRightToLeft() )
     750             :                                             ? aObjRect.TopRight()
     751           0 :                                             : aPt;
     752             : 
     753             :                     // allow drawing objects in header/footer
     754           0 :                     pNewAnchorFrm = ::FindAnchor( pOldAnchorFrm, aNewPoint, false );
     755           0 :                     if ( pNewAnchorFrm->IsTxtFrm() && ((SwTxtFrm*)pNewAnchorFrm)->IsFollow() )
     756             :                     {
     757           0 :                         pNewAnchorFrm = ((SwTxtFrm*)pNewAnchorFrm)->FindMaster();
     758             :                     }
     759           0 :                     if ( pNewAnchorFrm->IsProtected() )
     760             :                     {
     761           0 :                         pNewAnchorFrm = 0;
     762             :                     }
     763             :                     else
     764             :                     {
     765           0 :                         SwPosition aPos( *((SwCntntFrm*)pNewAnchorFrm)->GetNode() );
     766           0 :                         aNewAnch.SetType( _eAnchorType );
     767           0 :                         aNewAnch.SetAnchor( &aPos );
     768             :                     }
     769             :                 }
     770           0 :                 break;
     771             : 
     772             :             case FLY_AT_FLY: // LAYER_IMPL
     773             :                 {
     774             :                     // Search the closest SwFlyFrm starting from the upper left corner.
     775             :                     SwFrm *pTxtFrm;
     776             :                     {
     777           0 :                         SwCrsrMoveState aState( MV_SETONLYTEXT );
     778           0 :                         SwPosition aPos( GetNodes() );
     779           0 :                         Point aPoint( aPt );
     780           0 :                         aPoint.setX(aPoint.getX() - 1);
     781           0 :                         getIDocumentLayoutAccess().GetCurrentLayout()->GetCrsrOfst( &aPos, aPoint, &aState );
     782             :                         // consider that drawing objects can be in
     783             :                         // header/footer. Thus, <GetFrm()> by left-top-corner
     784           0 :                         pTxtFrm = aPos.nNode.GetNode().
     785           0 :                                         GetCntntNode()->getLayoutFrm( getIDocumentLayoutAccess().GetCurrentLayout(), &aPt, 0, false );
     786             :                     }
     787           0 :                     const SwFrm *pTmp = ::FindAnchor( pTxtFrm, aPt );
     788           0 :                     pNewAnchorFrm = pTmp->FindFlyFrm();
     789           0 :                     if( pNewAnchorFrm && !pNewAnchorFrm->IsProtected() )
     790             :                     {
     791           0 :                         const SwFrmFmt *pTmpFmt = ((SwFlyFrm*)pNewAnchorFrm)->GetFmt();
     792           0 :                         const SwFmtCntnt& rCntnt = pTmpFmt->GetCntnt();
     793           0 :                         SwPosition aPos( *rCntnt.GetCntntIdx() );
     794           0 :                         aNewAnch.SetAnchor( &aPos );
     795           0 :                         break;
     796             :                     }
     797             : 
     798           0 :                     aNewAnch.SetType( FLY_AT_PAGE );
     799             :                     // no break
     800             :                 }
     801             :             case FLY_AT_PAGE:
     802             :                 {
     803           0 :                     pNewAnchorFrm = getIDocumentLayoutAccess().GetCurrentLayout()->Lower();
     804           0 :                     while ( pNewAnchorFrm && !pNewAnchorFrm->Frm().IsInside( aPt ) )
     805           0 :                         pNewAnchorFrm = pNewAnchorFrm->GetNext();
     806           0 :                     if ( !pNewAnchorFrm )
     807           0 :                         continue;
     808             : 
     809           0 :                     aNewAnch.SetPageNum( ((SwPageFrm*)pNewAnchorFrm)->GetPhyPageNum());
     810             :                 }
     811           0 :                 break;
     812             :             case FLY_AS_CHAR:
     813           0 :                 if( _bSameOnly )    // Change of position/size
     814             :                 {
     815           0 :                     if( !pOldAnchorFrm )
     816             :                     {
     817           0 :                         pContact->ConnectToLayout();
     818           0 :                         pOldAnchorFrm = pContact->GetAnchorFrm();
     819             :                     }
     820           0 :                     ((SwTxtFrm*)pOldAnchorFrm)->Prepare();
     821             :                 }
     822             :                 else            // Change of anchors
     823             :                 {
     824             :                     // allow drawing objects in header/footer
     825           0 :                     pNewAnchorFrm = ::FindAnchor( pOldAnchorFrm, aPt, false );
     826           0 :                     if( pNewAnchorFrm->IsProtected() )
     827             :                     {
     828           0 :                         pNewAnchorFrm = 0;
     829           0 :                         break;
     830             :                     }
     831             : 
     832           0 :                     bUnmark = ( 0 != i );
     833           0 :                     Point aPoint( aPt );
     834           0 :                     aPoint.setX(aPoint.getX() - 1);    // Do not load in the DrawObj!
     835           0 :                     aNewAnch.SetType( FLY_AS_CHAR );
     836           0 :                     SwPosition aPos( *((SwCntntFrm*)pNewAnchorFrm)->GetNode() );
     837           0 :                     if ( pNewAnchorFrm->Frm().IsInside( aPoint ) )
     838             :                     {
     839             :                     // We need to find a TextNode, because only there we can anchor a
     840             :                     // content-bound DrawObject.
     841           0 :                         SwCrsrMoveState aState( MV_SETONLYTEXT );
     842           0 :                         getIDocumentLayoutAccess().GetCurrentLayout()->GetCrsrOfst( &aPos, aPoint, &aState );
     843             :                     }
     844             :                     else
     845             :                     {
     846             :                         SwCntntNode &rCNd = (SwCntntNode&)
     847           0 :                             *((SwCntntFrm*)pNewAnchorFrm)->GetNode();
     848           0 :                         if ( pNewAnchorFrm->Frm().Bottom() < aPt.Y() )
     849           0 :                             rCNd.MakeStartIndex( &aPos.nContent );
     850             :                         else
     851           0 :                             rCNd.MakeEndIndex( &aPos.nContent );
     852             :                     }
     853           0 :                     aNewAnch.SetAnchor( &aPos );
     854           0 :                     SetAttr( aNewAnch, *pContact->GetFmt() );
     855             :                     // #i26791# - adjust vertical positioning to 'center to
     856             :                     // baseline'
     857           0 :                     SetAttr( SwFmtVertOrient( 0, text::VertOrientation::CENTER, text::RelOrientation::FRAME ), *pContact->GetFmt() );
     858           0 :                     SwTxtNode *pNd = aPos.nNode.GetNode().GetTxtNode();
     859             :                     OSL_ENSURE( pNd, "Cursor not positioned at TxtNode." );
     860             : 
     861           0 :                     SwFmtFlyCnt aFmt( pContact->GetFmt() );
     862           0 :                     pNd->InsertItem( aFmt, aPos.nContent.GetIndex(), 0 );
     863             :                 }
     864           0 :                 break;
     865             :             default:
     866             :                 OSL_ENSURE( false, "unexpected AnchorId." );
     867             :             }
     868             : 
     869           0 :             if ( (FLY_AS_CHAR != _eAnchorType) &&
     870           0 :                  pNewAnchorFrm &&
     871           0 :                  ( !_bSameOnly || pNewAnchorFrm != pOldAnchorFrm ) )
     872             :             {
     873             :                 // #i26791# - Direct object positioning no longer needed. Apply
     874             :                 // of attributes (method call <SetAttr(..)>) takes care of the
     875             :                 // invalidation of the object position.
     876           0 :                 SetAttr( aNewAnch, *pContact->GetFmt() );
     877           0 :                 if ( _bPosCorr )
     878             :                 {
     879             :                     // #i33313# - consider not connected 'virtual' drawing
     880             :                     // objects
     881           0 :                     if ( pObj->ISA(SwDrawVirtObj) &&
     882           0 :                          !static_cast<SwDrawVirtObj*>(pObj)->IsConnected() )
     883             :                     {
     884           0 :                         SwRect aNewObjRect( aObjRect );
     885           0 :                         static_cast<SwAnchoredDrawObject*>(pContact->GetAnchoredObj( 0L ))
     886             :                                         ->AdjustPositioningAttr( pNewAnchorFrm,
     887           0 :                                                                  &aNewObjRect );
     888             :                     }
     889             :                     else
     890             :                     {
     891           0 :                         static_cast<SwAnchoredDrawObject*>(pContact->GetAnchoredObj( pObj ))
     892           0 :                                     ->AdjustPositioningAttr( pNewAnchorFrm );
     893             :                     }
     894             :                 }
     895             :             }
     896             : 
     897             :             // #i54336#
     898           0 :             if (xOldAsCharAnchorPos)
     899             :             {
     900           0 :                 if ( pNewAnchorFrm)
     901             :                 {
     902             :                     // We need to handle InCntnts in a special way:
     903             :                     // The TxtAttribut needs to be destroyed which, unfortunately, also
     904             :                     // destroys the format. To avoid that, we disconnect the format from
     905             :                     // the attribute.
     906           0 :                     const sal_Int32 nIndx( xOldAsCharAnchorPos->nContent.GetIndex() );
     907           0 :                     SwTxtNode* pTxtNode( xOldAsCharAnchorPos->nNode.GetNode().GetTxtNode() );
     908             :                     OSL_ENSURE( pTxtNode, "<SwDoc::ChgAnchor(..)> - missing previous anchor text node for as-character anchored object" );
     909             :                     OSL_ENSURE( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." );
     910             :                     SwTxtAttr * const pHnt =
     911           0 :                         pTxtNode->GetTxtAttrForCharAt( nIndx, RES_TXTATR_FLYCNT );
     912           0 :                     const_cast<SwFmtFlyCnt&>(pHnt->GetFlyCnt()).SetFlyFmt();
     913             : 
     914             :                     // They are disconnected. We now have to destroy the attribute.
     915           0 :                     pTxtNode->DeleteAttributes( RES_TXTATR_FLYCNT, nIndx, nIndx );
     916             :                 }
     917           0 :             }
     918             :         }
     919             :     }
     920             : 
     921           0 :     GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
     922           0 :     getIDocumentState().SetModified();
     923             : 
     924           0 :     return bUnmark;
     925             : }
     926             : 
     927          26 : int SwDoc::Chainable( const SwFrmFmt &rSource, const SwFrmFmt &rDest )
     928             : {
     929             :     // The Source must not yet have a Follow.
     930          26 :     const SwFmtChain &rOldChain = rSource.GetChain();
     931          26 :     if ( rOldChain.GetNext() )
     932          18 :         return SW_CHAIN_SOURCE_CHAINED;
     933             : 
     934             :     // Target must not be equal to Source and we also must not have a closed chain.
     935           8 :     const SwFrmFmt *pFmt = &rDest;
     936           8 :     do {
     937           8 :         if( pFmt == &rSource )
     938           0 :             return SW_CHAIN_SELF;
     939           8 :         pFmt = pFmt->GetChain().GetNext();
     940             :     } while ( pFmt );
     941             : 
     942             :     // There must not be a chaining from outside to inside or the other way around.
     943           8 :     if( rDest.IsLowerOf( rSource ) || rSource .IsLowerOf( rDest ) )
     944           0 :         return SW_CHAIN_SELF;
     945             : 
     946             :     // The Target must not yet have a Master.
     947           8 :     const SwFmtChain &rChain = rDest.GetChain();
     948           8 :     if( rChain.GetPrev() )
     949           0 :         return SW_CHAIN_IS_IN_CHAIN;
     950             : 
     951             :     // Target must be empty.
     952           8 :     const SwNodeIndex* pCntIdx = rDest.GetCntnt().GetCntntIdx();
     953           8 :     if( !pCntIdx )
     954           0 :         return SW_CHAIN_NOT_FOUND;
     955             : 
     956           8 :     SwNodeIndex aNxtIdx( *pCntIdx, 1 );
     957           8 :     const SwTxtNode* pTxtNd = aNxtIdx.GetNode().GetTxtNode();
     958           8 :     if( !pTxtNd )
     959           0 :         return SW_CHAIN_NOT_FOUND;
     960             : 
     961           8 :     const sal_uLong nFlySttNd = pCntIdx->GetIndex();
     962          16 :     if( 2 != ( pCntIdx->GetNode().EndOfSectionIndex() - nFlySttNd ) ||
     963           8 :         pTxtNd->GetTxt().getLength() )
     964             :     {
     965           0 :         return SW_CHAIN_NOT_EMPTY;
     966             :     }
     967             : 
     968           8 :     sal_uInt16 nArrLen = GetSpzFrmFmts()->size();
     969          68 :     for( sal_uInt16 n = 0; n < nArrLen; ++n )
     970             :     {
     971          60 :         const SwFmtAnchor& rAnchor = (*GetSpzFrmFmts())[ n ]->GetAnchor();
     972             :         sal_uLong nTstSttNd;
     973             :         // #i20622# - to-frame anchored objects are allowed.
     974         120 :         if ( ((rAnchor.GetAnchorId() == FLY_AT_PARA) ||
     975          60 :               (rAnchor.GetAnchorId() == FLY_AT_CHAR)) &&
     976         120 :              0 != rAnchor.GetCntntAnchor() &&
     977             :              nFlySttNd <= ( nTstSttNd =
     978         180 :                          rAnchor.GetCntntAnchor()->nNode.GetIndex() ) &&
     979          60 :              nTstSttNd < nFlySttNd + 2 )
     980             :         {
     981           0 :             return SW_CHAIN_NOT_EMPTY;
     982             :         }
     983             :     }
     984             : 
     985             :     // We also need to consider the right area.
     986             :     // Both Flys need to be located in the same area (Body, Header/Footer, Fly).
     987             :     // If the Source is not the selected frame, it's enough to find a suitable
     988             :     // one. e.g. if it's requested by the API.
     989             : 
     990             :     // both in the same fly, header, footer or on the page?
     991           8 :     const SwFmtAnchor &rSrcAnchor = rSource.GetAnchor(),
     992           8 :                       &rDstAnchor = rDest.GetAnchor();
     993           8 :     sal_uLong nEndOfExtras = GetNodes().GetEndOfExtras().GetIndex();
     994           8 :     bool bAllowed = false;
     995           8 :     if ( FLY_AT_PAGE == rSrcAnchor.GetAnchorId() )
     996             :     {
     997           0 :         if ( (FLY_AT_PAGE == rDstAnchor.GetAnchorId()) ||
     998           0 :             ( rDstAnchor.GetCntntAnchor() &&
     999           0 :               rDstAnchor.GetCntntAnchor()->nNode.GetIndex() > nEndOfExtras ))
    1000           0 :             bAllowed = true;
    1001             :     }
    1002           8 :     else if( rSrcAnchor.GetCntntAnchor() && rDstAnchor.GetCntntAnchor() )
    1003             :     {
    1004           8 :         const SwNodeIndex &rSrcIdx = rSrcAnchor.GetCntntAnchor()->nNode,
    1005           8 :                             &rDstIdx = rDstAnchor.GetCntntAnchor()->nNode;
    1006           8 :         const SwStartNode* pSttNd = 0;
    1007          18 :         if( rSrcIdx == rDstIdx ||
    1008           2 :             ( !pSttNd &&
    1009           2 :                 0 != ( pSttNd = rSrcIdx.GetNode().FindFlyStartNode() ) &&
    1010           2 :                 pSttNd == rDstIdx.GetNode().FindFlyStartNode() ) ||
    1011           2 :             ( !pSttNd &&
    1012           2 :                 0 != ( pSttNd = rSrcIdx.GetNode().FindFooterStartNode() ) &&
    1013           2 :                 pSttNd == rDstIdx.GetNode().FindFooterStartNode() ) ||
    1014           2 :             ( !pSttNd &&
    1015           2 :                 0 != ( pSttNd = rSrcIdx.GetNode().FindHeaderStartNode() ) &&
    1016          18 :                 pSttNd == rDstIdx.GetNode().FindHeaderStartNode() ) ||
    1017           4 :             ( !pSttNd && rDstIdx.GetIndex() > nEndOfExtras &&
    1018           2 :                             rSrcIdx.GetIndex() > nEndOfExtras ))
    1019           8 :             bAllowed = true;
    1020             :     }
    1021             : 
    1022           8 :     return bAllowed ? SW_CHAIN_OK : SW_CHAIN_WRONG_AREA;
    1023             : }
    1024             : 
    1025          26 : int SwDoc::Chain( SwFrmFmt &rSource, const SwFrmFmt &rDest )
    1026             : {
    1027          26 :     int nErr = Chainable( rSource, rDest );
    1028          26 :     if ( !nErr )
    1029             :     {
    1030           8 :         GetIDocumentUndoRedo().StartUndo( UNDO_CHAINE, NULL );
    1031             : 
    1032           8 :         SwFlyFrmFmt& rDestFmt = (SwFlyFrmFmt&)rDest;
    1033             : 
    1034             :         // Attach Follow to the Master.
    1035           8 :         SwFmtChain aChain = rDestFmt.GetChain();
    1036           8 :         aChain.SetPrev( &(SwFlyFrmFmt&)rSource );
    1037           8 :         SetAttr( aChain, rDestFmt );
    1038             : 
    1039           8 :         SfxItemSet aSet( GetAttrPool(), RES_FRM_SIZE, RES_FRM_SIZE,
    1040          16 :                                         RES_CHAIN,  RES_CHAIN, 0 );
    1041             : 
    1042             :         // Attach Follow to the Master.
    1043           8 :         aChain.SetPrev( &(SwFlyFrmFmt&)rSource );
    1044           8 :         SetAttr( aChain, rDestFmt );
    1045             : 
    1046             :         // Attach Master to the Follow.
    1047             :         // Make sure that the Master has a fixed height.
    1048           8 :         aChain = rSource.GetChain();
    1049           8 :         aChain.SetNext( &rDestFmt );
    1050           8 :         aSet.Put( aChain );
    1051             : 
    1052          16 :         SwFmtFrmSize aSize( rSource.GetFrmSize() );
    1053           8 :         if ( aSize.GetHeightSizeType() != ATT_FIX_SIZE )
    1054             :         {
    1055           0 :             SwFlyFrm *pFly = SwIterator<SwFlyFrm,SwFmt>::FirstElement( rSource );
    1056           0 :             if ( pFly )
    1057           0 :                 aSize.SetHeight( pFly->Frm().Height() );
    1058           0 :             aSize.SetHeightSizeType( ATT_FIX_SIZE );
    1059           0 :             aSet.Put( aSize );
    1060             :         }
    1061           8 :         SetAttr( aSet, rSource );
    1062             : 
    1063          16 :         GetIDocumentUndoRedo().EndUndo( UNDO_CHAINE, NULL );
    1064             :     }
    1065          26 :     return nErr;
    1066             : }
    1067             : 
    1068           0 : void SwDoc::Unchain( SwFrmFmt &rFmt )
    1069             : {
    1070           0 :     SwFmtChain aChain( rFmt.GetChain() );
    1071           0 :     if ( aChain.GetNext() )
    1072             :     {
    1073           0 :         GetIDocumentUndoRedo().StartUndo( UNDO_UNCHAIN, NULL );
    1074           0 :         SwFrmFmt *pFollow = aChain.GetNext();
    1075           0 :         aChain.SetNext( 0 );
    1076           0 :         SetAttr( aChain, rFmt );
    1077           0 :         aChain = pFollow->GetChain();
    1078           0 :         aChain.SetPrev( 0 );
    1079           0 :         SetAttr( aChain, *pFollow );
    1080           0 :         GetIDocumentUndoRedo().EndUndo( UNDO_UNCHAIN, NULL );
    1081           0 :     }
    1082         270 : }
    1083             : 
    1084             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10