LCOV - code coverage report
Current view: top level - sw/source/core/layout - flycnt.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 311 712 43.7 %
Date: 2014-04-11 Functions: 23 26 88.5 %
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 <tools/bigint.hxx>
      21             : #include "pagefrm.hxx"
      22             : #include "txtfrm.hxx"
      23             : #include <doc.hxx>
      24             : #include <IDocumentUndoRedo.hxx>
      25             : #include "frmtool.hxx"
      26             : #include "dflyobj.hxx"
      27             : #include "hints.hxx"
      28             : #include <fmtornt.hxx>
      29             : #include <fmtfsize.hxx>
      30             : #include <fmtsrnd.hxx>
      31             : #include <txatbase.hxx>
      32             : 
      33             : #include "tabfrm.hxx"
      34             : #include "flyfrms.hxx"
      35             : #include "crstate.hxx"
      36             : #include "sectfrm.hxx"
      37             : 
      38             : #include <tocntntanchoredobjectposition.hxx>
      39             : #include <dcontact.hxx>
      40             : #include <sortedobjs.hxx>
      41             : #include <layouter.hxx>
      42             : #include <objectformattertxtfrm.hxx>
      43             : #include <HandleAnchorNodeChg.hxx>
      44             : 
      45             : using namespace ::com::sun::star;
      46             : 
      47         649 : SwFlyAtCntFrm::SwFlyAtCntFrm( SwFlyFrmFmt *pFmt, SwFrm* pSib, SwFrm *pAnch ) :
      48         649 :     SwFlyFreeFrm( pFmt, pSib, pAnch )
      49             : {
      50         649 :     bAtCnt = sal_True;
      51         649 :     bAutoPosition = (FLY_AT_CHAR == pFmt->GetAnchor().GetAnchorId());
      52         649 : }
      53             : 
      54             : // #i28701#
      55      327483 : TYPEINIT1(SwFlyAtCntFrm,SwFlyFreeFrm);
      56             : 
      57          90 : void SwFlyAtCntFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
      58             : {
      59          90 :     sal_uInt16 nWhich = pNew ? pNew->Which() : 0;
      60          90 :     const SwFmtAnchor *pAnch = 0;
      61             : 
      62         130 :     if( RES_ATTRSET_CHG == nWhich && SFX_ITEM_SET ==
      63          40 :         ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( RES_ANCHOR, false,
      64          40 :             (const SfxPoolItem**)&pAnch ))
      65             :         ;       // The anchor pointer is set at GetItemState!
      66             : 
      67          90 :     else if( RES_ANCHOR == nWhich )
      68             :     {
      69             :         //Change anchor, I move myself to a new place.
      70             :         //The anchor type must not change, this is only possible using
      71             :         //SwFEShell.
      72           0 :         pAnch = (const SwFmtAnchor*)pNew;
      73             :     }
      74             : 
      75          90 :     if( pAnch )
      76             :     {
      77             :         OSL_ENSURE( pAnch->GetAnchorId() == GetFmt()->GetAnchor().GetAnchorId(),
      78             :                 "Illegal change of anchor type. " );
      79             : 
      80             :         //Unregister, get hold of a new anchor and attach it
      81           0 :         SwRect aOld( GetObjRectWithSpaces() );
      82           0 :         SwPageFrm *pOldPage = FindPageFrm();
      83           0 :         const SwFrm *pOldAnchor = GetAnchorFrm();
      84           0 :         SwCntntFrm *pCntnt = (SwCntntFrm*)GetAnchorFrm();
      85           0 :         AnchorFrm()->RemoveFly( this );
      86             : 
      87           0 :         const bool bBodyFtn = (pCntnt->IsInDocBody() || pCntnt->IsInFtn());
      88             : 
      89             :         // Search the new anchor using the NodeIdx; the relation between old
      90             :         // and new NodeIdx determines the search direction
      91           0 :         const SwNodeIndex aNewIdx( pAnch->GetCntntAnchor()->nNode );
      92           0 :         SwNodeIndex aOldIdx( *pCntnt->GetNode() );
      93             : 
      94             :         //fix: depending on which index was smaller, searching in the do-while
      95             :         //loop previously was done forward or backwards respectively. This however
      96             :         //could lead to an infinite loop. To at least avoid the loop, searching
      97             :         //is now done in only one direction. Getting hold of a frame from the node
      98             :         //is still possible if the new anchor could not be found. Chances are
      99             :         //good that this will be the correct one.
     100           0 :         const bool bNext = aOldIdx < aNewIdx;
     101             :         // consider the case that at found anchor frame candidate already a
     102             :         // fly frame of the given fly format is registered.
     103             :         // consider, that <pCntnt> is the already
     104             :         // the new anchor frame.
     105           0 :         bool bFound( aOldIdx == aNewIdx );
     106           0 :         while ( pCntnt && !bFound )
     107             :         {
     108           0 :             do
     109             :             {
     110           0 :                 if ( bNext )
     111           0 :                     pCntnt = pCntnt->GetNextCntntFrm();
     112             :                 else
     113           0 :                     pCntnt = pCntnt->GetPrevCntntFrm();
     114           0 :             } while ( pCntnt &&
     115           0 :                       !( bBodyFtn == ( pCntnt->IsInDocBody() ||
     116           0 :                                        pCntnt->IsInFtn() ) ) );
     117           0 :             if ( pCntnt )
     118           0 :                 aOldIdx = *pCntnt->GetNode();
     119             : 
     120             :             // check, if at found anchor frame candidate already a fly frame
     121             :             // of the given fly frame format is registered.
     122           0 :             bFound = aOldIdx == aNewIdx;
     123           0 :             if ( bFound && pCntnt->GetDrawObjs() )
     124             :             {
     125           0 :                 SwFrmFmt* pMyFlyFrmFmt( &GetFrmFmt() );
     126           0 :                 SwSortedObjs &rObjs = *pCntnt->GetDrawObjs();
     127           0 :                 for( sal_uInt16 i = 0; i < rObjs.Count(); ++i)
     128             :                 {
     129           0 :                     SwFlyFrm* pFlyFrm = dynamic_cast<SwFlyFrm*>(rObjs[i]);
     130           0 :                     if ( pFlyFrm &&
     131           0 :                          &(pFlyFrm->GetFrmFmt()) == pMyFlyFrmFmt )
     132             :                     {
     133           0 :                         bFound = false;
     134           0 :                         break;
     135             :                     }
     136             :                 }
     137             :             }
     138             :         }
     139           0 :         if ( !pCntnt )
     140             :         {
     141           0 :             SwCntntNode *pNode = aNewIdx.GetNode().GetCntntNode();
     142           0 :             pCntnt = pNode->getLayoutFrm( getRootFrm(), &pOldAnchor->Frm().Pos(), 0, false );
     143             :             OSL_ENSURE( pCntnt, "Neuen Anker nicht gefunden" );
     144             :         }
     145             :         //Flys are never attached to a follow, but always on the master which
     146             :         //we are going to search now.
     147           0 :         SwCntntFrm* pFlow = pCntnt;
     148           0 :         while ( pFlow->IsFollow() )
     149           0 :             pFlow = pFlow->FindMaster();
     150           0 :         pCntnt = pFlow;
     151             : 
     152             :         //and *puff* it's attached...
     153           0 :         pCntnt->AppendFly( this );
     154           0 :         if ( pOldPage && pOldPage != FindPageFrm() )
     155           0 :             NotifyBackground( pOldPage, aOld, PREP_FLY_LEAVE );
     156             : 
     157             :         //Fix(3495)
     158           0 :         _InvalidatePos();
     159           0 :         InvalidatePage();
     160           0 :         SetNotifyBack();
     161             :         // #i28701# - reset member <maLastCharRect> and
     162             :         // <mnLastTopOfLine> for to-character anchored objects.
     163           0 :         ClearCharRectAndTopOfLine();
     164             :     }
     165             :     else
     166          90 :         SwFlyFrm::Modify( pOld, pNew );
     167          90 : }
     168             : 
     169             : //We need some helper classes to monitor the oscillation and a few functions
     170             : //to not get lost.
     171             : 
     172             : // #i3317# - re-factoring of the position stack
     173             : class SwOszControl
     174             : {
     175             :     static const SwFlyFrm *pStk1;
     176             :     static const SwFlyFrm *pStk2;
     177             :     static const SwFlyFrm *pStk3;
     178             :     static const SwFlyFrm *pStk4;
     179             :     static const SwFlyFrm *pStk5;
     180             : 
     181             :     const SwFlyFrm *pFly;
     182             :     // #i3317#
     183             :     sal_uInt8 mnPosStackSize;
     184             :     std::vector<Point*> maObjPositions;
     185             : 
     186             : public:
     187             :     SwOszControl( const SwFlyFrm *pFrm );
     188             :     ~SwOszControl();
     189             :     bool ChkOsz();
     190             :     static bool IsInProgress( const SwFlyFrm *pFly );
     191             : };
     192             : 
     193             : const SwFlyFrm *SwOszControl::pStk1 = 0;
     194             : const SwFlyFrm *SwOszControl::pStk2 = 0;
     195             : const SwFlyFrm *SwOszControl::pStk3 = 0;
     196             : const SwFlyFrm *SwOszControl::pStk4 = 0;
     197             : const SwFlyFrm *SwOszControl::pStk5 = 0;
     198             : 
     199        1456 : SwOszControl::SwOszControl( const SwFlyFrm *pFrm )
     200             :     : pFly( pFrm ),
     201             :       // #i3317#
     202        1456 :       mnPosStackSize( 20 )
     203             : {
     204        1456 :     if ( !SwOszControl::pStk1 )
     205        1456 :         SwOszControl::pStk1 = pFly;
     206           0 :     else if ( !SwOszControl::pStk2 )
     207           0 :         SwOszControl::pStk2 = pFly;
     208           0 :     else if ( !SwOszControl::pStk3 )
     209           0 :         SwOszControl::pStk3 = pFly;
     210           0 :     else if ( !SwOszControl::pStk4 )
     211           0 :         SwOszControl::pStk4 = pFly;
     212           0 :     else if ( !SwOszControl::pStk5 )
     213           0 :         SwOszControl::pStk5 = pFly;
     214        1456 : }
     215             : 
     216        2912 : SwOszControl::~SwOszControl()
     217             : {
     218        1456 :     if ( SwOszControl::pStk1 == pFly )
     219        1456 :         SwOszControl::pStk1 = 0;
     220           0 :     else if ( SwOszControl::pStk2 == pFly )
     221           0 :         SwOszControl::pStk2 = 0;
     222           0 :     else if ( SwOszControl::pStk3 == pFly )
     223           0 :         SwOszControl::pStk3 = 0;
     224           0 :     else if ( SwOszControl::pStk4 == pFly )
     225           0 :         SwOszControl::pStk4 = 0;
     226           0 :     else if ( SwOszControl::pStk5 == pFly )
     227           0 :         SwOszControl::pStk5 = 0;
     228             :     // #i3317#
     229        3692 :     while ( !maObjPositions.empty() )
     230             :     {
     231         780 :         Point* pPos = maObjPositions.back();
     232         780 :         delete pPos;
     233             : 
     234         780 :         maObjPositions.pop_back();
     235             :     }
     236        1456 : }
     237             : 
     238        5480 : bool SwOszControl::IsInProgress( const SwFlyFrm *pFly )
     239             : {
     240        5480 :     if ( SwOszControl::pStk1 && !pFly->IsLowerOf( SwOszControl::pStk1 ) )
     241           0 :         return true;
     242        5480 :     if ( SwOszControl::pStk2 && !pFly->IsLowerOf( SwOszControl::pStk2 ) )
     243           0 :         return true;
     244        5480 :     if ( SwOszControl::pStk3 && !pFly->IsLowerOf( SwOszControl::pStk3 ) )
     245           0 :         return true;
     246        5480 :     if ( SwOszControl::pStk4 && !pFly->IsLowerOf( SwOszControl::pStk4 ) )
     247           0 :         return true;
     248        5480 :     if ( SwOszControl::pStk5 && !pFly->IsLowerOf( SwOszControl::pStk5 ) )
     249           0 :         return true;
     250        5480 :     return false;
     251             : }
     252             : 
     253         780 : bool SwOszControl::ChkOsz()
     254             : {
     255         780 :     bool bOscillationDetected = false;
     256             : 
     257         780 :     if ( maObjPositions.size() == mnPosStackSize )
     258             :     {
     259             :         // position stack is full -> oscillation
     260           0 :         bOscillationDetected = true;
     261             :     }
     262             :     else
     263             :     {
     264         780 :         Point* pNewObjPos = new Point( pFly->GetObjRect().Pos() );
     265        2343 :         for ( std::vector<Point*>::iterator aObjPosIter = maObjPositions.begin();
     266        1562 :               aObjPosIter != maObjPositions.end();
     267             :               ++aObjPosIter )
     268             :         {
     269           1 :             if ( *(pNewObjPos) == *(*aObjPosIter) )
     270             :             {
     271             :                 // position already occurred -> oscillation
     272           0 :                 bOscillationDetected = true;
     273           0 :                 delete pNewObjPos;
     274           0 :                 break;
     275             :             }
     276             :         }
     277         780 :         if ( !bOscillationDetected )
     278             :         {
     279         780 :             maObjPositions.push_back( pNewObjPos );
     280             :         }
     281             :     }
     282             : 
     283         780 :     return bOscillationDetected;
     284             : }
     285             : 
     286             : /**
     287             : |*      With a paragraph-anchored fly it's absolutely possible that
     288             : |*      the anchor reacts to changes of the fly. To this reaction the fly must
     289             : |*      certaily react too. Sadly this can lead to oscillations; for example the
     290             : |*      fly wants to go down therefore the content can go up - this leads to a
     291             : |*      smaller TxtFrm thus the fly needs to go up again whereby the text will
     292             : |*      get pushed down...
     293             : |*      To avoid such oscillations, a small position stack is built. If the fly
     294             : |*      reaches a position which it already had once, the action is stopped.
     295             : |*      To not run into problems, the stack is designed to hold five positions.
     296             : |*      If the stack flows over, the action is stopped too.
     297             : |*      Cancellation leads to the situation that the fly has a bad position in
     298             : |*      the end. In case of cancellation, the frame is set to automatic top
     299             : |*      alignment to not trigger a 'big oscillation' when calling from outside
     300             : |*      again.
     301             : |*/
     302        1456 : void SwFlyAtCntFrm::MakeAll()
     303             : {
     304        1456 :     if ( !GetFmt()->GetDoc()->IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) )
     305             :     {
     306        1456 :         return;
     307             :     }
     308             : 
     309        1456 :     if ( !SwOszControl::IsInProgress( this ) && !IsLocked() && !IsColLocked() )
     310             :     {
     311             :         // #i28701# - use new method <GetPageFrm()>
     312        1456 :         if( !GetPageFrm() && GetAnchorFrm() && GetAnchorFrm()->IsInFly() )
     313             :         {
     314           0 :             SwFlyFrm* pFly = AnchorFrm()->FindFlyFrm();
     315           0 :             SwPageFrm *pTmpPage = pFly ? pFly->FindPageFrm() : NULL;
     316           0 :             if( pTmpPage )
     317           0 :                 pTmpPage->AppendFlyToPage( this );
     318             :         }
     319             :         // #i28701# - use new method <GetPageFrm()>
     320        1456 :         if( GetPageFrm() )
     321             :         {
     322        1456 :             bSetCompletePaintOnInvalidate = true;
     323             :             {
     324        1456 :                 SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt();
     325        1456 :                 const SwFmtFrmSize &rFrmSz = GetFmt()->GetFrmSize();
     326        2912 :                 if( rFrmSz.GetHeightPercent() != 0xFF &&
     327        1456 :                     rFrmSz.GetHeightPercent() >= 100 )
     328             :                 {
     329           0 :                     pFmt->LockModify();
     330           0 :                     SwFmtSurround aMain( pFmt->GetSurround() );
     331           0 :                     if ( aMain.GetSurround() == SURROUND_NONE )
     332             :                     {
     333           0 :                         aMain.SetSurround( SURROUND_THROUGHT );
     334           0 :                         pFmt->SetFmtAttr( aMain );
     335             :                     }
     336           0 :                     pFmt->UnlockModify();
     337             :                 }
     338             :             }
     339             : 
     340        1456 :             SwOszControl aOszCntrl( this );
     341             : 
     342             :             // #i43255#
     343             :             // #i50356# - format the anchor frame, which
     344             :             // contains the anchor position. E.g., for at-character anchored
     345             :             // object this can be the follow frame of the anchor frame.
     346             :             const bool bFormatAnchor =
     347        2912 :                     !static_cast<const SwTxtFrm*>( GetAnchorFrmContainingAnchPos() )->IsAnyJoinLocked() &&
     348        2280 :                     !ConsiderObjWrapInfluenceOnObjPos() &&
     349        2280 :                     !ConsiderObjWrapInfluenceOfOtherObjs();
     350             : 
     351        1456 :             const SwFrm* pFooter = GetAnchorFrm()->FindFooterOrHeader();
     352        1456 :             if( pFooter && !pFooter->IsFooterFrm() )
     353         275 :                 pFooter = NULL;
     354        1456 :             bool bOsz = false;
     355        1456 :             bool bExtra = Lower() && Lower()->IsColumnFrm();
     356             :             // #i3317# - boolean, to apply temporarly the
     357             :             // 'straightforward positioning process' for the frame due to its
     358             :             // overlapping with a previous column.
     359        1456 :             bool bConsiderWrapInfluenceDueToOverlapPrevCol( false );
     360             :             //  #i35911# - boolean, to apply temporarly the
     361             :             // 'straightforward positioning process' for the frame due to fact
     362             :             // that it causes the complete content of its layout environment
     363             :             // to move forward.
     364             :             // #i40444# - extend usage of this boolean:
     365             :             // apply temporarly the 'straightforward positioning process' for
     366             :             // the frame due to the fact that the frame clears the area for
     367             :             // the anchor frame, thus it has to move forward.
     368        1456 :             bool bConsiderWrapInfluenceDueToMovedFwdAnchor( false );
     369        4386 :             do {
     370        1465 :                 SWRECTFN( this )
     371        1465 :                 Point aOldPos( (Frm().*fnRect->fnGetPos)() );
     372        1465 :                 SwFlyFreeFrm::MakeAll();
     373             :                 const bool bPosChgDueToOwnFormat =
     374        1465 :                                         aOldPos != (Frm().*fnRect->fnGetPos)();
     375             :                 // #i3317#
     376        2298 :                 if ( !ConsiderObjWrapInfluenceOnObjPos() &&
     377         833 :                      OverlapsPrevColumn() )
     378             :                 {
     379           0 :                     bConsiderWrapInfluenceDueToOverlapPrevCol = true;
     380             :                 }
     381             :                 // #i28701# - no format of anchor frame, if
     382             :                 // wrapping style influence is considered on object positioning
     383        1465 :                 if ( bFormatAnchor )
     384             :                 {
     385             :                     SwTxtFrm& rAnchPosAnchorFrm =
     386         832 :                             dynamic_cast<SwTxtFrm&>(*GetAnchorFrmContainingAnchPos());
     387             :                     // #i58182# - For the usage of new method
     388             :                     // <SwObjectFormatterTxtFrm::CheckMovedFwdCondition(..)>
     389             :                     // to check move forward of anchor frame due to the object
     390             :                     // positioning it's needed to know, if the object is anchored
     391             :                     // at the master frame before the anchor frame is formatted.
     392         832 :                     const bool bAnchoredAtMaster(!rAnchPosAnchorFrm.IsFollow());
     393             : 
     394             :                     // #i56300#
     395             :                     // perform complete format of anchor text frame and its
     396             :                     // previous frames, which have become invalid due to the
     397             :                     // fly frame format.
     398         832 :                     SwObjectFormatterTxtFrm::FormatAnchorFrmAndItsPrevs( rAnchPosAnchorFrm );
     399             :                     // #i35911#
     400             :                     // #i40444#
     401             :                     // #i58182# - usage of new method
     402             :                     // <SwObjectFormatterTxtFrm::CheckMovedFwdCondition(..)>
     403         832 :                     sal_uInt32 nToPageNum( 0L );
     404         832 :                     bool bDummy( false );
     405         832 :                     if ( SwObjectFormatterTxtFrm::CheckMovedFwdCondition(
     406         832 :                                         *this, GetPageFrm()->GetPhyPageNum(),
     407        1664 :                                         bAnchoredAtMaster, nToPageNum, bDummy ) )
     408             :                     {
     409           0 :                         bConsiderWrapInfluenceDueToMovedFwdAnchor = true;
     410             :                         // mark anchor text frame
     411             :                         // directly, that it is moved forward by object positioning.
     412           0 :                         SwTxtFrm* pAnchorTxtFrm( static_cast<SwTxtFrm*>(AnchorFrm()) );
     413           0 :                         bool bInsert( true );
     414           0 :                         sal_uInt32 nAnchorFrmToPageNum( 0L );
     415           0 :                         const SwDoc& rDoc = *(GetFrmFmt().GetDoc());
     416           0 :                         if ( SwLayouter::FrmMovedFwdByObjPos(
     417             :                                                 rDoc, *pAnchorTxtFrm, nAnchorFrmToPageNum ) )
     418             :                         {
     419           0 :                             if ( nAnchorFrmToPageNum < nToPageNum )
     420           0 :                                 SwLayouter::RemoveMovedFwdFrm( rDoc, *pAnchorTxtFrm );
     421             :                             else
     422           0 :                                 bInsert = false;
     423             :                         }
     424           0 :                         if ( bInsert )
     425             :                         {
     426             :                             SwLayouter::InsertMovedFwdFrm( rDoc, *pAnchorTxtFrm,
     427           0 :                                                            nToPageNum );
     428             :                         }
     429             :                     }
     430             :                 }
     431             : 
     432        2930 :                 if ( aOldPos != (Frm().*fnRect->fnGetPos)() ||
     433         685 :                      ( !GetValidPosFlag() &&
     434           0 :                        ( pFooter || bPosChgDueToOwnFormat ) ) )
     435             :                 {
     436         780 :                     bOsz = aOszCntrl.ChkOsz();
     437             : 
     438             :                     // special loop prevention for dedicated document:
     439         780 :                     if ( bOsz &&
     440         780 :                          HasFixSize() && IsClipped() &&
     441           0 :                          GetAnchorFrm()->GetUpper()->IsCellFrm() )
     442             :                     {
     443           0 :                         SwFrmFmt* pFmt = GetFmt();
     444           0 :                         const SwFmtFrmSize& rFrmSz = pFmt->GetFrmSize();
     445           0 :                         if ( rFrmSz.GetWidthPercent() &&
     446           0 :                              rFrmSz.GetHeightPercent() == 0xFF )
     447             :                         {
     448           0 :                             SwFmtSurround aSurround( pFmt->GetSurround() );
     449           0 :                             if ( aSurround.GetSurround() == SURROUND_NONE )
     450             :                             {
     451           0 :                                 pFmt->LockModify();
     452           0 :                                 aSurround.SetSurround( SURROUND_THROUGHT );
     453           0 :                                 pFmt->SetFmtAttr( aSurround );
     454           0 :                                 pFmt->UnlockModify();
     455           0 :                                 bOsz = false;
     456             :                                 OSL_FAIL( "<SwFlyAtCntFrm::MakeAll()> - special loop prevention for dedicated document of b6403541 applied" );
     457           0 :                             }
     458             :                         }
     459             :                     }
     460             :                 }
     461             : 
     462        1465 :                 if ( bExtra && Lower() && !Lower()->GetValidPosFlag() )
     463             :                 {
     464             :                     // If a multi column frame leaves invalid columns because of
     465             :                     // a position change, we loop once more and format
     466             :                     // our content using FormatWidthCols again.
     467           0 :                     _InvalidateSize();
     468           0 :                     bExtra = false; // Ensure only one additional loop run
     469             :                 }
     470        1483 :             } while ( !IsValid() && !bOsz &&
     471             :                       // #i3317#
     472          18 :                       !bConsiderWrapInfluenceDueToOverlapPrevCol &&
     473             :                       // #i40444#
     474        2957 :                       !bConsiderWrapInfluenceDueToMovedFwdAnchor &&
     475        1492 :                       GetFmt()->GetDoc()->IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) );
     476             : 
     477             :             // #i3317# - instead of attribute change apply
     478             :             // temporarly the 'straightforward positioning process'.
     479             :             // #i80924#
     480             :             // handle special case during splitting of table rows
     481        1456 :             if ( bConsiderWrapInfluenceDueToMovedFwdAnchor &&
     482        1456 :                  GetAnchorFrm()->IsInTab() &&
     483           0 :                  GetAnchorFrm()->IsInFollowFlowRow() )
     484             :             {
     485           0 :                 const SwFrm* pCellFrm = GetAnchorFrm();
     486           0 :                 while ( pCellFrm && !pCellFrm->IsCellFrm() )
     487             :                 {
     488           0 :                     pCellFrm = pCellFrm->GetUpper();
     489             :                 }
     490           0 :                 if ( pCellFrm )
     491             :                 {
     492           0 :                     SWRECTFN( pCellFrm )
     493           0 :                     if ( (pCellFrm->Frm().*fnRect->fnGetTop)() == 0 &&
     494           0 :                          (pCellFrm->Frm().*fnRect->fnGetHeight)() == 0 )
     495             :                     {
     496           0 :                         bConsiderWrapInfluenceDueToMovedFwdAnchor = false;
     497             :                     }
     498             :                 }
     499             :             }
     500        1456 :             if ( bOsz || bConsiderWrapInfluenceDueToOverlapPrevCol ||
     501             :                  // #i40444#
     502             :                  bConsiderWrapInfluenceDueToMovedFwdAnchor )
     503             :             {
     504           0 :                 SetTmpConsiderWrapInfluence( true );
     505           0 :                 SetRestartLayoutProcess( true );
     506           0 :                 SetTmpConsiderWrapInfluenceOfOtherObjs( true );
     507             :             }
     508        1456 :             bSetCompletePaintOnInvalidate = false;
     509             :         }
     510             :     }
     511             : }
     512             : 
     513             : /** method to determine, if a <MakeAll()> on the Writer fly frame is possible
     514             : 
     515             :     #i28701#
     516             : */
     517        4024 : bool SwFlyAtCntFrm::IsFormatPossible() const
     518             : {
     519        8048 :     return SwFlyFreeFrm::IsFormatPossible() &&
     520        8048 :            !SwOszControl::IsInProgress( this );
     521             : }
     522             : 
     523             : class SwDistance
     524             : {
     525             : public:
     526             :     SwTwips nMain, nSub;
     527          21 :     SwDistance() { nMain = nSub = 0; }
     528         176 :     SwDistance& operator=( const SwDistance &rTwo )
     529         176 :         { nMain = rTwo.nMain; nSub = rTwo.nSub; return *this; }
     530          40 :     bool operator<( const SwDistance& rTwo ) const
     531          41 :         { return nMain < rTwo.nMain || ( nMain == rTwo.nMain && nSub &&
     532          78 :           rTwo.nSub && nSub < rTwo.nSub ); }
     533         170 :     bool operator<=( const SwDistance& rTwo ) const
     534         387 :         { return nMain < rTwo.nMain || ( nMain == rTwo.nMain && ( !nSub ||
     535         270 :           !rTwo.nSub || nSub <= rTwo.nSub ) ); }
     536             : };
     537             : 
     538         177 : static const SwFrm * lcl_CalcDownDist( SwDistance &rRet,
     539             :                                          const Point &rPt,
     540             :                                          const SwCntntFrm *pCnt )
     541             : {
     542         177 :     rRet.nSub = 0;
     543             :     //If the point stays inside the Cnt everything is clear already; the Cntnt
     544             :     //automatically has a distance of 0.
     545         177 :     if ( pCnt->Frm().IsInside( rPt ) )
     546             :     {
     547           0 :         rRet.nMain = 0;
     548           0 :         return pCnt;
     549             :     }
     550             :     else
     551             :     {
     552         177 :         const SwLayoutFrm *pUp = pCnt->IsInTab() ? pCnt->FindTabFrm()->GetUpper() : pCnt->GetUpper();
     553             :         // single column sections need to interconnect to their upper
     554         354 :         while( pUp->IsSctFrm() )
     555           0 :             pUp = pUp->GetUpper();
     556         177 :         const bool bVert = pUp->IsVertical();
     557             :         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     558         177 :         const bool bVertL2R = pUp->IsVertLR();
     559             : 
     560             :         //Follow the text flow.
     561             :         // #i70582#
     562             :         // --> OD 2009-03-05 - adopted for Support for Classical Mongolian Script
     563             :         const SwTwips nTopForObjPos =
     564             :             bVert
     565             :             ? ( bVertL2R
     566           0 :                 ? ( pCnt->Frm().Left() +
     567           0 :                     pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() )
     568           0 :                 : ( pCnt->Frm().Left() +
     569           0 :                     pCnt->Frm().Width() -
     570           0 :                     pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() ) )
     571         177 :             : ( pCnt->Frm().Top() +
     572         354 :                 pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() );
     573         177 :         if ( pUp->Frm().IsInside( rPt ) )
     574             :         {
     575             :             // <rPt> point is inside environment of given content frame
     576             :             // #i70582#
     577           6 :             if( bVert )
     578             :             //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     579             :             {
     580           0 :                    if ( bVertL2R )
     581           0 :                     rRet.nMain =  rPt.X() - nTopForObjPos;
     582             :                 else
     583           0 :                     rRet.nMain =  nTopForObjPos - rPt.X();
     584             :             }
     585             :             else
     586           6 :                 rRet.nMain =  rPt.Y() - nTopForObjPos;
     587           6 :             return pCnt;
     588             :         }
     589         171 :         else if ( rPt.Y() <= pUp->Frm().Top() )
     590             :         {
     591             :             // <rPt> point is above environment of given content frame
     592             :             // correct for vertical layout?
     593           0 :             rRet.nMain = LONG_MAX;
     594             :         }
     595         171 :         else if( rPt.X() < pUp->Frm().Left() &&
     596           0 :                  rPt.Y() <= ( bVert ? pUp->Frm().Top() : pUp->Frm().Bottom() ) )
     597             :         {
     598             :             // <rPt> point is left of environment of given content frame
     599             :             // seems not to be correct for vertical layout!?
     600           0 :             const SwFrm *pLay = pUp->GetLeaf( MAKEPAGE_NONE, sal_False, pCnt );
     601           0 :             if( !pLay ||
     602           0 :                 (bVert && (pLay->Frm().Top() + pLay->Prt().Bottom()) <rPt.Y())||
     603           0 :                 (!bVert && (pLay->Frm().Left() + pLay->Prt().Right())<rPt.X()) )
     604             :             {
     605             :                 // <rPt> point is in left border of environment
     606             :                 // #i70582#
     607           0 :                 if( bVert )
     608             :                 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     609             :                 {
     610           0 :                        if ( bVertL2R )
     611           0 :                         rRet.nMain = rPt.X() - nTopForObjPos;
     612             :                     else
     613           0 :                         rRet.nMain =  nTopForObjPos - rPt.X();
     614             :                 }
     615             :                 else
     616           0 :                     rRet.nMain = rPt.Y() - nTopForObjPos;
     617           0 :                 return pCnt;
     618             :             }
     619             :             else
     620           0 :                 rRet.nMain = LONG_MAX;
     621             :         }
     622             :         else
     623             :         {
     624             :             // Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     625             :             rRet.nMain = bVert
     626             :                 ? ( bVertL2R
     627           0 :                     ? ( (pUp->Frm().Left() + pUp->Prt().Right()) - nTopForObjPos )
     628           0 :                     : ( nTopForObjPos - (pUp->Frm().Left() + pUp->Prt().Left() ) ) )
     629         171 :                 : ( (pUp->Frm().Top() + pUp->Prt().Bottom()) - nTopForObjPos );
     630             : 
     631         171 :             const SwFrm *pPre = pCnt;
     632         171 :             const SwFrm *pLay = pUp->GetLeaf( MAKEPAGE_NONE, sal_True, pCnt );
     633         171 :             SwTwips nFrmTop = 0;
     634         171 :             SwTwips nPrtHeight = 0;
     635         171 :             bool bSct = false;
     636         171 :             const SwSectionFrm *pSect = pUp->FindSctFrm();
     637         171 :             if( pSect )
     638             :             {
     639          52 :                 rRet.nSub = rRet.nMain;
     640          52 :                 rRet.nMain = 0;
     641             :             }
     642         171 :             if( pSect && !pSect->IsAnLower( pLay ) )
     643             :             {
     644           0 :                 bSct = false;
     645           0 :                 const SwSectionFrm* pNxtSect = pLay ? pLay->FindSctFrm() : 0;
     646           0 :                 if( pSect->IsAnFollow( pNxtSect ) )
     647             :                 {
     648           0 :                     if( pLay->IsVertical() )
     649             :                     {
     650             :                         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     651           0 :                         if ( pLay->IsVertLR() )
     652           0 :                             nFrmTop = pLay->Frm().Left();
     653             :                         else
     654           0 :                             nFrmTop = pLay->Frm().Left() + pLay->Frm().Width();
     655           0 :                         nPrtHeight = pLay->Prt().Width();
     656             :                     }
     657             :                     else
     658             :                     {
     659           0 :                         nFrmTop = pLay->Frm().Top();
     660           0 :                         nPrtHeight = pLay->Prt().Height();
     661             :                     }
     662           0 :                     pSect = pNxtSect;
     663             :                 }
     664             :                 else
     665             :                 {
     666           0 :                     pLay = pSect->GetUpper();
     667           0 :                     if( pLay->IsVertical() )
     668             :                     {
     669             :                         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     670           0 :                         if ( pLay->IsVertLR() )
     671             :                         {
     672           0 :                             nFrmTop = pSect->Frm().Right();
     673           0 :                             nPrtHeight = pLay->Frm().Left() + pLay->Prt().Left()
     674           0 :                                          + pLay->Prt().Width() - pSect->Frm().Left()
     675           0 :                                          - pSect->Frm().Width();
     676             :                          }
     677             :                          else
     678             :                          {
     679           0 :                              nFrmTop = pSect->Frm().Left();
     680           0 :                              nPrtHeight = pSect->Frm().Left() - pLay->Frm().Left()
     681           0 :                                      - pLay->Prt().Left();
     682             :                           }
     683             :                     }
     684             :                     else
     685             :                     {
     686           0 :                         nFrmTop = pSect->Frm().Bottom();
     687           0 :                         nPrtHeight = pLay->Frm().Top() + pLay->Prt().Top()
     688           0 :                                      + pLay->Prt().Height() - pSect->Frm().Top()
     689           0 :                                      - pSect->Frm().Height();
     690             :                     }
     691           0 :                     pSect = 0;
     692             :                 }
     693             :             }
     694         171 :             else if( pLay )
     695             :             {
     696          55 :                 if( pLay->IsVertical() )
     697             :                 {
     698             :                     //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     699           0 :                     if ( pLay->IsVertLR() )
     700             :                     {
     701           0 :                         nFrmTop = pLay->Frm().Left();
     702           0 :                         nPrtHeight = pLay->Prt().Width();
     703             :                     }
     704             :                     else
     705             :                     {
     706           0 :                         nFrmTop = pLay->Frm().Left() + pLay->Frm().Width();
     707           0 :                         nPrtHeight = pLay->Prt().Width();
     708             :                     }
     709             :                 }
     710             :                 else
     711             :                 {
     712          55 :                     nFrmTop = pLay->Frm().Top();
     713          55 :                     nPrtHeight = pLay->Prt().Height();
     714             :                 }
     715          55 :                 bSct = 0 != pSect;
     716             :             }
     717         663 :             while ( pLay && !pLay->Frm().IsInside( rPt ) &&
     718         107 :                     ( pLay->Frm().Top() <= rPt.Y() || pLay->IsInFly() ||
     719           0 :                       ( pLay->IsInSct() &&
     720           0 :                       pLay->FindSctFrm()->GetUpper()->Frm().Top() <= rPt.Y())) )
     721             :             {
     722         107 :                 if ( pLay->IsFtnContFrm() )
     723             :                 {
     724           0 :                     if ( !((SwLayoutFrm*)pLay)->Lower() )
     725             :                     {
     726           0 :                         SwFrm *pDel = (SwFrm*)pLay;
     727           0 :                         pDel->Cut();
     728           0 :                         delete pDel;
     729           0 :                         return pPre;
     730             :                     }
     731           0 :                     return 0;
     732             :                 }
     733             :                 else
     734             :                 {
     735         107 :                     if( bSct || pSect )
     736          52 :                         rRet.nSub += nPrtHeight;
     737             :                     else
     738          55 :                         rRet.nMain += nPrtHeight;
     739         107 :                     pPre = pLay;
     740         107 :                     pLay = pLay->GetLeaf( MAKEPAGE_NONE, sal_True, pCnt );
     741         107 :                     if( pSect && !pSect->IsAnLower( pLay ) )
     742             :                     {   // If we're leaving a SwSectionFrm, the next Leaf-Frm
     743             :                         // is the part of the upper below the SectionFrm.
     744             :                         const SwSectionFrm* pNxtSect = pLay ?
     745          52 :                             pLay->FindSctFrm() : NULL;
     746          52 :                         bSct = false;
     747          52 :                         if( pSect->IsAnFollow( pNxtSect ) )
     748             :                         {
     749           0 :                             pSect = pNxtSect;
     750           0 :                             if( pLay->IsVertical() )
     751             :                             {
     752             :                                 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     753           0 :                                 if ( pLay->IsVertLR() )
     754             :                                 {
     755           0 :                                     nFrmTop = pLay->Frm().Left();
     756           0 :                                     nPrtHeight = pLay->Prt().Width();
     757             :                                 }
     758             :                                 else
     759             :                                 {
     760           0 :                                     nFrmTop = pLay->Frm().Left() + pLay->Frm().Width();
     761           0 :                                     nPrtHeight = pLay->Prt().Width();
     762             :                                 }
     763             :                             }
     764             :                             else
     765             :                             {
     766           0 :                                 nFrmTop = pLay->Frm().Top();
     767           0 :                                 nPrtHeight = pLay->Prt().Height();
     768             :                             }
     769             :                         }
     770             :                         else
     771             :                         {
     772          52 :                             pLay = pSect->GetUpper();
     773          52 :                             if( pLay->IsVertical() )
     774             :                             {
     775             :                                 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     776           0 :                                 if ( pLay->IsVertLR() )
     777             :                                 {
     778           0 :                                     nFrmTop = pSect->Frm().Right();
     779           0 :                                     nPrtHeight = pLay->Frm().Left()+pLay->Prt().Left()
     780           0 :                                              + pLay->Prt().Width() - pSect->Frm().Left()
     781           0 :                                              - pSect->Frm().Width();
     782             :                                 }
     783             :                                 else
     784             :                                 {
     785           0 :                                     nFrmTop = pSect->Frm().Left();
     786           0 :                                     nPrtHeight = pSect->Frm().Left() -
     787           0 :                                             pLay->Frm().Left() - pLay->Prt().Left();
     788             :                                 }
     789             :                             }
     790             :                             else
     791             :                             {
     792          52 :                                 nFrmTop = pSect->Frm().Bottom();
     793          52 :                                 nPrtHeight = pLay->Frm().Top()+pLay->Prt().Top()
     794          52 :                                      + pLay->Prt().Height() - pSect->Frm().Top()
     795          52 :                                      - pSect->Frm().Height();
     796             :                             }
     797          52 :                             pSect = 0;
     798             :                         }
     799             :                     }
     800          55 :                     else if( pLay )
     801             :                     {
     802           0 :                         if( pLay->IsVertical() )
     803             :                         {
     804             :                              //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     805           0 :                              if ( pLay->IsVertLR() )
     806             :                               {
     807           0 :                                  nFrmTop = pLay->Frm().Left();
     808           0 :                                  nPrtHeight = pLay->Prt().Width();
     809             :                              }
     810             :                              else
     811             :                              {
     812           0 :                                  nFrmTop = pLay->Frm().Left() + pLay->Frm().Width();
     813           0 :                                  nPrtHeight = pLay->Prt().Width();
     814             :                              }
     815             :                         }
     816             :                         else
     817             :                         {
     818           0 :                             nFrmTop = pLay->Frm().Top();
     819           0 :                             nPrtHeight = pLay->Prt().Height();
     820             :                         }
     821           0 :                         bSct = 0 != pSect;
     822             :                     }
     823             :                 }
     824             :             }
     825         171 :             if ( pLay )
     826             :             {
     827           0 :                 if ( pLay->Frm().IsInside( rPt ) )
     828             :                 {
     829             :                     //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     830           0 :                     SwTwips nDiff = pLay->IsVertical() ? ( pLay->IsVertLR() ? ( rPt.X() - nFrmTop ) : ( nFrmTop - rPt.X() ) )
     831           0 :                                                        : ( rPt.Y() - nFrmTop );
     832           0 :                     if( bSct || pSect )
     833           0 :                         rRet.nSub += nDiff;
     834             :                     else
     835           0 :                         rRet.nMain += nDiff;
     836             :                 }
     837           0 :                 if ( pLay->IsFtnContFrm() && !((SwLayoutFrm*)pLay)->Lower() )
     838             :                 {
     839           0 :                     SwFrm *pDel = (SwFrm*)pLay;
     840           0 :                     pDel->Cut();
     841           0 :                     delete pDel;
     842           0 :                     return 0;
     843             :                 }
     844           0 :                 return pLay;
     845             :             }
     846             :             else
     847         171 :                 rRet.nMain = LONG_MAX;
     848             :         }
     849             :     }
     850         171 :     return 0;
     851             : }
     852             : 
     853          10 : static sal_uInt64 lcl_FindCntDiff( const Point &rPt, const SwLayoutFrm *pLay,
     854             :                           const SwCntntFrm *& rpCnt,
     855             :                           const bool bBody, const sal_Bool bFtn )
     856             : {
     857             :     // Searches below pLay the nearest Cnt to the point. The reference point of
     858             :     //the Cntnts is always the left upper corner.
     859             :     //The Cnt should preferably be above the point.
     860             : 
     861             : #if OSL_DEBUG_LEVEL > 1
     862             :     Point arPoint( rPt );
     863             : #endif
     864             : 
     865          10 :     rpCnt = 0;
     866          10 :     sal_uInt64 nDistance = SAL_MAX_UINT64;
     867          10 :     sal_uInt64 nNearest  = SAL_MAX_UINT64;
     868          10 :     const SwCntntFrm *pCnt = pLay ? pLay->ContainsCntnt() : NULL;
     869             : 
     870          22 :     while ( pCnt && (bBody != pCnt->IsInDocBody() || bFtn != pCnt->IsInFtn()))
     871             :     {
     872           2 :         pCnt = pCnt->GetNextCntntFrm();
     873           2 :         if ( !pLay->IsAnLower( pCnt ) )
     874           0 :             pCnt = 0;
     875             :     }
     876          10 :     const SwCntntFrm *pNearest = pCnt;
     877          10 :     if ( pCnt )
     878             :     {
     879         197 :         do
     880             :         {
     881             :             //Calculate the distance between those two points.
     882             :             //'delta' X^2 + 'delta' Y^2 = 'distance'^2
     883         591 :             sal_uInt64 dX = std::max( pCnt->Frm().Left(), rPt.X() ) -
     884         394 :                        std::min( pCnt->Frm().Left(), rPt.X() ),
     885         591 :                   dY = std::max( pCnt->Frm().Top(), rPt.Y() ) -
     886         394 :                        std::min( pCnt->Frm().Top(), rPt.Y() );
     887             :             // square of the difference will do fine here
     888         197 :             const sal_uInt64 nDiff = (dX * dX) + (dY * dY);
     889         197 :             if ( pCnt->Frm().Top() <= rPt.Y() )
     890             :             {
     891         197 :                 if ( nDiff < nDistance )
     892             :                 {
     893             :                     //This one is the nearer one
     894         129 :                     nDistance = nNearest = nDiff;
     895         129 :                     rpCnt = pNearest = pCnt;
     896             :                 }
     897             :             }
     898           0 :             else if ( nDiff < nNearest )
     899             :             {
     900           0 :                 nNearest = nDiff;
     901           0 :                 pNearest = pCnt;
     902             :             }
     903         197 :             pCnt = pCnt->GetNextCntntFrm();
     904         616 :             while ( pCnt &&
     905         394 :                     (bBody != pCnt->IsInDocBody() || bFtn != pCnt->IsInFtn()))
     906          10 :                 pCnt = pCnt->GetNextCntntFrm();
     907             : 
     908         197 :         }  while ( pCnt && pLay->IsAnLower( pCnt ) );
     909             :     }
     910          10 :     if (nDistance == SAL_MAX_UINT64)
     911           0 :     {   rpCnt = pNearest;
     912           0 :         return nNearest;
     913             :     }
     914          10 :     return nDistance;
     915             : }
     916             : 
     917           5 : static const SwCntntFrm * lcl_FindCnt( const Point &rPt, const SwCntntFrm *pCnt,
     918             :                                   const bool bBody, const sal_Bool bFtn )
     919             : {
     920             :     //Starting from pCnt searches the CntntFrm whose left upper corner is the
     921             :     //nearest to the point.
     922             :     //Always returns a CntntFrm.
     923             : 
     924             :     //First the nearest Cntnt inside the page which contains the Cntnt is
     925             :     //searched. Starting from this page the pages in both directions need to
     926             :     //be considered. If possible a Cntnt is returned whose Y-position is
     927             :     //above the point.
     928             :     const SwCntntFrm  *pRet, *pNew;
     929           5 :     const SwLayoutFrm *pLay = pCnt->FindPageFrm();
     930             :     sal_uInt64 nDist; // not sure if a sal_Int32 would be enough?
     931             : 
     932           5 :     nDist = ::lcl_FindCntDiff( rPt, pLay, pNew, bBody, bFtn );
     933           5 :     if ( pNew )
     934           5 :         pRet = pNew;
     935             :     else
     936           0 :     {   pRet  = pCnt;
     937           0 :         nDist = SAL_MAX_UINT64;
     938             :     }
     939           5 :     const SwCntntFrm *pNearest = pRet;
     940           5 :     sal_uInt64 nNearest = nDist;
     941             : 
     942           5 :     if ( pLay )
     943             :     {
     944           5 :         const SwLayoutFrm *pPge = pLay;
     945           5 :         sal_uInt64 nOldNew = SAL_MAX_UINT64;
     946          10 :         for ( sal_uInt16 i = 0; pPge->GetPrev() && (i < 3); ++i )
     947             :         {
     948           5 :             pPge = (SwLayoutFrm*)pPge->GetPrev();
     949           5 :             const sal_uInt64 nNew = ::lcl_FindCntDiff( rPt, pPge, pNew, bBody, bFtn );
     950           5 :             if ( nNew < nDist )
     951             :             {
     952           0 :                 if ( pNew->Frm().Top() <= rPt.Y() )
     953             :                 {
     954           0 :                     pRet = pNearest = pNew;
     955           0 :                     nDist = nNearest = nNew;
     956             :                 }
     957           0 :                 else if ( nNew < nNearest )
     958             :                 {
     959           0 :                     pNearest = pNew;
     960           0 :                     nNearest = nNew;
     961             :                 }
     962             :             }
     963           5 :             else if (nOldNew != SAL_MAX_UINT64 && nNew > nOldNew)
     964             :                 break;
     965             :             else
     966           5 :                 nOldNew = nNew;
     967             : 
     968             :         }
     969           5 :         pPge = pLay;
     970           5 :         nOldNew = SAL_MAX_UINT64;
     971           5 :         for ( sal_uInt16 j = 0; pPge->GetNext() && (j < 3); ++j )
     972             :         {
     973           0 :             pPge = (SwLayoutFrm*)pPge->GetNext();
     974           0 :             const sal_uInt64 nNew = ::lcl_FindCntDiff( rPt, pPge, pNew, bBody, bFtn );
     975           0 :             if ( nNew < nDist )
     976             :             {
     977           0 :                 if ( pNew->Frm().Top() <= rPt.Y() )
     978             :                 {
     979           0 :                     pRet = pNearest = pNew;
     980           0 :                     nDist = nNearest = nNew;
     981             :                 }
     982           0 :                 else if ( nNew < nNearest )
     983             :                 {
     984           0 :                     pNearest = pNew;
     985           0 :                     nNearest = nNew;
     986             :                 }
     987             :             }
     988           0 :             else if (nOldNew != SAL_MAX_UINT64 && nNew > nOldNew)
     989             :                 break;
     990             :             else
     991           0 :                 nOldNew = nNew;
     992             :         }
     993             :     }
     994           5 :     if ( (pRet->Frm().Top() > rPt.Y()) )
     995           0 :         return pNearest;
     996             :     else
     997           5 :         return pRet;
     998             : }
     999             : 
    1000          24 : static void lcl_PointToPrt( Point &rPoint, const SwFrm *pFrm )
    1001             : {
    1002          24 :     SwRect aTmp( pFrm->Prt() );
    1003          24 :     aTmp += pFrm->Frm().Pos();
    1004          24 :     if ( rPoint.getX() < aTmp.Left() )
    1005           0 :         rPoint.setX(aTmp.Left());
    1006          24 :     else if ( rPoint.getX() > aTmp.Right() )
    1007          12 :         rPoint.setX(aTmp.Right());
    1008          24 :     if ( rPoint.getY() < aTmp.Top() )
    1009           0 :         rPoint.setY(aTmp.Top());
    1010          24 :     else if ( rPoint.getY() > aTmp.Bottom() )
    1011          12 :         rPoint.setY(aTmp.Bottom());
    1012             : 
    1013          24 : }
    1014             : 
    1015             : /** Searches an anchor for paragraph bound objects starting from pOldAnch.
    1016             :  *
    1017             :  *  This is used to show anchors as well as changing anchors
    1018             :  *  when dragging paragraph bound objects.
    1019             :  */
    1020          12 : const SwCntntFrm *FindAnchor( const SwFrm *pOldAnch, const Point &rNew,
    1021             :                               const sal_Bool bBodyOnly )
    1022             : {
    1023             :     //Search the nearest Cnt around the given document position in the text
    1024             :     //flow. The given anchor is the starting Frm.
    1025             :     const SwCntntFrm* pCnt;
    1026          12 :     if ( pOldAnch->IsCntntFrm() )
    1027             :     {
    1028          11 :         pCnt = (const SwCntntFrm*)pOldAnch;
    1029             :     }
    1030             :     else
    1031             :     {
    1032           1 :         Point aTmp( rNew );
    1033           1 :         SwLayoutFrm *pTmpLay = (SwLayoutFrm*)pOldAnch;
    1034           1 :         if( pTmpLay->IsRootFrm() )
    1035             :         {
    1036           0 :             SwRect aTmpRect( aTmp, Size(0,0) );
    1037           0 :             pTmpLay = (SwLayoutFrm*)::FindPage( aTmpRect, pTmpLay->Lower() );
    1038             :         }
    1039           1 :         pCnt = pTmpLay->GetCntntPos( aTmp, sal_False, bBodyOnly );
    1040             :     }
    1041             : 
    1042             :     //Take care to use meaningful ranges during search. This means to not enter
    1043             :     //or leave header/footer in this case.
    1044          12 :     const bool bBody = pCnt->IsInDocBody() || bBodyOnly;
    1045          12 :     const sal_Bool bFtn  = !bBodyOnly && pCnt->IsInFtn();
    1046             : 
    1047          12 :     Point aNew( rNew );
    1048          12 :     if ( bBody )
    1049             :     {
    1050             :         //#38848 drag from page margin into the body.
    1051          12 :         const SwFrm *pPage = pCnt->FindPageFrm();
    1052          12 :         ::lcl_PointToPrt( aNew, pPage->GetUpper() );
    1053          12 :         SwRect aTmp( aNew, Size( 0, 0 ) );
    1054          12 :         pPage = ::FindPage( aTmp, pPage );
    1055          12 :         ::lcl_PointToPrt( aNew, pPage );
    1056             :     }
    1057             : 
    1058          12 :     if ( pCnt->IsInDocBody() == bBody && pCnt->Frm().IsInside( aNew ) )
    1059           3 :         return pCnt;
    1060           9 :     else if ( pOldAnch->IsInDocBody() || pOldAnch->IsPageFrm() )
    1061             :     {
    1062             :         // Maybe the selected anchor is on the same page as the current anchor.
    1063             :         // With this we won't run into problems with the columns.
    1064           9 :         Point aTmp( aNew );
    1065           9 :         const SwCntntFrm *pTmp = pCnt->FindPageFrm()->
    1066           9 :                                         GetCntntPos( aTmp, sal_False, sal_True, sal_False );
    1067           9 :         if ( pTmp && pTmp->Frm().IsInside( aNew ) )
    1068           2 :             return pTmp;
    1069             :     }
    1070             : 
    1071             :     //Starting from the anchor we now search in both directions until we found
    1072             :     //the nearest one respectively.
    1073             :     //Not the direct distance is relevant but the distance which needs to be
    1074             :     //traveled through the text flow.
    1075             :     const SwCntntFrm *pUpLst;
    1076           7 :     const SwCntntFrm *pUpFrm = pCnt;
    1077           7 :     SwDistance nUp, nUpLst;
    1078           7 :     ::lcl_CalcDownDist( nUp, aNew, pUpFrm );
    1079           7 :     SwDistance nDown = nUp;
    1080           7 :     bool bNegAllowed = true;// Make it possible to leave the negative section once.
    1081         168 :     do
    1082             :     {
    1083         168 :         pUpLst = pUpFrm; nUpLst = nUp;
    1084         168 :         pUpFrm = pUpLst->GetPrevCntntFrm();
    1085         500 :         while ( pUpFrm &&
    1086         328 :                 (bBody != pUpFrm->IsInDocBody() || bFtn != pUpFrm->IsInFtn()))
    1087           0 :             pUpFrm = pUpFrm->GetPrevCntntFrm();
    1088         168 :         if ( pUpFrm )
    1089             :         {
    1090         164 :             ::lcl_CalcDownDist( nUp, aNew, pUpFrm );
    1091             :             //It makes sense to search further, if the distance grows inside
    1092             :             //a table.
    1093         164 :             if ( pUpLst->IsInTab() && pUpFrm->IsInTab() )
    1094             :             {
    1095         114 :                 while ( pUpFrm && ((nUpLst < nUp && pUpFrm->IsInTab()) ||
    1096          38 :                         bBody != pUpFrm->IsInDocBody()) )
    1097             :                 {
    1098           0 :                     pUpFrm = pUpFrm->GetPrevCntntFrm();
    1099           0 :                     if ( pUpFrm )
    1100           0 :                         ::lcl_CalcDownDist( nUp, aNew, pUpFrm );
    1101             :                 }
    1102             :             }
    1103             :         }
    1104         168 :         if ( !pUpFrm )
    1105           4 :             nUp.nMain = LONG_MAX;
    1106         168 :         if ( nUp.nMain >= 0 && LONG_MAX != nUp.nMain )
    1107             :         {
    1108           3 :             bNegAllowed = false;
    1109           3 :             if ( nUpLst.nMain < 0 ) //don't take the wrong one, if the value
    1110             :                                     //just changed from negative to positive.
    1111           0 :             {   pUpLst = pUpFrm;
    1112           0 :                 nUpLst = nUp;
    1113             :             }
    1114             :         }
    1115         168 :     } while ( pUpFrm && ( ( bNegAllowed && nUp.nMain < 0 ) || ( nUp <= nUpLst ) ) );
    1116             : 
    1117             :     const SwCntntFrm *pDownLst;
    1118           7 :     const SwCntntFrm *pDownFrm = pCnt;
    1119           7 :     SwDistance nDownLst;
    1120           7 :     if ( nDown.nMain < 0 )
    1121           0 :         nDown.nMain = LONG_MAX;
    1122           8 :     do
    1123             :     {
    1124           8 :         pDownLst = pDownFrm; nDownLst = nDown;
    1125           8 :         pDownFrm = pDownLst->GetNextCntntFrm();
    1126          22 :         while ( pDownFrm &&
    1127          12 :                 (bBody != pDownFrm->IsInDocBody() || bFtn != pDownFrm->IsInFtn()))
    1128           0 :             pDownFrm = pDownFrm->GetNextCntntFrm();
    1129           8 :         if ( pDownFrm )
    1130             :         {
    1131           6 :             ::lcl_CalcDownDist( nDown, aNew, pDownFrm );
    1132           6 :             if ( nDown.nMain < 0 )
    1133           0 :                 nDown.nMain = LONG_MAX;
    1134             :             //It makes sense to search further, if the distance grows inside
    1135             :             //a table.
    1136           6 :             if ( pDownLst->IsInTab() && pDownFrm->IsInTab() )
    1137             :             {
    1138           0 :                 while ( pDownFrm && ( ( nDown.nMain != LONG_MAX && pDownFrm->IsInTab()) || bBody != pDownFrm->IsInDocBody() ) )
    1139             :                 {
    1140           0 :                     pDownFrm = pDownFrm->GetNextCntntFrm();
    1141           0 :                     if ( pDownFrm )
    1142           0 :                         ::lcl_CalcDownDist( nDown, aNew, pDownFrm );
    1143           0 :                     if ( nDown.nMain < 0 )
    1144           0 :                         nDown.nMain = LONG_MAX;
    1145             :                 }
    1146             :             }
    1147             :         }
    1148           8 :         if ( !pDownFrm )
    1149           2 :             nDown.nMain = LONG_MAX;
    1150             : 
    1151          12 :     } while ( pDownFrm && nDown <= nDownLst &&
    1152          15 :               nDown.nMain != LONG_MAX && nDownLst.nMain != LONG_MAX );
    1153             : 
    1154             :     //If we couldn't find one in both directions, we'll search the Cntnt whose
    1155             :     //left upper corner is the nearest to the point. Such a situation may
    1156             :     //happen, if the point doesn't lay in the text flow but in any margin.
    1157           7 :     if ( nDownLst.nMain == LONG_MAX && nUpLst.nMain == LONG_MAX )
    1158             :     {
    1159             :         // If an OLE objects, which is contained in a fly frame
    1160             :         // is resized in inplace mode and the new Position is outside the
    1161             :         // fly frame, we do not want to leave our fly frame.
    1162           5 :         if ( pCnt->IsInFly() )
    1163           0 :             return pCnt;
    1164             : 
    1165           5 :         return ::lcl_FindCnt( aNew, pCnt, bBody, bFtn );
    1166             :     }
    1167             :     else
    1168           2 :         return nDownLst < nUpLst ? pDownLst : pUpLst;
    1169             : }
    1170             : 
    1171           0 : void SwFlyAtCntFrm::SetAbsPos( const Point &rNew )
    1172             : {
    1173           0 :     SwPageFrm *pOldPage = FindPageFrm();
    1174           0 :     const SwRect aOld( GetObjRectWithSpaces() );
    1175           0 :     Point aNew( rNew );
    1176             :     //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
    1177           0 :       if( ( GetAnchorFrm()->IsVertical() && !GetAnchorFrm()->IsVertLR() ) || GetAnchorFrm()->IsRightToLeft() )
    1178           0 :         aNew.setX(aNew.getX() + Frm().Width());
    1179           0 :     SwCntntFrm *pCnt = (SwCntntFrm*)::FindAnchor( GetAnchorFrm(), aNew );
    1180           0 :     if( pCnt->IsProtected() )
    1181           0 :         pCnt = (SwCntntFrm*)GetAnchorFrm();
    1182             : 
    1183           0 :     SwPageFrm *pTmpPage = 0;
    1184           0 :     const bool bVert = pCnt->IsVertical();
    1185             :     //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
    1186           0 :     const bool bVertL2R = pCnt->IsVertLR();
    1187           0 :     const sal_Bool bRTL = pCnt->IsRightToLeft();
    1188             : 
    1189           0 :     if( ( !bVert != !GetAnchorFrm()->IsVertical() ) ||
    1190           0 :         ( !bRTL !=  !GetAnchorFrm()->IsRightToLeft() ) )
    1191             :     {
    1192           0 :         if( bVert || bRTL )
    1193           0 :             aNew.setX(aNew.getX() + Frm().Width());
    1194             :         else
    1195           0 :             aNew.setX(aNew.getX() - Frm().Width());
    1196             :     }
    1197             : 
    1198           0 :     if ( pCnt->IsInDocBody() )
    1199             :     {
    1200             :         //#38848 drag from page margin into the body.
    1201           0 :         pTmpPage = pCnt->FindPageFrm();
    1202           0 :         ::lcl_PointToPrt( aNew, pTmpPage->GetUpper() );
    1203           0 :         SwRect aTmp( aNew, Size( 0, 0 ) );
    1204           0 :         pTmpPage = (SwPageFrm*)::FindPage( aTmp, pTmpPage );
    1205           0 :         ::lcl_PointToPrt( aNew, pTmpPage );
    1206             :     }
    1207             : 
    1208             :     //Setup RelPos, only invalidate if requested.
    1209             :     //rNew is an absolute position. We need to calculate the distance from rNew
    1210             :     //to the anchor inside the text flow to correctly set RelPos.
    1211             : //!!!!!We can optimize here: FindAnchor could also return RelPos!
    1212           0 :     const SwFrm *pFrm = 0;
    1213             :     SwTwips nY;
    1214           0 :     if ( pCnt->Frm().IsInside( aNew ) )
    1215             :     {
    1216             :         // #i70582#
    1217             :         const SwTwips nTopForObjPos =
    1218             :                 bVert
    1219             :                 ? ( bVertL2R
    1220           0 :                     ? ( pCnt->Frm().Left() +
    1221           0 :                         pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() )
    1222           0 :                     : ( pCnt->Frm().Left() +
    1223           0 :                         pCnt->Frm().Width() -
    1224           0 :                         pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() ) )
    1225           0 :                 : ( pCnt->Frm().Top() +
    1226           0 :                     pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() );
    1227           0 :         if( bVert )
    1228             :         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
    1229             :         {
    1230           0 :             if ( bVertL2R )
    1231           0 :                 nY = rNew.X() - nTopForObjPos;
    1232             :             else
    1233           0 :                 nY = nTopForObjPos - rNew.X() - Frm().Width();
    1234             :         }
    1235             :         else
    1236             :         {
    1237           0 :             nY = rNew.Y() - nTopForObjPos;
    1238             :         }
    1239             :     }
    1240             :     else
    1241             :     {
    1242           0 :         SwDistance aDist;
    1243           0 :         pFrm = ::lcl_CalcDownDist( aDist, aNew, pCnt );
    1244           0 :         nY = aDist.nMain + aDist.nSub;
    1245             :     }
    1246             : 
    1247           0 :     SwTwips nX = 0;
    1248             : 
    1249           0 :     if ( pCnt->IsFollow() )
    1250             :     {
    1251             :         // Flys are never attached to the follow but always to the master,
    1252             :         // which we're going to search now.
    1253           0 :         const SwCntntFrm *pOriginal = pCnt;
    1254           0 :         const SwCntntFrm *pFollow = pCnt;
    1255           0 :         while ( pCnt->IsFollow() )
    1256             :         {
    1257           0 :             do
    1258           0 :             {   pCnt = pCnt->GetPrevCntntFrm();
    1259           0 :             } while ( pCnt->GetFollow() != pFollow );
    1260           0 :             pFollow = pCnt;
    1261             :         }
    1262           0 :         SwTwips nDiff = 0;
    1263           0 :         do
    1264           0 :         {   const SwFrm *pUp = pFollow->GetUpper();
    1265           0 :             if( pUp->IsVertical() )
    1266             :             //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
    1267             :             {
    1268           0 :                 if ( pUp->IsVertLR()  )
    1269           0 :                     nDiff += pUp->Prt().Width() - pFollow->GetRelPos().getX();
    1270             :                 else
    1271           0 :                        nDiff += pFollow->Frm().Left() + pFollow->Frm().Width()
    1272           0 :                              - pUp->Frm().Left() - pUp->Prt().Left();
    1273             :             }
    1274             :             else
    1275           0 :                 nDiff += pUp->Prt().Height() - pFollow->GetRelPos().Y();
    1276           0 :             pFollow = pFollow->GetFollow();
    1277             :         } while ( pFollow != pOriginal );
    1278           0 :         nY += nDiff;
    1279           0 :         if( bVert )
    1280           0 :             nX = pCnt->Frm().Top() - pOriginal->Frm().Top();
    1281             :         else
    1282           0 :             nX = pCnt->Frm().Left() - pOriginal->Frm().Left();
    1283             :     }
    1284             : 
    1285           0 :     if ( nY == LONG_MAX )
    1286             :     {
    1287             :         // #i70582#
    1288             :         const SwTwips nTopForObjPos =
    1289             :                 bVert
    1290             :                 ? ( bVertL2R
    1291           0 :                     ? ( pCnt->Frm().Left() +
    1292           0 :                         pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() )
    1293           0 :                     : ( pCnt->Frm().Left() +
    1294           0 :                         pCnt->Frm().Width() -
    1295           0 :                         pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() ) )
    1296           0 :                 : ( pCnt->Frm().Top() +
    1297           0 :                     pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() );
    1298           0 :         if( bVert )
    1299             :         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
    1300             :         {
    1301           0 :             if ( bVertL2R )
    1302           0 :                 nY = rNew.X() - nTopForObjPos;
    1303             :             else
    1304           0 :                 nY = nTopForObjPos - rNew.X();
    1305             :         }
    1306             :         else
    1307             :         {
    1308           0 :             nY = rNew.Y() - nTopForObjPos;
    1309             :         }
    1310             :     }
    1311             : 
    1312           0 :     SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt();
    1313           0 :     const SwFmtSurround& rSurround = pFmt->GetSurround();
    1314             :     const sal_Bool bWrapThrough =
    1315           0 :         rSurround.GetSurround() == SURROUND_THROUGHT;
    1316           0 :     SwTwips nBaseOfstForFly = 0;
    1317           0 :     const SwFrm* pTmpFrm = pFrm ? pFrm : pCnt;
    1318           0 :     if ( pTmpFrm->IsTxtFrm() )
    1319             :         nBaseOfstForFly =
    1320           0 :             ((SwTxtFrm*)pTmpFrm)->GetBaseOfstForFly( !bWrapThrough );
    1321             : 
    1322           0 :     if( bVert )
    1323             :     {
    1324           0 :         if( !pFrm )
    1325           0 :             nX += rNew.Y() - pCnt->Frm().Top() - nBaseOfstForFly;
    1326             :         else
    1327           0 :             nX = rNew.Y() - pFrm->Frm().Top() - nBaseOfstForFly;
    1328             :     }
    1329             :     else
    1330             :     {
    1331           0 :         if( !pFrm )
    1332             :         {
    1333           0 :             if ( pCnt->IsRightToLeft() )
    1334           0 :                 nX += pCnt->Frm().Right() - rNew.X() - Frm().Width() +
    1335           0 :                       nBaseOfstForFly;
    1336             :             else
    1337           0 :                 nX += rNew.X() - pCnt->Frm().Left() - nBaseOfstForFly;
    1338             :         }
    1339             :         else
    1340             :         {
    1341           0 :             if ( pFrm->IsRightToLeft() )
    1342           0 :                 nX += pFrm->Frm().Right() - rNew.X() - Frm().Width() +
    1343           0 :                       nBaseOfstForFly;
    1344             :             else
    1345           0 :                 nX = rNew.X() - pFrm->Frm().Left() - nBaseOfstForFly;
    1346             :         }
    1347             :     }
    1348           0 :     GetFmt()->GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
    1349             : 
    1350           0 :     if( pCnt != GetAnchorFrm() || ( IsAutoPos() && pCnt->IsTxtFrm() &&
    1351           0 :                                   GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::HTML_MODE)) )
    1352             :     {
    1353             :         //Set the anchor attribute according to the new Cnt.
    1354           0 :         SwFmtAnchor aAnch( pFmt->GetAnchor() );
    1355           0 :         SwPosition *pPos = (SwPosition*)aAnch.GetCntntAnchor();
    1356           0 :         if( IsAutoPos() && pCnt->IsTxtFrm() )
    1357             :         {
    1358           0 :             SwCrsrMoveState eTmpState( MV_SETONLYTEXT );
    1359           0 :             Point aPt( rNew );
    1360           0 :             if( pCnt->GetCrsrOfst( pPos, aPt, &eTmpState )
    1361           0 :                 && pPos->nNode == *pCnt->GetNode() )
    1362             :             {
    1363           0 :                 if ( pCnt->GetNode()->GetTxtNode() != NULL )
    1364             :                 {
    1365             :                     const SwTxtAttr* pTxtInputFld =
    1366           0 :                         pCnt->GetNode()->GetTxtNode()->GetTxtAttrAt( pPos->nContent.GetIndex(), RES_TXTATR_INPUTFIELD, SwTxtNode::PARENT );
    1367           0 :                     if ( pTxtInputFld != NULL )
    1368             :                     {
    1369           0 :                         pPos->nContent = *(pTxtInputFld->GetStart());
    1370             :                     }
    1371             :                 }
    1372           0 :                 ResetLastCharRectHeight();
    1373           0 :                 if( text::RelOrientation::CHAR == pFmt->GetVertOrient().GetRelationOrient() )
    1374           0 :                     nY = LONG_MAX;
    1375           0 :                 if( text::RelOrientation::CHAR == pFmt->GetHoriOrient().GetRelationOrient() )
    1376           0 :                     nX = LONG_MAX;
    1377             :             }
    1378             :             else
    1379             :             {
    1380           0 :                 pPos->nNode = *pCnt->GetNode();
    1381           0 :                 pPos->nContent.Assign( pCnt->GetNode(), 0 );
    1382             :             }
    1383             :         }
    1384             :         else
    1385             :         {
    1386           0 :             pPos->nNode = *pCnt->GetNode();
    1387           0 :             pPos->nContent.Assign( pCnt->GetNode(), 0 );
    1388             :         }
    1389             : 
    1390             :         // handle change of anchor node:
    1391             :         // if count of the anchor frame also change, the fly frames have to be
    1392             :         // re-created. Thus, delete all fly frames except the <this> before the
    1393             :         // anchor attribute is change and re-create them afterwards.
    1394             :         {
    1395           0 :             SwHandleAnchorNodeChg aHandleAnchorNodeChg( *pFmt, aAnch, this );
    1396           0 :             pFmt->GetDoc()->SetAttr( aAnch, *pFmt );
    1397           0 :         }
    1398             :     }
    1399           0 :     else if ( pTmpPage && pTmpPage != GetPageFrm() )
    1400           0 :         GetPageFrm()->MoveFly( this, pTmpPage );
    1401             : 
    1402           0 :     const Point aRelPos = bVert ? Point( -nY, nX ) : Point( nX, nY );
    1403             : 
    1404           0 :     ChgRelPos( aRelPos );
    1405             : 
    1406           0 :     GetFmt()->GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
    1407             : 
    1408           0 :     if ( pOldPage != FindPageFrm() )
    1409           0 :         ::Notify_Background( GetVirtDrawObj(), pOldPage, aOld, PREP_FLY_LEAVE, sal_False );
    1410           0 : }
    1411             : 
    1412             : /** method to assure that anchored object is registered at the correct
    1413             :     page frame
    1414             : 
    1415             :     #i28701#
    1416             :     takes over functionality of deleted method <SwFlyAtCntFrm::AssertPage()>
    1417             : */
    1418        1342 : void SwFlyAtCntFrm::RegisterAtCorrectPage()
    1419             : {
    1420        1342 :     SwPageFrm* pPageFrm( 0L );
    1421        1342 :     if ( GetVertPosOrientFrm() )
    1422             :     {
    1423        1342 :         pPageFrm = const_cast<SwPageFrm*>(GetVertPosOrientFrm()->FindPageFrm());
    1424             :     }
    1425        1342 :     if ( pPageFrm && GetPageFrm() != pPageFrm )
    1426             :     {
    1427          18 :         if ( GetPageFrm() )
    1428          18 :             GetPageFrm()->MoveFly( this, pPageFrm );
    1429             :         else
    1430           0 :             pPageFrm->AppendFlyToPage( this );
    1431             :     }
    1432        1342 : }
    1433             : 
    1434             : // #i26791#
    1435        1344 : void SwFlyAtCntFrm::MakeObjPos()
    1436             : {
    1437             :     // if fly frame position is valid, nothing is to do. Thus, return
    1438        1344 :     if ( mbValidPos )
    1439             :     {
    1440           2 :         return;
    1441             :     }
    1442             : 
    1443             :     // #i26791# - validate position flag here.
    1444        1344 :     mbValidPos = sal_True;
    1445             : 
    1446             :     // #i35911# - no calculation of new position, if
    1447             :     // anchored object is marked that it clears its environment and its
    1448             :     // environment is already cleared.
    1449             :     // before checking for cleared environment
    1450             :     // check, if member <mpVertPosOrientFrm> is set.
    1451        3406 :     if ( GetVertPosOrientFrm() &&
    1452        1348 :          ClearedEnvironment() && HasClearedEnvironment() )
    1453             :     {
    1454           2 :         return;
    1455             :     }
    1456             : 
    1457             :     // use new class to position object
    1458             :     objectpositioning::SwToCntntAnchoredObjectPosition
    1459        1342 :             aObjPositioning( *GetVirtDrawObj() );
    1460        1342 :     aObjPositioning.CalcPosition();
    1461             : 
    1462        1342 :     SetVertPosOrientFrm ( aObjPositioning.GetVertPosOrientFrm() );
    1463             : }
    1464             : 
    1465             : // #i28701#
    1466        2496 : bool SwFlyAtCntFrm::_InvalidationAllowed( const InvalidationType _nInvalid ) const
    1467             : {
    1468        2496 :     bool bAllowed( SwFlyFreeFrm::_InvalidationAllowed( _nInvalid ) );
    1469             : 
    1470             :     // forbiddance of base instance can't be over ruled.
    1471        2496 :     if ( bAllowed )
    1472             :     {
    1473        2496 :         if ( _nInvalid == INVALID_POS ||
    1474             :              _nInvalid == INVALID_ALL )
    1475             :         {
    1476        1466 :             bAllowed = InvalidationOfPosAllowed();
    1477             :         }
    1478             :     }
    1479             : 
    1480        2496 :     return bAllowed;
    1481             : }
    1482             : 
    1483             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10