LCOV - code coverage report
Current view: top level - sw/source/core/layout - trvlfrm.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 667 1341 49.7 %
Date: 2014-11-03 Functions: 34 51 66.7 %
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 <hints.hxx>
      21             : #include <comphelper/flagguard.hxx>
      22             : #include <tools/line.hxx>
      23             : #include <editeng/opaqitem.hxx>
      24             : #include <editeng/protitem.hxx>
      25             : #include <vcl/settings.hxx>
      26             : #include <fmtpdsc.hxx>
      27             : #include <fmtsrnd.hxx>
      28             : #include <pagedesc.hxx>
      29             : #include <pagefrm.hxx>
      30             : #include <rootfrm.hxx>
      31             : #include <ftnfrm.hxx>
      32             : #include <flyfrm.hxx>
      33             : #include <tabfrm.hxx>
      34             : #include <rowfrm.hxx>
      35             : #include <cellfrm.hxx>
      36             : #include <txtfrm.hxx>
      37             : #include <viewopt.hxx>
      38             : #include <DocumentSettingManager.hxx>
      39             : #include <viscrs.hxx>
      40             : #include <dflyobj.hxx>
      41             : #include <crstate.hxx>
      42             : #include <dcontact.hxx>
      43             : #include <sortedobjs.hxx>
      44             : #include <txatbase.hxx>
      45             : #include <fmtfld.hxx>
      46             : #include <fldbas.hxx>
      47             : 
      48             : #include <cfloat>
      49             : #include <swselectionlist.hxx>
      50             : 
      51             : namespace {
      52          20 :     bool lcl_GetCrsrOfst_Objects( const SwPageFrm* pPageFrm, bool bSearchBackground,
      53             :            SwPosition *pPos, Point& rPoint, SwCrsrMoveState* pCMS  )
      54             :     {
      55          20 :         bool bRet = false;
      56          20 :         Point aPoint( rPoint );
      57          20 :         SwOrderIter aIter( pPageFrm );
      58          20 :         aIter.Top();
      59          68 :         while ( aIter() )
      60             :         {
      61             :             const SwVirtFlyDrawObj* pObj =
      62          28 :                                 static_cast<const SwVirtFlyDrawObj*>(aIter());
      63          28 :             const SwAnchoredObject* pAnchoredObj = GetUserCall( aIter() )->GetAnchoredObj( aIter() );
      64          28 :             const SwFmtSurround& rSurround = pAnchoredObj->GetFrmFmt().GetSurround();
      65          28 :             const SvxOpaqueItem& rOpaque = pAnchoredObj->GetFrmFmt().GetOpaque();
      66          28 :             bool bInBackground = ( rSurround.GetSurround() == SURROUND_THROUGHT ) && !rOpaque.GetValue();
      67             : 
      68          70 :             bool bBackgroundMatches = ( bInBackground && bSearchBackground ) ||
      69          84 :                                       ( !bInBackground && !bSearchBackground );
      70             : 
      71          28 :             const SwFlyFrm* pFly = pObj ? pObj->GetFlyFrm() : 0;
      72          56 :             if ( pFly && bBackgroundMatches &&
      73          14 :                  ( ( pCMS && pCMS->bSetInReadOnly ) ||
      74          42 :                    !pFly->IsProtected() ) &&
      75          14 :                  pFly->GetCrsrOfst( pPos, aPoint, pCMS ) )
      76             :             {
      77           0 :                 bRet = true;
      78           0 :                 break;
      79             :             }
      80             : 
      81          28 :             if ( pCMS && pCMS->bStop )
      82           0 :                 return false;
      83          28 :             aIter.Prev();
      84             :         }
      85          20 :         return bRet;
      86             :     }
      87             : 
      88           0 :     double lcl_getDistance( const SwRect& rRect, const Point& rPoint )
      89             :     {
      90           0 :         double nDist = 0.0;
      91             : 
      92             :         // If the point is inside the rectangle, then distance is 0
      93             :         // Otherwise, compute the distance to the center of the rectangle.
      94           0 :         if ( !rRect.IsInside( rPoint ) )
      95             :         {
      96           0 :             Line aLine( rPoint, rRect.Center( ) );
      97           0 :             nDist = aLine.GetLength( );
      98             :         }
      99             : 
     100           0 :         return nDist;
     101             :     }
     102             : }
     103             : 
     104             : //For SwFlyFrm::GetCrsrOfst
     105             : class SwCrsrOszControl
     106             : {
     107             : public:
     108             :     // So the compiler can initialize the class already. No DTOR and member
     109             :     // as public members
     110             :     const SwFlyFrm *pEntry;
     111             :     const SwFlyFrm *pStk1;
     112             :     const SwFlyFrm *pStk2;
     113             : 
     114           0 :     bool ChkOsz( const SwFlyFrm *pFly )
     115             :         {
     116           0 :             bool bRet = true;
     117           0 :             if ( pFly != pStk1 && pFly != pStk2 )
     118             :             {
     119           0 :                 pStk1 = pStk2;
     120           0 :                 pStk2 = pFly;
     121           0 :                 bRet  = false;
     122             :             }
     123           0 :             return bRet;
     124             :         }
     125             : 
     126          14 :     void Entry( const SwFlyFrm *pFly )
     127             :         {
     128          14 :             if ( !pEntry )
     129          14 :                 pEntry = pStk1 = pFly;
     130          14 :         }
     131             : 
     132          14 :     void Exit( const SwFlyFrm *pFly )
     133             :         {
     134          14 :             if ( pFly == pEntry )
     135          14 :                 pEntry = pStk1 = pStk2 = 0;
     136          14 :         }
     137             : };
     138             : 
     139             : static SwCrsrOszControl aOszCtrl = { 0, 0, 0 };
     140             : 
     141             : /** Searches the CntntFrm owning the PrtArea containing the point. */
     142        1044 : bool SwLayoutFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint,
     143             :                                SwCrsrMoveState* pCMS, bool ) const
     144             : {
     145        1044 :     bool bRet = false;
     146        1044 :     const SwFrm *pFrm = Lower();
     147        3140 :     while ( !bRet && pFrm )
     148             :     {
     149        1052 :         pFrm->Calc();
     150             : 
     151             :         // #i43742# New function
     152        1052 :         const bool bCntntCheck = pFrm->IsTxtFrm() && pCMS && pCMS->bCntntCheck;
     153             :         const SwRect aPaintRect( bCntntCheck ?
     154             :                                  pFrm->UnionFrm() :
     155        1052 :                                  pFrm->PaintArea() );
     156             : 
     157        1484 :         if ( aPaintRect.IsInside( rPoint ) &&
     158         735 :              ( bCntntCheck || pFrm->GetCrsrOfst( pPos, rPoint, pCMS ) ) )
     159         432 :             bRet = true;
     160             :         else
     161         620 :             pFrm = pFrm->GetNext();
     162        1052 :         if ( pCMS && pCMS->bStop )
     163           0 :             return false;
     164             :     }
     165        1044 :     return bRet;
     166             : }
     167             : 
     168             : /** Searches the page containing the searched point. */
     169             : 
     170         529 : bool SwPageFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint,
     171             :                              SwCrsrMoveState* pCMS, bool bTestBackground ) const
     172             : {
     173         529 :     bool bRet = false;
     174         529 :     Point aPoint( rPoint );
     175             : 
     176             :     // check, if we have to adjust the point
     177         529 :     if ( !Frm().IsInside( aPoint ) )
     178             :     {
     179           0 :         aPoint.X() = std::max( aPoint.X(), Frm().Left() );
     180           0 :         aPoint.X() = std::min( aPoint.X(), Frm().Right() );
     181           0 :         aPoint.Y() = std::max( aPoint.Y(), Frm().Top() );
     182           0 :         aPoint.Y() = std::min( aPoint.Y(), Frm().Bottom() );
     183             :     }
     184             : 
     185         529 :     bool bTextRet = false;
     186         529 :     bool bBackRet = false;
     187             : 
     188             :     //Could it be a free flying one?
     189             :     //If his content should be protected, we can't set the Crsr in it, thus
     190             :     //all changes should be impossible.
     191         529 :     if ( GetSortedObjs() )
     192             :     {
     193          10 :         bRet = lcl_GetCrsrOfst_Objects( this, false, pPos, rPoint, pCMS );
     194             :     }
     195             : 
     196         529 :     if ( !bRet )
     197             :     {
     198         529 :         SwPosition aBackPos( *pPos );
     199        1054 :         SwPosition aTextPos( *pPos );
     200             : 
     201             :         //We fix the StartPoint if no Cntnt below the page 'answers' and then
     202             :         //start all over again one page before the current one.
     203             :         //However we can't use Flys in such a case.
     204         529 :         if ( SwLayoutFrm::GetCrsrOfst( &aTextPos, aPoint, pCMS ) )
     205             :         {
     206         216 :             bTextRet = true;
     207             :         }
     208             :         else
     209             :         {
     210         313 :             if ( pCMS && (pCMS->bStop || pCMS->bExactOnly) )
     211             :             {
     212           4 :                 ((SwCrsrMoveState*)pCMS)->bStop = true;
     213           4 :                 return false;
     214             :             }
     215         309 :             const SwCntntFrm *pCnt = GetCntntPos( aPoint, false, false, false, pCMS, false );
     216         309 :             if ( pCMS && pCMS->bStop )
     217           0 :                 return false;
     218             : 
     219             :             OSL_ENSURE( pCnt, "Crsr is gone to a Black hole" );
     220         309 :             if( pCMS && pCMS->pFill && pCnt->IsTxtFrm() )
     221           0 :                 bTextRet = pCnt->GetCrsrOfst( &aTextPos, rPoint, pCMS );
     222             :             else
     223         309 :                 bTextRet = pCnt->GetCrsrOfst( &aTextPos, aPoint, pCMS );
     224             : 
     225         309 :             if ( !bTextRet )
     226             :             {
     227             :                 // Set point to pCnt, delete mark
     228             :                 // this may happen, if pCnt is hidden
     229          57 :                 aTextPos = SwPosition( *pCnt->GetNode(), SwIndex( (SwTxtNode*)pCnt->GetNode(), 0 ) );
     230          57 :                 bTextRet = true;
     231             :             }
     232             :         }
     233             : 
     234         525 :         SwCntntNode* pTextNd = aTextPos.nNode.GetNode( ).GetCntntNode( );
     235         525 :         bool bConsiderBackground = true;
     236             :         // If the text position is a clickable field, then that should have priority.
     237         525 :         if (pTextNd && pTextNd->IsTxtNode())
     238             :         {
     239         525 :             SwTxtNode* pTxtNd = pTextNd->GetTxtNode();
     240         525 :             SwTxtAttr* pTxtAttr = pTxtNd->GetTxtAttrForCharAt(aTextPos.nContent.GetIndex(), RES_TXTATR_FIELD);
     241         525 :             if (pTxtAttr)
     242             :             {
     243           0 :                 const SwField* pField = pTxtAttr->GetFmtFld().GetField();
     244           0 :                 if (pField->IsClickable())
     245           0 :                     bConsiderBackground = false;
     246             :             }
     247             :         }
     248             : 
     249             :         // Check objects in the background if nothing else matched
     250         525 :         if ( GetSortedObjs() )
     251             :         {
     252          10 :             bBackRet = lcl_GetCrsrOfst_Objects( this, true, &aBackPos, rPoint, pCMS );
     253             :         }
     254             : 
     255         525 :         if ( ( bConsiderBackground && bTestBackground && bBackRet ) || !bTextRet )
     256             :         {
     257           0 :             bRet = bBackRet;
     258           0 :             (*pPos) = aBackPos;
     259             :         }
     260         525 :         else if (bTextRet && !bBackRet)
     261             :         {
     262         525 :             bRet = bTextRet;
     263         525 :             (*pPos) = aTextPos;
     264             :         }
     265             :         else
     266             :         {
     267             :             /* In order to provide a selection as accurable as possible when we have both
     268             :              * text and brackground object, then we compute the distance between both
     269             :              * would-be positions and the click point. The shortest distance wins.
     270             :              */
     271           0 :             double nTextDistance = 0;
     272           0 :             bool bValidTextDistance = false;
     273           0 :             if ( pTextNd )
     274             :             {
     275           0 :                 SwCntntFrm* pTextFrm = pTextNd->getLayoutFrm( getRootFrm( ) );
     276             : 
     277             :                 // try this again but prefer the "previous" position
     278           0 :                 SwCrsrMoveState aMoveState;
     279           0 :                 SwCrsrMoveState *const pState((pCMS) ? pCMS : &aMoveState);
     280             :                 comphelper::FlagRestorationGuard g(
     281           0 :                         pState->bPosMatchesBounds, true);
     282           0 :                 SwPosition prevTextPos(*pPos);
     283           0 :                 SwLayoutFrm::GetCrsrOfst(&prevTextPos, aPoint, pState);
     284             : 
     285           0 :                 SwRect aTextRect;
     286           0 :                 pTextFrm->GetCharRect(aTextRect, prevTextPos);
     287             : 
     288           0 :                 if (prevTextPos.nContent < pTextNd->Len())
     289             :                 {
     290             :                     // aRextRect is just a line on the left edge of the
     291             :                     // previous character; to get a better measure from
     292             :                     // lcl_getDistance, extend that to a rectangle over
     293             :                     // the entire character.
     294             :                     SwPosition const nextTextPos(prevTextPos.nNode,
     295           0 :                             SwIndex(prevTextPos.nContent, +1));
     296           0 :                     SwRect nextTextRect;
     297           0 :                     pTextFrm->GetCharRect(nextTextRect, nextTextPos);
     298           0 :                     SWRECTFN(pTextFrm);
     299           0 :                     if ((aTextRect.*fnRect->fnGetTop)() ==
     300           0 :                         (nextTextRect.*fnRect->fnGetTop)()) // same line?
     301             :                     {
     302             :                         // need to handle mixed RTL/LTR portions somehow
     303           0 :                         if ((aTextRect.*fnRect->fnGetLeft)() <
     304           0 :                             (nextTextRect.*fnRect->fnGetLeft)())
     305             :                         {
     306             :                             (aTextRect.*fnRect->fnSetRight)(
     307           0 :                                     (nextTextRect.*fnRect->fnGetLeft)());
     308             :                         }
     309             :                         else // RTL
     310             :                         {
     311             :                             (aTextRect.*fnRect->fnSetLeft)(
     312           0 :                                     (nextTextRect.*fnRect->fnGetLeft)());
     313             :                         }
     314           0 :                     }
     315             :                 }
     316             : 
     317           0 :                 nTextDistance = lcl_getDistance(aTextRect, rPoint);
     318           0 :                 bValidTextDistance = true;
     319             :             }
     320             : 
     321           0 :             double nBackDistance = 0;
     322           0 :             bool bValidBackDistance = false;
     323           0 :             SwCntntNode* pBackNd = aBackPos.nNode.GetNode( ).GetCntntNode( );
     324           0 :             if ( pBackNd && bConsiderBackground)
     325             :             {
     326             :                 // FIXME There are still cases were we don't have the proper node here.
     327           0 :                 SwCntntFrm* pBackFrm = pBackNd->getLayoutFrm( getRootFrm( ) );
     328           0 :                 SwRect rBackRect;
     329           0 :                 if (pBackFrm)
     330             :                 {
     331           0 :                     pBackFrm->GetCharRect( rBackRect, aBackPos );
     332             : 
     333           0 :                     nBackDistance = lcl_getDistance( rBackRect, rPoint );
     334           0 :                     bValidBackDistance = true;
     335             :                 }
     336             :             }
     337             : 
     338           0 :             if ( bValidTextDistance && bValidBackDistance && basegfx::fTools::more( nTextDistance, nBackDistance ) )
     339             :             {
     340           0 :                 bRet = bBackRet;
     341           0 :                 (*pPos) = aBackPos;
     342             :             }
     343             :             else
     344             :             {
     345           0 :                 bRet = bTextRet;
     346           0 :                 (*pPos) = aTextPos;
     347             :             }
     348         525 :         }
     349             :     }
     350             : 
     351         525 :     if ( bRet )
     352         525 :         rPoint = aPoint;
     353             : 
     354         525 :     return bRet;
     355             : }
     356             : 
     357           0 : bool SwLayoutFrm::FillSelection( SwSelectionList& rList, const SwRect& rRect ) const
     358             : {
     359           0 :     bool bRet = false;
     360           0 :     if( rRect.IsOver(PaintArea()) )
     361             :     {
     362           0 :         const SwFrm* pFrm = Lower();
     363           0 :         while( pFrm )
     364             :         {
     365           0 :             pFrm->FillSelection( rList, rRect );
     366           0 :             pFrm = pFrm->GetNext();
     367             :         }
     368             :     }
     369           0 :     return bRet;
     370             : }
     371             : 
     372           0 : bool SwPageFrm::FillSelection( SwSelectionList& rList, const SwRect& rRect ) const
     373             : {
     374           0 :     bool bRet = false;
     375           0 :     if( rRect.IsOver(PaintArea()) )
     376             :     {
     377           0 :         bRet = SwLayoutFrm::FillSelection( rList, rRect );
     378           0 :         if( GetSortedObjs() )
     379             :         {
     380           0 :             const SwSortedObjs &rObjs = *GetSortedObjs();
     381           0 :             for ( size_t i = 0; i < rObjs.size(); ++i )
     382             :             {
     383           0 :                 const SwAnchoredObject* pAnchoredObj = rObjs[i];
     384           0 :                 if( !pAnchoredObj->ISA(SwFlyFrm) )
     385           0 :                     continue;
     386           0 :                 const SwFlyFrm* pFly = static_cast<const SwFlyFrm*>(pAnchoredObj);
     387           0 :                 if( pFly->FillSelection( rList, rRect ) )
     388           0 :                     bRet = true;
     389             :             }
     390             :         }
     391             :     }
     392           0 :     return bRet;
     393             : }
     394             : 
     395           0 : bool SwRootFrm::FillSelection( SwSelectionList& aSelList, const SwRect& rRect) const
     396             : {
     397           0 :     const SwFrm *pPage = Lower();
     398           0 :     const long nBottom = rRect.Bottom();
     399           0 :     while( pPage )
     400             :     {
     401           0 :         if( pPage->Frm().Top() < nBottom )
     402             :         {
     403           0 :             if( pPage->Frm().Bottom() > rRect.Top() )
     404           0 :                 pPage->FillSelection( aSelList, rRect );
     405           0 :             pPage = pPage->GetNext();
     406             :         }
     407             :         else
     408           0 :             pPage = 0;
     409             :     }
     410           0 :     return !aSelList.isEmpty();
     411             : }
     412             : 
     413             : /** Primary passes the call to the first page.
     414             :  *
     415             :  *  @return false, if the passed Point gets changed
     416             :  */
     417         529 : bool SwRootFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint,
     418             :                              SwCrsrMoveState* pCMS, bool bTestBackground ) const
     419             : {
     420         529 :     const bool bOldAction = IsCallbackActionEnabled();
     421         529 :     ((SwRootFrm*)this)->SetCallbackActionEnabled( false );
     422             :     OSL_ENSURE( (Lower() && Lower()->IsPageFrm()), "No PageFrm found." );
     423         529 :     if( pCMS && pCMS->pFill )
     424           0 :         ((SwCrsrMoveState*)pCMS)->bFillRet = false;
     425         529 :     Point aOldPoint = rPoint;
     426             : 
     427             :     // search for page containing rPoint. The borders around the pages are considerd
     428         529 :     const SwPageFrm* pPage = GetPageAtPos( rPoint, 0, true );
     429             : 
     430             :     // #i95626#
     431             :     // special handling for <rPoint> beyond root frames area
     432         529 :     if ( !pPage &&
     433         529 :          rPoint.X() > Frm().Right() &&
     434           0 :          rPoint.Y() > Frm().Bottom() )
     435             :     {
     436           0 :         pPage = dynamic_cast<const SwPageFrm*>(Lower());
     437           0 :         while ( pPage && pPage->GetNext() )
     438             :         {
     439           0 :             pPage = dynamic_cast<const SwPageFrm*>(pPage->GetNext());
     440             :         }
     441             :     }
     442         529 :     if ( pPage )
     443             :     {
     444         529 :         pPage->SwPageFrm::GetCrsrOfst( pPos, rPoint, pCMS, bTestBackground );
     445             :     }
     446             : 
     447         529 :     ((SwRootFrm*)this)->SetCallbackActionEnabled( bOldAction );
     448         529 :     if( pCMS )
     449             :     {
     450         529 :         if( pCMS->bStop )
     451           4 :             return false;
     452         525 :         if( pCMS->pFill )
     453           0 :             return pCMS->bFillRet;
     454             :     }
     455         525 :     return aOldPoint == rPoint;
     456             : }
     457             : 
     458             : /**
     459             :  * If this is about a Cntnt-carrying cell the Crsr will be force inserted into one of the CntntFrms
     460             :  * if there are no other options.
     461             :  *
     462             :  * There is no entry for protected cells.
     463             :  */
     464           0 : bool SwCellFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint,
     465             :                              SwCrsrMoveState* pCMS, bool ) const
     466             : {
     467             :     // cell frame does not necessarily have a lower (split table cell)
     468           0 :     if ( !Lower() )
     469           0 :         return false;
     470             : 
     471           0 :     if ( !(pCMS && pCMS->bSetInReadOnly) &&
     472           0 :          GetFmt()->GetProtect().IsCntntProtected() )
     473           0 :         return false;
     474             : 
     475           0 :     if ( pCMS && pCMS->eState == MV_TBLSEL )
     476             :     {
     477           0 :         const SwTabFrm *pTab = FindTabFrm();
     478           0 :         if ( pTab->IsFollow() && pTab->IsInHeadline( *this ) )
     479             :         {
     480           0 :             ((SwCrsrMoveState*)pCMS)->bStop = true;
     481           0 :             return false;
     482             :         }
     483             :     }
     484             : 
     485           0 :     if ( Lower() )
     486             :     {
     487           0 :         if ( Lower()->IsLayoutFrm() )
     488           0 :             return SwLayoutFrm::GetCrsrOfst( pPos, rPoint, pCMS );
     489             :         else
     490             :         {
     491           0 :             Calc();
     492           0 :             bool bRet = false;
     493             : 
     494           0 :             const SwFrm *pFrm = Lower();
     495           0 :             while ( pFrm && !bRet )
     496             :             {
     497           0 :                 pFrm->Calc();
     498           0 :                 if ( pFrm->Frm().IsInside( rPoint ) )
     499             :                 {
     500           0 :                     bRet = pFrm->GetCrsrOfst( pPos, rPoint, pCMS );
     501           0 :                     if ( pCMS && pCMS->bStop )
     502           0 :                         return false;
     503             :                 }
     504           0 :                 pFrm = pFrm->GetNext();
     505             :             }
     506           0 :             if ( !bRet )
     507             :             {
     508           0 :                 const bool bFill = pCMS && pCMS->pFill;
     509           0 :                 Point aPoint( rPoint );
     510           0 :                 const SwCntntFrm *pCnt = GetCntntPos( rPoint, true );
     511           0 :                 if( bFill && pCnt->IsTxtFrm() )
     512             :                 {
     513           0 :                     rPoint = aPoint;
     514             :                 }
     515           0 :                 pCnt->GetCrsrOfst( pPos, rPoint, pCMS );
     516             :             }
     517           0 :             return true;
     518             :         }
     519             :     }
     520             : 
     521           0 :     return false;
     522             : }
     523             : 
     524             : //Problem: If two Flys have the same size and share the same position then
     525             : //they end inside each other.
     526             : //Because we recursively check if a Point doesn't randomly lie inside an other
     527             : //fly which lies completely inside the current Fly we could trigger an endless
     528             : //loop with the mentioned situation above.
     529             : //Using the helper class SwCrsrOszControl we prevent the recursion. During
     530             : //a recursion GetCrsrOfst picks the one which lies on top.
     531          14 : bool SwFlyFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint,
     532             :                             SwCrsrMoveState* pCMS, bool ) const
     533             : {
     534          14 :     aOszCtrl.Entry( this );
     535             : 
     536             :     //If the Points lies inside the Fly, we try hard to set the Crsr inside it.
     537             :     //However if the Point sits inside a Fly which is completely located inside
     538             :     //the current one, we call GetCrsrOfst for it.
     539          14 :     Calc();
     540          14 :     bool bInside = Frm().IsInside( rPoint ) && Lower();
     541          14 :     bool bRet = false;
     542             : 
     543             :     //If an Frm contains a graphic, but only text was requested, it basically
     544             :     //won't accept the Crsr.
     545          14 :     if ( bInside && pCMS && pCMS->eState == MV_SETONLYTEXT &&
     546           0 :          (!Lower() || Lower()->IsNoTxtFrm()) )
     547           0 :         bInside = false;
     548             : 
     549          14 :     const SwPageFrm *pPage = FindPageFrm();
     550          14 :     if ( bInside && pPage && pPage->GetSortedObjs() )
     551             :     {
     552           0 :         SwOrderIter aIter( pPage );
     553           0 :         aIter.Top();
     554           0 :         while ( aIter() && !bRet )
     555             :         {
     556           0 :             const SwVirtFlyDrawObj* pObj = static_cast<const SwVirtFlyDrawObj*>(aIter());
     557           0 :             const SwFlyFrm* pFly = pObj ? pObj->GetFlyFrm() : 0;
     558           0 :             if ( pFly && pFly->Frm().IsInside( rPoint ) &&
     559           0 :                  Frm().IsInside( pFly->Frm() ) )
     560             :             {
     561           0 :                 if ( aOszCtrl.ChkOsz( pFly ) )
     562           0 :                     break;
     563           0 :                 bRet = pFly->GetCrsrOfst( pPos, rPoint, pCMS );
     564           0 :                 if ( bRet )
     565           0 :                     break;
     566           0 :                 if ( pCMS && pCMS->bStop )
     567           0 :                     return false;
     568             :             }
     569           0 :             aIter.Next();
     570             :         }
     571             :     }
     572             : 
     573          28 :     while ( bInside && !bRet )
     574             :     {
     575           0 :         const SwFrm *pFrm = Lower();
     576           0 :         while ( pFrm && !bRet )
     577             :         {
     578           0 :             pFrm->Calc();
     579           0 :             if ( pFrm->Frm().IsInside( rPoint ) )
     580             :             {
     581           0 :                 bRet = pFrm->GetCrsrOfst( pPos, rPoint, pCMS );
     582           0 :                 if ( pCMS && pCMS->bStop )
     583           0 :                     return false;
     584             :             }
     585           0 :             pFrm = pFrm->GetNext();
     586             :         }
     587           0 :         if ( !bRet )
     588             :         {
     589           0 :             const bool bFill = pCMS && pCMS->pFill;
     590           0 :             Point aPoint( rPoint );
     591           0 :             const SwCntntFrm *pCnt = GetCntntPos( rPoint, true, false, false, pCMS );
     592           0 :             if ( pCMS && pCMS->bStop )
     593           0 :                 return false;
     594           0 :             if( bFill && pCnt->IsTxtFrm() )
     595             :             {
     596           0 :                 rPoint = aPoint;
     597             :             }
     598           0 :             pCnt->GetCrsrOfst( pPos, rPoint, pCMS );
     599           0 :             bRet = true;
     600             :         }
     601             :     }
     602          14 :     aOszCtrl.Exit( this );
     603          14 :     return bRet;
     604             : }
     605             : 
     606             : /** Layout dependent cursor travelling */
     607           0 : bool SwCntntFrm::LeftMargin(SwPaM *pPam) const
     608             : {
     609           0 :     if( &pPam->GetNode() != (SwCntntNode*)GetNode() )
     610           0 :         return false;
     611           0 :     ((SwCntntNode*)GetNode())->
     612           0 :         MakeStartIndex((SwIndex *) &pPam->GetPoint()->nContent);
     613           0 :     return true;
     614             : }
     615             : 
     616           0 : bool SwCntntFrm::RightMargin(SwPaM *pPam, bool) const
     617             : {
     618           0 :     if( &pPam->GetNode() != (SwCntntNode*)GetNode() )
     619           0 :         return false;
     620           0 :     ((SwCntntNode*)GetNode())->
     621           0 :         MakeEndIndex((SwIndex *) &pPam->GetPoint()->nContent);
     622           0 :     return true;
     623             : }
     624             : 
     625           4 : static const SwCntntFrm *lcl_GetNxtCnt( const SwCntntFrm* pCnt )
     626             : {
     627           4 :     return pCnt->GetNextCntntFrm();
     628             : }
     629             : 
     630           8 : static const SwCntntFrm *lcl_GetPrvCnt( const SwCntntFrm* pCnt )
     631             : {
     632           8 :     return pCnt->GetPrevCntntFrm();
     633             : }
     634             : 
     635             : typedef const SwCntntFrm *(*GetNxtPrvCnt)( const SwCntntFrm* );
     636             : 
     637             : /// Frame in repeated headline?
     638          12 : static bool lcl_IsInRepeatedHeadline( const SwFrm *pFrm,
     639             :                                     const SwTabFrm** ppTFrm = 0 )
     640             : {
     641          12 :     const SwTabFrm *pTab = pFrm->FindTabFrm();
     642          12 :     if( ppTFrm )
     643           0 :         *ppTFrm = pTab;
     644          12 :     return pTab && pTab->IsFollow() && pTab->IsInHeadline( *pFrm );
     645             : }
     646             : 
     647             : /// Skip protected table cells. Optionally also skip repeated headlines.
     648             : //MA 1998-01-26: Chg also skip other protected areas
     649             : //FME: Skip follow flow cells
     650         447 : static const SwCntntFrm * lcl_MissProtectedFrames( const SwCntntFrm *pCnt,
     651             :                                                    GetNxtPrvCnt fnNxtPrv,
     652             :                                                    bool bMissHeadline,
     653             :                                                    bool bInReadOnly,
     654             :                                                    bool bMissFollowFlowLine )
     655             : {
     656         447 :     if ( pCnt && pCnt->IsInTab() )
     657             :     {
     658         116 :         bool bProtect = true;
     659         348 :         while ( pCnt && bProtect )
     660             :         {
     661         116 :             const SwLayoutFrm *pCell = pCnt->GetUpper();
     662         232 :             while ( pCell && !pCell->IsCellFrm() )
     663           0 :                 pCell = pCell->GetUpper();
     664         232 :             if ( !pCell ||
     665         116 :                     (( ( bInReadOnly || !pCell->GetFmt()->GetProtect().IsCntntProtected() ) &&
     666         244 :                       ( !bMissHeadline || !lcl_IsInRepeatedHeadline( pCell ) ) &&
     667         232 :                       ( !bMissFollowFlowLine || !pCell->IsInFollowFlowRow() ) &&
     668         116 :                        !pCell->IsCoveredCell()) ) )
     669         116 :                 bProtect = false;
     670             :             else
     671           0 :                 pCnt = (*fnNxtPrv)( pCnt );
     672             :         }
     673             :     }
     674         331 :     else if ( !bInReadOnly )
     675         496 :         while ( pCnt && pCnt->IsProtected() )
     676           0 :             pCnt = (*fnNxtPrv)( pCnt );
     677             : 
     678         447 :     return pCnt;
     679             : }
     680             : 
     681           6 : static bool lcl_UpDown( SwPaM *pPam, const SwCntntFrm *pStart,
     682             :                     GetNxtPrvCnt fnNxtPrv, bool bInReadOnly )
     683             : {
     684             :     OSL_ENSURE( &pPam->GetNode() == (SwCntntNode*)pStart->GetNode(),
     685             :             "lcl_UpDown doesn't work for others." );
     686             : 
     687           6 :     const SwCntntFrm *pCnt = 0;
     688             : 
     689             :     //We have to cheat a little bit during a table selection: Go to the
     690             :     //beginning of the cell while going up and go to the end of the cell while
     691             :     //going down.
     692           6 :     bool bTblSel = false;
     693          12 :     if ( pStart->IsInTab() &&
     694           6 :         pPam->GetNode( true ).StartOfSectionNode() !=
     695           6 :         pPam->GetNode( false ).StartOfSectionNode() )
     696             :     {
     697           0 :         bTblSel = true;
     698           0 :         const SwLayoutFrm  *pCell = pStart->GetUpper();
     699           0 :         while ( !pCell->IsCellFrm() )
     700           0 :             pCell = pCell->GetUpper();
     701             : 
     702             :         // Check, if cell has a Prev/Follow cell:
     703           0 :         const bool bFwd = ( fnNxtPrv == lcl_GetNxtCnt );
     704             :         const SwLayoutFrm* pTmpCell = bFwd ?
     705             :             ((SwCellFrm*)pCell)->GetFollowCell() :
     706           0 :             ((SwCellFrm*)pCell)->GetPreviousCell();
     707             : 
     708           0 :         const SwCntntFrm* pTmpStart = pStart;
     709           0 :         while ( pTmpCell && 0 != ( pTmpStart = pTmpCell->ContainsCntnt() ) )
     710             :         {
     711           0 :             pCell = pTmpCell;
     712             :             pTmpCell = bFwd ?
     713             :                 ((SwCellFrm*)pCell)->GetFollowCell() :
     714           0 :                 ((SwCellFrm*)pCell)->GetPreviousCell();
     715             :         }
     716           0 :         const SwCntntFrm *pNxt = pCnt = pTmpStart;
     717             : 
     718           0 :         while ( pCell->IsAnLower( pNxt ) )
     719             :         {
     720           0 :             pCnt = pNxt;
     721           0 :             pNxt = (*fnNxtPrv)( pNxt );
     722             :         }
     723             :     }
     724             : 
     725           6 :     pCnt = (*fnNxtPrv)( pCnt ? pCnt : pStart );
     726           6 :     pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, true, bInReadOnly, bTblSel );
     727             : 
     728           6 :     const SwTabFrm *pStTab = pStart->FindTabFrm();
     729           6 :     const SwTabFrm *pTable = 0;
     730           6 :     const bool bTab = pStTab || (pCnt && pCnt->IsInTab());
     731           6 :     bool bEnd = !bTab;
     732             : 
     733           6 :     const SwFrm* pVertRefFrm = pStart;
     734           6 :     if ( bTblSel && pStTab )
     735           0 :         pVertRefFrm = pStTab;
     736           6 :     SWRECTFN( pVertRefFrm )
     737             : 
     738           6 :     SwTwips nX = 0;
     739           6 :     if ( bTab )
     740             :     {
     741             :         // pStart or pCnt is inside a table. nX will be used for travelling:
     742           6 :         SwRect aRect( pStart->Frm() );
     743           6 :         pStart->GetCharRect( aRect, *pPam->GetPoint() );
     744           6 :         Point aCenter = aRect.Center();
     745           6 :         nX = bVert ? aCenter.Y() : aCenter.X();
     746             : 
     747           6 :         pTable = pCnt ? pCnt->FindTabFrm() : 0;
     748           6 :         if ( !pTable )
     749           0 :             pTable = pStTab;
     750             : 
     751          12 :         if ( pStTab &&
     752          12 :             !pStTab->GetUpper()->IsInTab() &&
     753           6 :             !pTable->GetUpper()->IsInTab() )
     754             :         {
     755           6 :             const SwFrm *pCell = pStart->GetUpper();
     756          12 :             while ( pCell && !pCell->IsCellFrm() )
     757           0 :                 pCell = pCell->GetUpper();
     758             :             OSL_ENSURE( pCell, "could not find the cell" );
     759           6 :             nX =  (pCell->Frm().*fnRect->fnGetLeft)() +
     760           6 :                   (pCell->Frm().*fnRect->fnGetWidth)() / 2;
     761             : 
     762             :             //The flow leads from one table to the next. The X-value needs to be
     763             :             //corrected based on the middle of the starting cell by the amount
     764             :             //of the offset of the tables.
     765           6 :             if ( pStTab != pTable )
     766             :             {
     767           0 :                 nX += (pTable->Frm().*fnRect->fnGetLeft)() -
     768           0 :                       (pStTab->Frm().*fnRect->fnGetLeft)();
     769             :             }
     770             :         }
     771             : 
     772             :         // Restrict nX to the left and right borders of pTab:
     773             :         // (is this really necessary?)
     774           6 :         if ( !pTable->GetUpper()->IsInTab() )
     775             :         {
     776           6 :             const bool bRTL = pTable->IsRightToLeft();
     777             :             const long nPrtLeft = bRTL ?
     778           0 :                                 (pTable->*fnRect->fnGetPrtRight)() :
     779           6 :                                 (pTable->*fnRect->fnGetPrtLeft)();
     780           6 :             if ( bRTL != (nX < nPrtLeft) )
     781           0 :                 nX = nPrtLeft;
     782             :             else
     783             :             {
     784             :                    const long nPrtRight = bRTL ?
     785           0 :                                     (pTable->*fnRect->fnGetPrtLeft)() :
     786           6 :                                     (pTable->*fnRect->fnGetPrtRight)();
     787           6 :                 if ( bRTL != (nX > nPrtRight) )
     788           0 :                     nX = nPrtRight;
     789             :             }
     790             :         }
     791             :     }
     792             : 
     793          12 :     do
     794             :     {
     795             :         //If I'm in the DocumentBody, I wan't to stay there.
     796          12 :         if ( pStart->IsInDocBody() )
     797             :         {
     798          36 :             while ( pCnt && (!pCnt->IsInDocBody() ||
     799          24 :                              (pCnt->IsTxtFrm() && ((SwTxtFrm*)pCnt)->IsHiddenNow())))
     800             :             {
     801           0 :                 pCnt = (*fnNxtPrv)( pCnt );
     802           0 :                 pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, true, bInReadOnly, bTblSel );
     803             :             }
     804             :         }
     805             : 
     806             :         //If I'm in the FootNoteArea, I try to reach the next FootNoteArea in
     807             :         //case of necessity.
     808           0 :         else if ( pStart->IsInFtn() )
     809             :         {
     810           0 :             while ( pCnt && (!pCnt->IsInFtn() ||
     811           0 :                             (pCnt->IsTxtFrm() && ((SwTxtFrm*)pCnt)->IsHiddenNow())))
     812             :             {
     813           0 :                 pCnt = (*fnNxtPrv)( pCnt );
     814           0 :                 pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, true, bInReadOnly, bTblSel );
     815             :             }
     816             :         }
     817             : 
     818             :         //In Flys we can go ahead blindly as long as we find a Cntnt.
     819           0 :         else if ( pStart->IsInFly() )
     820             :         {
     821           0 :             if ( pCnt && pCnt->IsTxtFrm() && ((SwTxtFrm*)pCnt)->IsHiddenNow() )
     822             :             {
     823           0 :                 pCnt = (*fnNxtPrv)( pCnt );
     824           0 :                 pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, true, bInReadOnly, bTblSel );
     825             :             }
     826             :         }
     827             : 
     828             :         //Otherwise I'll just refuse to leave to current area.
     829           0 :         else if ( pCnt )
     830             :         {
     831           0 :             const SwFrm *pUp = pStart->GetUpper();               //Head/Foot
     832           0 :             while ( pUp && pUp->GetUpper() && !(pUp->GetType() & 0x0018 ) )
     833           0 :                 pUp = pUp->GetUpper();
     834           0 :             bool bSame = false;
     835           0 :             const SwFrm *pCntUp = pCnt->GetUpper();
     836           0 :             while ( pCntUp && !bSame )
     837             :             {
     838           0 :                 if ( pUp == pCntUp )
     839           0 :                     bSame = true;
     840             :                 else
     841           0 :                     pCntUp = pCntUp->GetUpper();
     842             :             }
     843           0 :             if ( !bSame )
     844           0 :                 pCnt = 0;
     845           0 :             else if ( pCnt && pCnt->IsTxtFrm() && ((SwTxtFrm*)pCnt)->IsHiddenNow() ) // i73332
     846             :             {
     847           0 :                 pCnt = (*fnNxtPrv)( pCnt );
     848           0 :                 pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, true, bInReadOnly, bTblSel );
     849             :             }
     850             :         }
     851             : 
     852          12 :         if ( bTab )
     853             :         {
     854          12 :             if ( !pCnt )
     855           0 :                 bEnd = true;
     856             :             else
     857             :             {
     858          12 :                 const SwTabFrm *pTab = pCnt->FindTabFrm();
     859          12 :                 if( !pTab )
     860           0 :                     bEnd = true;
     861             :                 else
     862             :                 {
     863          12 :                     if ( pTab != pTable )
     864             :                     {
     865             :                         //The flow leads from one table to the next. The X-value
     866             :                         //needs to be corrected by the amount of the offset of
     867             :                         //the tables
     868           0 :                          if ( pTable &&
     869           0 :                               !pTab->GetUpper()->IsInTab() &&
     870           0 :                             !pTable->GetUpper()->IsInTab() )
     871           0 :                             nX += pTab->Frm().Left() - pTable->Frm().Left();
     872           0 :                         pTable = pTab;
     873             :                     }
     874          12 :                     const SwLayoutFrm *pCell = pCnt->GetUpper();
     875          24 :                     while ( pCell && !pCell->IsCellFrm() )
     876           0 :                         pCell = pCell->GetUpper();
     877             : 
     878          12 :                     Point aInsideCell;
     879          12 :                     Point aInsideCnt;
     880          12 :                     if ( pCell )
     881             :                     {
     882          12 :                         long nTmpTop = (pCell->Frm().*fnRect->fnGetTop)();
     883          12 :                         if ( bVert )
     884             :                         {
     885           0 :                             if ( nTmpTop )
     886           0 :                                 --nTmpTop;
     887             : 
     888           0 :                             aInsideCell = Point( nTmpTop, nX );
     889             :                         }
     890             :                         else
     891          12 :                             aInsideCell = Point( nX, nTmpTop );
     892             :                     }
     893             : 
     894          12 :                     long nTmpTop = (pCnt->Frm().*fnRect->fnGetTop)();
     895          12 :                     if ( bVert )
     896             :                     {
     897           0 :                         if ( nTmpTop )
     898           0 :                             --nTmpTop;
     899             : 
     900           0 :                         aInsideCnt = Point( nTmpTop, nX );
     901             :                     }
     902             :                     else
     903          12 :                         aInsideCnt = Point( nX, nTmpTop );
     904             : 
     905          12 :                     if ( pCell && pCell->Frm().IsInside( aInsideCell ) )
     906             :                     {
     907           6 :                         bEnd = true;
     908             :                         //Get the right Cntnt out of the cell.
     909           6 :                         if ( !pCnt->Frm().IsInside( aInsideCnt ) )
     910             :                         {
     911           0 :                             pCnt = pCell->ContainsCntnt();
     912           0 :                             if ( fnNxtPrv == lcl_GetPrvCnt )
     913           0 :                                 while ( pCell->IsAnLower(pCnt->GetNextCntntFrm()) )
     914           0 :                                     pCnt = pCnt->GetNextCntntFrm();
     915             :                         }
     916             :                     }
     917           6 :                     else if ( pCnt->Frm().IsInside( aInsideCnt ) )
     918           0 :                         bEnd = true;
     919             :                 }
     920             :             }
     921          12 :             if ( !bEnd )
     922             :             {
     923           6 :                 pCnt = (*fnNxtPrv)( pCnt );
     924           6 :                 pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, true, bInReadOnly, bTblSel );
     925             :             }
     926             :         }
     927             : 
     928          18 :     } while ( !bEnd ||
     929           6 :               (pCnt && pCnt->IsTxtFrm() && ((SwTxtFrm*)pCnt)->IsHiddenNow()));
     930             : 
     931           6 :     if( pCnt )
     932             :     {   // set the Point on the Content-Node
     933           6 :         SwCntntNode *pCNd = (SwCntntNode*)pCnt->GetNode();
     934           6 :         pPam->GetPoint()->nNode = *pCNd;
     935           6 :         if ( fnNxtPrv == lcl_GetPrvCnt )
     936           4 :             pCNd->MakeEndIndex( (SwIndex*)&pPam->GetPoint()->nContent );
     937             :         else
     938           2 :             pCNd->MakeStartIndex( (SwIndex*)&pPam->GetPoint()->nContent );
     939           6 :         return true;
     940             :     }
     941           0 :     return false;
     942             : }
     943             : 
     944           4 : bool SwCntntFrm::UnitUp( SwPaM* pPam, const SwTwips, bool bInReadOnly ) const
     945             : {
     946           4 :     return ::lcl_UpDown( pPam, this, lcl_GetPrvCnt, bInReadOnly );
     947             : }
     948             : 
     949           2 : bool SwCntntFrm::UnitDown( SwPaM* pPam, const SwTwips, bool bInReadOnly ) const
     950             : {
     951           2 :     return ::lcl_UpDown( pPam, this, lcl_GetNxtCnt, bInReadOnly );
     952             : }
     953             : 
     954             : /** Returns the number of the current page.
     955             :  *
     956             :  * If the method gets a PaM then the current page is the one in which the PaM sits. Otherwise the
     957             :  * current page is the first one inside the VisibleArea. We only work on available pages!
     958             :  */
     959           0 : sal_uInt16 SwRootFrm::GetCurrPage( const SwPaM *pActualCrsr ) const
     960             : {
     961             :     OSL_ENSURE( pActualCrsr, "got no page cursor" );
     962           0 :     SwFrm const*const pActFrm = pActualCrsr->GetPoint()->nNode.GetNode().
     963             :                                     GetCntntNode()->getLayoutFrm( this, 0,
     964             :                                                     pActualCrsr->GetPoint(),
     965           0 :                                                     false );
     966           0 :     return pActFrm->FindPageFrm()->GetPhyPageNum();
     967             : }
     968             : 
     969             : /** Returns a PaM which sits at the beginning of the requested page.
     970             :  *
     971             :  * Formatting is done as far as necessary.
     972             :  * The PaM sits on the last page, if the page number was chosen to big.
     973             :  *
     974             :  * @return Null, if the operation was not possible.
     975             :  */
     976           6 : sal_uInt16 SwRootFrm::SetCurrPage( SwCursor* pToSet, sal_uInt16 nPageNum )
     977             : {
     978             :     OSL_ENSURE( Lower() && Lower()->IsPageFrm(), "No page available." );
     979             : 
     980           6 :     SwPageFrm *pPage = (SwPageFrm*)Lower();
     981           6 :     bool bEnd =false;
     982          18 :     while ( !bEnd && pPage->GetPhyPageNum() != nPageNum )
     983           6 :     {   if ( pPage->GetNext() )
     984           6 :             pPage = (SwPageFrm*)pPage->GetNext();
     985             :         else
     986             :         {   //Search the first CntntFrm and format until a new page is started
     987             :             //or until the CntntFrm are all done.
     988           0 :             const SwCntntFrm *pCntnt = pPage->ContainsCntnt();
     989           0 :             while ( pCntnt && pPage->IsAnLower( pCntnt ) )
     990             :             {
     991           0 :                 pCntnt->Calc();
     992           0 :                 pCntnt = pCntnt->GetNextCntntFrm();
     993             :             }
     994             :             //Either this is a new page or we found the last page.
     995           0 :             if ( pPage->GetNext() )
     996           0 :                 pPage = (SwPageFrm*)pPage->GetNext();
     997             :             else
     998           0 :                 bEnd = true;
     999             :         }
    1000             :     }
    1001             :     //pPage now points to the 'requested' page. Now we have to create the PaM
    1002             :     //on the beginning of the first CntntFrm in the body-text.
    1003             :     //If this is a footnote-page, the PaM will be set in the first footnote.
    1004           6 :     const SwCntntFrm *pCntnt = pPage->ContainsCntnt();
    1005           6 :     if ( pPage->IsFtnPage() )
    1006           0 :         while ( pCntnt && !pCntnt->IsInFtn() )
    1007           0 :             pCntnt = pCntnt->GetNextCntntFrm();
    1008             :     else
    1009          16 :         while ( pCntnt && !pCntnt->IsInDocBody() )
    1010           4 :             pCntnt = pCntnt->GetNextCntntFrm();
    1011           6 :     if ( pCntnt )
    1012             :     {
    1013           6 :         SwCntntNode* pCNd = (SwCntntNode*)pCntnt->GetNode();
    1014           6 :         pToSet->GetPoint()->nNode = *pCNd;
    1015           6 :         pCNd->MakeStartIndex( (SwIndex*)&pToSet->GetPoint()->nContent );
    1016           6 :         pToSet->GetPoint()->nContent = ((SwTxtFrm*)pCntnt)->GetOfst();
    1017             : 
    1018           6 :         SwShellCrsr* pSCrsr = dynamic_cast<SwShellCrsr*>(pToSet);
    1019           6 :         if( pSCrsr )
    1020             :         {
    1021           6 :             Point &rPt = pSCrsr->GetPtPos();
    1022           6 :             rPt = pCntnt->Frm().Pos();
    1023           6 :             rPt += pCntnt->Prt().Pos();
    1024             :         }
    1025           6 :         return pPage->GetPhyPageNum();
    1026             :     }
    1027           0 :     return 0;
    1028             : }
    1029             : 
    1030          66 : SwCntntFrm *GetFirstSub( const SwLayoutFrm *pLayout )
    1031             : {
    1032          66 :     return ((SwPageFrm*)pLayout)->FindFirstBodyCntnt();
    1033             : }
    1034             : 
    1035           4 : SwCntntFrm *GetLastSub( const SwLayoutFrm *pLayout )
    1036             : {
    1037           4 :     return ((SwPageFrm*)pLayout)->FindLastBodyCntnt();
    1038             : }
    1039             : 
    1040           2 : SwLayoutFrm *GetNextFrm( const SwLayoutFrm *pFrm )
    1041             : {
    1042             :     SwLayoutFrm *pNext =
    1043           4 :         (pFrm->GetNext() && pFrm->GetNext()->IsLayoutFrm()) ?
    1044           4 :                                             (SwLayoutFrm*)pFrm->GetNext() : 0;
    1045             :     // #i39402# in case of an empty page
    1046           2 :     if(pNext && !pNext->ContainsCntnt())
    1047           0 :         pNext = (pNext->GetNext() && pNext->GetNext()->IsLayoutFrm()) ?
    1048           0 :                                             (SwLayoutFrm*)pNext->GetNext() : 0;
    1049           2 :     return pNext;
    1050             : }
    1051             : 
    1052          66 : SwLayoutFrm *GetThisFrm( const SwLayoutFrm *pFrm )
    1053             : {
    1054          66 :     return (SwLayoutFrm*)pFrm;
    1055             : }
    1056             : 
    1057           2 : SwLayoutFrm *GetPrevFrm( const SwLayoutFrm *pFrm )
    1058             : {
    1059             :     SwLayoutFrm *pPrev =
    1060           4 :         (pFrm->GetPrev() && pFrm->GetPrev()->IsLayoutFrm()) ?
    1061           4 :                                             (SwLayoutFrm*)pFrm->GetPrev() : 0;
    1062             :     // #i39402# in case of an empty page
    1063           2 :     if(pPrev && !pPrev->ContainsCntnt())
    1064           0 :         pPrev = (pPrev->GetPrev() && pPrev->GetPrev()->IsLayoutFrm()) ?
    1065           0 :                                             (SwLayoutFrm*)pPrev->GetPrev() : 0;
    1066           2 :     return pPrev;
    1067             : }
    1068             : 
    1069             : //Now we can also initialize de function pointers;
    1070             : //they are declared in cshtyp.hxx
    1071             : SwPosPage fnPageStart = GetFirstSub;
    1072             : SwPosPage fnPageEnd = GetLastSub;
    1073             : SwWhichPage fnPagePrev = GetPrevFrm;
    1074             : SwWhichPage fnPageCurr = GetThisFrm;
    1075             : SwWhichPage fnPageNext = GetNextFrm;
    1076             : 
    1077             : /**
    1078             :  * Returns the first/last Contentframe (controlled using the parameter fnPosPage)
    1079             :  * of the current/previous/next page (controlled using the parameter fnWhichPage).
    1080             :  */
    1081          70 : bool GetFrmInPage( const SwCntntFrm *pCnt, SwWhichPage fnWhichPage,
    1082             :                    SwPosPage fnPosPage, SwPaM *pPam )
    1083             : {
    1084             :     //First find the requested page, at first the current, then the one which
    1085             :     //was requests through fnWichPage.
    1086          70 :     const SwLayoutFrm *pLayoutFrm = pCnt->FindPageFrm();
    1087          70 :     if ( !pLayoutFrm || (0 == (pLayoutFrm = (*fnWhichPage)(pLayoutFrm))) )
    1088           0 :         return false;
    1089             : 
    1090             :     //Now the desired CntntFrm below the page
    1091          70 :     if( 0 == (pCnt = (*fnPosPage)(pLayoutFrm)) )
    1092           0 :         return false;
    1093             :     else
    1094             :     {
    1095             :         // repeated headlines in tables
    1096          70 :         if ( pCnt->IsInTab() && fnPosPage == GetFirstSub )
    1097             :         {
    1098          12 :             const SwTabFrm* pTab = pCnt->FindTabFrm();
    1099          12 :             if ( pTab->IsFollow() )
    1100             :             {
    1101           8 :                 if ( pTab->IsInHeadline( *pCnt ) )
    1102             :                 {
    1103           0 :                     SwLayoutFrm* pRow = pTab->GetFirstNonHeadlineRow();
    1104           0 :                     if ( pRow )
    1105             :                     {
    1106             :                         // We are in the first line of a follow table
    1107             :                         // with repeated headings.
    1108             :                         // To actually make a "real" move we take the first content
    1109             :                         // of the next row
    1110           0 :                         pCnt = pRow->ContainsCntnt();
    1111           0 :                         if ( ! pCnt )
    1112           0 :                             return false;
    1113             :                     }
    1114             :                 }
    1115             :             }
    1116             :         }
    1117             : 
    1118          70 :         SwCntntNode *pCNd = (SwCntntNode*)pCnt->GetNode();
    1119          70 :         pPam->GetPoint()->nNode = *pCNd;
    1120             :         sal_Int32 nIdx;
    1121          70 :         if( fnPosPage == GetFirstSub )
    1122          66 :             nIdx = ((SwTxtFrm*)pCnt)->GetOfst();
    1123             :         else
    1124           4 :             nIdx = pCnt->GetFollow() ?
    1125           4 :                     ((SwTxtFrm*)pCnt)->GetFollow()->GetOfst()-1 : pCNd->Len();
    1126          70 :         pPam->GetPoint()->nContent.Assign( pCNd, nIdx );
    1127          70 :         return true;
    1128             :     }
    1129             : }
    1130             : 
    1131         378 : static sal_uInt64 CalcDiff(const Point &rPt1, const Point &rPt2)
    1132             : {
    1133             :     //Calculate the distance between the two points.
    1134             :     //'delta' X^2 + 'delta'Y^2 = 'distance'^2
    1135        1134 :     sal_uInt64 dX = std::max( rPt1.X(), rPt2.X() ) -
    1136         756 :                std::min( rPt1.X(), rPt2.X() ),
    1137        1134 :           dY = std::max( rPt1.Y(), rPt2.Y() ) -
    1138         756 :                std::min( rPt1.Y(), rPt2.Y() );
    1139         378 :     return (dX * dX) + (dY * dY);
    1140             : }
    1141             : 
    1142             : /** Check if the point lies inside the page part in which also the CntntFrame lies.
    1143             :  *
    1144             :  * In this context header, page body, footer and footnote-container count as page part.
    1145             :  * This will suit the purpose that the CntntFrm which lies in the "right" page part will be
    1146             :  * accepted instead of one which doesn't lie there although his distance to the point is shorter.
    1147             :  */
    1148         378 : static const SwLayoutFrm* lcl_Inside( const SwCntntFrm *pCnt, Point& rPt )
    1149             : {
    1150         378 :     const SwLayoutFrm* pUp = pCnt->GetUpper();
    1151        1068 :     while( pUp )
    1152             :     {
    1153         690 :         if( pUp->IsPageBodyFrm() || pUp->IsFooterFrm() || pUp->IsHeaderFrm() )
    1154             :         {
    1155         378 :             if( rPt.Y() >= pUp->Frm().Top() && rPt.Y() <= pUp->Frm().Bottom() )
    1156         248 :                 return pUp;
    1157         130 :             return NULL;
    1158             :         }
    1159         312 :         if( pUp->IsFtnContFrm() )
    1160           0 :             return pUp->Frm().IsInside( rPt ) ? pUp : NULL;
    1161         312 :         pUp = pUp->GetUpper();
    1162             :     }
    1163           0 :     return NULL;
    1164             : }
    1165             : 
    1166             : /** Search for the nearest Cntnt to pass.
    1167             :  *
    1168             :  * Considers the previous, the current and the next page.
    1169             :  * If no content is found, the area gets expanded until one is found.
    1170             :  *
    1171             :  * @return The 'semantically correct' position inside the PrtArea of the found CntntFrm.
    1172             :  */
    1173         315 : const SwCntntFrm *SwLayoutFrm::GetCntntPos( Point& rPoint,
    1174             :                                             const bool bDontLeave,
    1175             :                                             const bool bBodyOnly,
    1176             :                                             const bool bCalc,
    1177             :                                             const SwCrsrMoveState *pCMS,
    1178             :                                             const bool bDefaultExpand ) const
    1179             : {
    1180             :     //Determine the first CntntFrm.
    1181         630 :     const SwLayoutFrm *pStart = (!bDontLeave && bDefaultExpand && GetPrev()) ?
    1182         315 :                                     (SwLayoutFrm*)GetPrev() : this;
    1183         315 :     const SwCntntFrm *pCntnt = pStart->ContainsCntnt();
    1184             : 
    1185         315 :     if ( !pCntnt && (GetPrev() && !bDontLeave) )
    1186           0 :         pCntnt = ContainsCntnt();
    1187             : 
    1188         315 :     if ( bBodyOnly && pCntnt && !pCntnt->IsInDocBody() )
    1189           0 :         while ( pCntnt && !pCntnt->IsInDocBody() )
    1190           0 :             pCntnt = pCntnt->GetNextCntntFrm();
    1191             : 
    1192         315 :     const SwCntntFrm *pActual= pCntnt;
    1193         315 :     const SwLayoutFrm *pInside = NULL;
    1194         315 :     sal_uInt16 nMaxPage = GetPhyPageNum() + (bDefaultExpand ? 1 : 0);
    1195         315 :     Point aPoint = rPoint;
    1196         315 :     sal_uInt64 nDistance = SAL_MAX_UINT64;
    1197             : 
    1198             :     while ( true )  //A loop to be sure we always find one.
    1199             :     {
    1200        2163 :         while ( pCntnt &&
    1201        1022 :                 ((!bDontLeave || IsAnLower( pCntnt )) &&
    1202         511 :                 (pCntnt->GetPhyPageNum() <= nMaxPage)) )
    1203             :         {
    1204        1381 :             if ( ( bCalc || pCntnt->Frm().Width() ) &&
    1205         439 :                  ( !bBodyOnly || pCntnt->IsInDocBody() ) )
    1206             :             {
    1207             :                 //If the Cntnt lies in a protected area (cell, Ftn, section),
    1208             :                 //we search the next Cntnt which is not protected.
    1209         435 :                 const SwCntntFrm *pComp = pCntnt;
    1210             :                 pCntnt = ::lcl_MissProtectedFrames( pCntnt, lcl_GetNxtCnt, false,
    1211         435 :                                         pCMS && pCMS->bSetInReadOnly, false );
    1212         435 :                 if ( pComp != pCntnt )
    1213           0 :                     continue;
    1214             : 
    1215         435 :                 if ( !pCntnt->IsTxtFrm() || !((SwTxtFrm*)pCntnt)->IsHiddenNow() )
    1216             :                 {
    1217         378 :                     if ( bCalc )
    1218           0 :                         pCntnt->Calc();
    1219             : 
    1220         378 :                     SwRect aCntFrm( pCntnt->UnionFrm() );
    1221         378 :                     if ( aCntFrm.IsInside( rPoint ) )
    1222             :                     {
    1223           0 :                         pActual = pCntnt;
    1224           0 :                         aPoint = rPoint;
    1225           0 :                         break;
    1226             :                     }
    1227             :                     //The distance from rPoint to the nearest Point of pCntnt
    1228             :                     //will now be calculated.
    1229         378 :                     Point aCntntPoint( rPoint );
    1230             : 
    1231             :                     //First set the vertical position
    1232         378 :                     if ( aCntFrm.Top() > aCntntPoint.Y() )
    1233         130 :                         aCntntPoint.Y() = aCntFrm.Top();
    1234         248 :                     else if ( aCntFrm.Bottom() < aCntntPoint.Y() )
    1235         248 :                         aCntntPoint.Y() = aCntFrm.Bottom();
    1236             : 
    1237             :                     //Now the horizontal position
    1238         378 :                     if ( aCntFrm.Left() > aCntntPoint.X() )
    1239         120 :                         aCntntPoint.X() = aCntFrm.Left();
    1240         258 :                     else if ( aCntFrm.Right() < aCntntPoint.X() )
    1241           0 :                         aCntntPoint.X() = aCntFrm.Right();
    1242             : 
    1243             :                     // pInside is a page area in which the point lies. As soon
    1244             :                     // as pInside != 0 only frames are accepted which are
    1245             :                     // placed inside.
    1246         756 :                     if( !pInside || ( pInside->IsAnLower( pCntnt ) &&
    1247           0 :                         ( !pCntnt->IsInFtn() || pInside->IsFtnContFrm() ) ) )
    1248             :                     {
    1249         378 :                         const sal_uInt64 nDiff = ::CalcDiff(aCntntPoint, rPoint);
    1250         378 :                         bool bBetter = nDiff < nDistance;  // This one is nearer
    1251         378 :                         if( !pInside )
    1252             :                         {
    1253         378 :                             pInside = lcl_Inside( pCntnt, rPoint );
    1254         378 :                             if( pInside )  // In the "right" page area
    1255         248 :                                 bBetter = true;
    1256             :                         }
    1257         378 :                         if( bBetter )
    1258             :                         {
    1259         258 :                             aPoint = aCntntPoint;
    1260         258 :                             nDistance = nDiff;
    1261         258 :                             pActual = pCntnt;
    1262             :                         }
    1263             :                     }
    1264             :                 }
    1265             :             }
    1266         511 :             pCntnt = pCntnt->GetNextCntntFrm();
    1267         511 :             if ( bBodyOnly )
    1268         160 :                 while ( pCntnt && !pCntnt->IsInDocBody() )
    1269           0 :                     pCntnt = pCntnt->GetNextCntntFrm();
    1270             :         }
    1271         315 :         if ( !pActual )
    1272             :         {   //If we not yet found one we have to expand the searched
    1273             :             //area, sometime we will find one!
    1274             :             //MA 1997-01-09: Opt for many empty pages - if we only search inside
    1275             :             //the body, we can expand the searched area sufficiently in one step.
    1276           0 :             if ( bBodyOnly )
    1277             :             {
    1278           0 :                 while ( !pCntnt && pStart->GetPrev() )
    1279             :                 {
    1280           0 :                     ++nMaxPage;
    1281           0 :                     if( !pStart->GetPrev()->IsLayoutFrm() )
    1282           0 :                         return 0;
    1283           0 :                     pStart = (SwLayoutFrm*)pStart->GetPrev();
    1284           0 :                     pCntnt = pStart->IsInDocBody()
    1285             :                                 ? pStart->ContainsCntnt()
    1286           0 :                                 : pStart->FindPageFrm()->FindFirstBodyCntnt();
    1287             :                 }
    1288           0 :                 if ( !pCntnt )  // Somewhere down the road we have to start with one!
    1289             :                 {
    1290           0 :                     pCntnt = pStart->FindPageFrm()->GetUpper()->ContainsCntnt();
    1291           0 :                     while ( pCntnt && !pCntnt->IsInDocBody() )
    1292           0 :                         pCntnt = pCntnt->GetNextCntntFrm();
    1293           0 :                     if ( !pCntnt )
    1294           0 :                         return 0;   // There is no document content yet!
    1295             :                 }
    1296             :             }
    1297             :             else
    1298             :             {
    1299           0 :                 ++nMaxPage;
    1300           0 :                 if ( pStart->GetPrev() )
    1301             :                 {
    1302           0 :                     if( !pStart->GetPrev()->IsLayoutFrm() )
    1303           0 :                         return 0;
    1304           0 :                     pStart = (SwLayoutFrm*)pStart->GetPrev();
    1305           0 :                     pCntnt = pStart->ContainsCntnt();
    1306             :                 }
    1307             :                 else // Somewhere down the road we have to start with one!
    1308           0 :                     pCntnt = pStart->FindPageFrm()->GetUpper()->ContainsCntnt();
    1309             :             }
    1310           0 :             pActual = pCntnt;
    1311             :         }
    1312             :         else
    1313         315 :             break;
    1314             :     }
    1315             : 
    1316             :     OSL_ENSURE( pActual, "no Cntnt found." );
    1317             :     OSL_ENSURE( !bBodyOnly || pActual->IsInDocBody(), "Cntnt not in Body." );
    1318             : 
    1319             :     //Special case for selecting tables not in repeated TblHeadlines.
    1320         315 :     if ( pActual->IsInTab() && pCMS && pCMS->eState == MV_TBLSEL )
    1321             :     {
    1322           0 :         const SwTabFrm *pTab = pActual->FindTabFrm();
    1323           0 :         if ( pTab->IsFollow() && pTab->IsInHeadline( *pActual ) )
    1324             :         {
    1325           0 :             ((SwCrsrMoveState*)pCMS)->bStop = true;
    1326           0 :             return 0;
    1327             :         }
    1328             :     }
    1329             : 
    1330             :     //A small correction at the first/last
    1331         315 :     Size aActualSize( pActual->Prt().SSize() );
    1332         315 :     if ( aActualSize.Height() > pActual->GetUpper()->Prt().Height() )
    1333           0 :         aActualSize.Height() = pActual->GetUpper()->Prt().Height();
    1334             : 
    1335         315 :     SWRECTFN( pActual )
    1336         628 :     if ( !pActual->GetPrev() &&
    1337         626 :          (*fnRect->fnYDiff)( (pActual->*fnRect->fnGetPrtTop)(),
    1338         939 :                               bVert ? rPoint.X() : rPoint.Y() ) > 0 )
    1339             :     {
    1340          10 :         aPoint.Y() = pActual->Frm().Top() + pActual->Prt().Top();
    1341          30 :         aPoint.X() = pActual->Frm().Left() +
    1342          20 :                         ( pActual->IsRightToLeft() || bVert ?
    1343           0 :                           pActual->Prt().Right() :
    1344          20 :                           pActual->Prt().Left() );
    1345             :     }
    1346         610 :     else if ( !pActual->GetNext() &&
    1347         610 :               (*fnRect->fnYDiff)( (pActual->*fnRect->fnGetPrtBottom)(),
    1348         915 :                                    bVert ? rPoint.X() : rPoint.Y() ) < 0 )
    1349             :     {
    1350         301 :         aPoint.Y() = pActual->Frm().Top() + pActual->Prt().Bottom();
    1351         903 :         aPoint.X() = pActual->Frm().Left() +
    1352         602 :                         ( pActual->IsRightToLeft() || bVert ?
    1353           0 :                           pActual->Prt().Left() :
    1354         602 :                           pActual->Prt().Right() );
    1355             :     }
    1356             : 
    1357             :     //Bring the Point in to the PrtArea
    1358         315 :     if ( bCalc )
    1359           0 :         pActual->Calc();
    1360         630 :     const SwRect aRect( pActual->Frm().Pos() + pActual->Prt().Pos(),
    1361         315 :                         aActualSize );
    1362         315 :     if ( aPoint.Y() < aRect.Top() )
    1363           0 :         aPoint.Y() = aRect.Top();
    1364         315 :     else if ( aPoint.Y() > aRect.Bottom() )
    1365           0 :         aPoint.Y() = aRect.Bottom();
    1366         315 :     if ( aPoint.X() < aRect.Left() )
    1367           0 :         aPoint.X() = aRect.Left();
    1368         315 :     else if ( aPoint.X() > aRect.Right() )
    1369           0 :         aPoint.X() = aRect.Right();
    1370         315 :     rPoint = aPoint;
    1371         315 :     return pActual;
    1372             : }
    1373             : 
    1374             : /** Same as SwLayoutFrm::GetCntntPos(). Specialized for fields and border. */
    1375           0 : void SwPageFrm::GetCntntPosition( const Point &rPt, SwPosition &rPos ) const
    1376             : {
    1377             :     //Determine the first CntntFrm.
    1378           0 :     const SwCntntFrm *pCntnt = ContainsCntnt();
    1379           0 :     if ( pCntnt )
    1380             :     {
    1381             :         //Look back one more (if possible).
    1382           0 :         const SwCntntFrm *pTmp = pCntnt->GetPrevCntntFrm();
    1383           0 :         while ( pTmp && !pTmp->IsInDocBody() )
    1384           0 :             pTmp = pTmp->GetPrevCntntFrm();
    1385           0 :         if ( pTmp )
    1386           0 :             pCntnt = pTmp;
    1387             :     }
    1388             :     else
    1389           0 :         pCntnt = GetUpper()->ContainsCntnt();
    1390             : 
    1391           0 :     const SwCntntFrm *pAct = pCntnt;
    1392           0 :     Point aAct       = rPt;
    1393           0 :     sal_uInt64 nDist = SAL_MAX_UINT64;
    1394             : 
    1395           0 :     while ( pCntnt )
    1396             :     {
    1397           0 :         SwRect aCntFrm( pCntnt->UnionFrm() );
    1398           0 :         if ( aCntFrm.IsInside( rPt ) )
    1399             :         {
    1400             :             //This is the nearest one.
    1401           0 :             pAct = pCntnt;
    1402           0 :             break;
    1403             :         }
    1404             : 
    1405             :         //Calculate the distance from rPt to the nearest point of pCntnt.
    1406           0 :         Point aPoint( rPt );
    1407             : 
    1408             :         //Calculate the vertical position first
    1409           0 :         if ( aCntFrm.Top() > rPt.Y() )
    1410           0 :             aPoint.Y() = aCntFrm.Top();
    1411           0 :         else if ( aCntFrm.Bottom() < rPt.Y() )
    1412           0 :             aPoint.Y() = aCntFrm.Bottom();
    1413             : 
    1414             :         //And now the horizontal position
    1415           0 :         if ( aCntFrm.Left() > rPt.X() )
    1416           0 :             aPoint.X() = aCntFrm.Left();
    1417           0 :         else if ( aCntFrm.Right() < rPt.X() )
    1418           0 :             aPoint.X() = aCntFrm.Right();
    1419             : 
    1420           0 :         const sal_uInt64 nDiff = ::CalcDiff( aPoint, rPt );
    1421           0 :         if ( nDiff < nDist )
    1422             :         {
    1423           0 :             aAct    = aPoint;
    1424           0 :             nDist   = nDiff;
    1425           0 :             pAct    = pCntnt;
    1426             :         }
    1427           0 :         else if ( aCntFrm.Top() > Frm().Bottom() )
    1428             :             //In terms of fields, it's not possible to be closer any more!
    1429           0 :             break;
    1430             : 
    1431           0 :         pCntnt = pCntnt->GetNextCntntFrm();
    1432           0 :         while ( pCntnt && !pCntnt->IsInDocBody() )
    1433           0 :             pCntnt = pCntnt->GetNextCntntFrm();
    1434             :     }
    1435             : 
    1436             :     //Bring the point into the PrtArea.
    1437           0 :     const SwRect aRect( pAct->Frm().Pos() + pAct->Prt().Pos(), pAct->Prt().SSize() );
    1438           0 :     if ( aAct.Y() < aRect.Top() )
    1439           0 :         aAct.Y() = aRect.Top();
    1440           0 :     else if ( aAct.Y() > aRect.Bottom() )
    1441           0 :         aAct.Y() = aRect.Bottom();
    1442           0 :     if ( aAct.X() < aRect.Left() )
    1443           0 :         aAct.X() = aRect.Left();
    1444           0 :     else if ( aAct.X() > aRect.Right() )
    1445           0 :         aAct.X() = aRect.Right();
    1446             : 
    1447           0 :     if( !pAct->IsValid() )
    1448             :     {
    1449             :         // CntntFrm not formated -> always on node-beginning
    1450           0 :         SwCntntNode* pCNd = (SwCntntNode*)pAct->GetNode();
    1451             :         OSL_ENSURE( pCNd, "Where is my CntntNode?" );
    1452           0 :         rPos.nNode = *pCNd;
    1453           0 :         rPos.nContent.Assign( pCNd, 0 );
    1454             :     }
    1455             :     else
    1456             :     {
    1457           0 :         SwCrsrMoveState aTmpState( MV_SETONLYTEXT );
    1458           0 :         pAct->GetCrsrOfst( &rPos, aAct, &aTmpState );
    1459             :     }
    1460           0 : }
    1461             : 
    1462             : // #123110# - helper class to disable creation of an action
    1463             : // by a callback event - e.g., change event from a drawing object
    1464             : class DisableCallbackAction
    1465             : {
    1466             :     private:
    1467             :         SwRootFrm& mrRootFrm;
    1468             :         bool mbOldCallbackActionState;
    1469             : 
    1470             :     public:
    1471           0 :         DisableCallbackAction( const SwRootFrm& _rRootFrm ) :
    1472             :             mrRootFrm( const_cast<SwRootFrm&>(_rRootFrm) ),
    1473           0 :             mbOldCallbackActionState( _rRootFrm.IsCallbackActionEnabled() )
    1474             :         {
    1475           0 :             mrRootFrm.SetCallbackActionEnabled( false );
    1476           0 :         }
    1477             : 
    1478           0 :         ~DisableCallbackAction()
    1479             :         {
    1480           0 :             mrRootFrm.SetCallbackActionEnabled( mbOldCallbackActionState );
    1481           0 :         }
    1482             : };
    1483             : 
    1484             : /** Search the nearest Cntnt to the passed point.
    1485             :  *
    1486             :  * Only search inside the BodyText.
    1487             :  * @note Only the nearest vertically one will be searched.
    1488             :  * @note JP 11.10.2001: only in tables we try to find the right column - Bug 72294
    1489             :  */
    1490           0 : Point SwRootFrm::GetNextPrevCntntPos( const Point& rPoint, bool bNext ) const
    1491             : {
    1492             :     // #123110# - disable creation of an action by a callback
    1493             :     // event during processing of this method. Needed because formatting is
    1494             :     // triggered by this method.
    1495           0 :     DisableCallbackAction aDisableCallbackAction( *this );
    1496             :     //Search the first CntntFrm and his successor in the body area.
    1497             :     //To be efficient (and not formatting too much) we'll start at the correct
    1498             :     //page.
    1499           0 :     SwLayoutFrm *pPage = (SwLayoutFrm*)Lower();
    1500           0 :     if( pPage )
    1501           0 :         while( pPage->GetNext() && pPage->Frm().Bottom() < rPoint.Y() )
    1502           0 :             pPage = (SwLayoutFrm*)pPage->GetNext();
    1503             : 
    1504           0 :     const SwCntntFrm *pCnt = pPage ? pPage->ContainsCntnt() : ContainsCntnt();
    1505           0 :     while ( pCnt && !pCnt->IsInDocBody() )
    1506           0 :         pCnt = pCnt->GetNextCntntFrm();
    1507             : 
    1508           0 :     if ( !pCnt )
    1509           0 :         return Point( 0, 0 );
    1510             : 
    1511           0 :     pCnt->Calc();
    1512           0 :     if( !bNext )
    1513             :     {
    1514             :         // As long as the point lies before the first CntntFrm and there are
    1515             :         // still precedent pages I'll go to the next page.
    1516           0 :         while ( rPoint.Y() < pCnt->Frm().Top() && pPage->GetPrev() )
    1517             :         {
    1518           0 :             pPage = (SwLayoutFrm*)pPage->GetPrev();
    1519           0 :             pCnt = pPage->ContainsCntnt();
    1520           0 :             while ( !pCnt )
    1521             :             {
    1522           0 :                 pPage = (SwLayoutFrm*)pPage->GetPrev();
    1523           0 :                 if ( pPage )
    1524           0 :                     pCnt = pPage->ContainsCntnt();
    1525             :                 else
    1526           0 :                     return ContainsCntnt()->UnionFrm().Pos();
    1527             :             }
    1528           0 :             pCnt->Calc();
    1529             :         }
    1530             :     }
    1531             : 
    1532             :     //Does the point lie above the first CntntFrm?
    1533           0 :     if ( rPoint.Y() < pCnt->Frm().Top() && !lcl_IsInRepeatedHeadline( pCnt ) )
    1534           0 :         return pCnt->UnionFrm().Pos();
    1535             : 
    1536           0 :     Point aRet(0, 0);
    1537           0 :     do
    1538             :     {
    1539             :         //Does the point lie in the current CntntFrm?
    1540           0 :         SwRect aCntFrm( pCnt->UnionFrm() );
    1541           0 :         if ( aCntFrm.IsInside( rPoint ) && !lcl_IsInRepeatedHeadline( pCnt ))
    1542             :         {
    1543           0 :             aRet = rPoint;
    1544           0 :             break;
    1545             :         }
    1546             : 
    1547             :         //Is the current one the last CntntFrm?
    1548             :         //If the next CntntFrm lies behind the point, then the current on is the
    1549             :         //one we searched.
    1550           0 :         const SwCntntFrm *pNxt = pCnt->GetNextCntntFrm();
    1551           0 :         while ( pNxt && !pNxt->IsInDocBody() )
    1552           0 :             pNxt = pNxt->GetNextCntntFrm();
    1553             : 
    1554             :         //Does the point lie behind the last CntntFrm?
    1555           0 :         if ( !pNxt )
    1556             :         {
    1557           0 :             aRet = Point( aCntFrm.Right(), aCntFrm.Bottom() );
    1558           0 :             break;
    1559             :         }
    1560             : 
    1561             :         //If the next CntntFrm lies behind the point then it is the one we
    1562             :         //searched.
    1563             :         const SwTabFrm* pTFrm;
    1564           0 :         pNxt->Calc();
    1565           0 :         if( pNxt->Frm().Top() > rPoint.Y() &&
    1566           0 :             !lcl_IsInRepeatedHeadline( pCnt, &pTFrm ) &&
    1567           0 :             ( !pTFrm || pNxt->Frm().Left() > rPoint.X() ))
    1568             :         {
    1569           0 :             if (bNext)
    1570           0 :                 aRet = pNxt->Frm().Pos();
    1571             :             else
    1572           0 :                 aRet = Point( aCntFrm.Right(), aCntFrm.Bottom() );
    1573           0 :             break;
    1574             :         }
    1575           0 :         pCnt = pNxt;
    1576             :     }
    1577             :     while (pCnt);
    1578           0 :     return aRet;
    1579             : }
    1580             : 
    1581             : /** Returns the absolute document position of the desired page.
    1582             :  *
    1583             :  * Formatting is done only as far as needed and only if bFormat=true.
    1584             :  * Pos is set to the one of the last page, if the page number was chosen to big.
    1585             :  *
    1586             :  * @return Null, if the operation failed.
    1587             :  */
    1588           0 : Point SwRootFrm::GetPagePos( sal_uInt16 nPageNum ) const
    1589             : {
    1590             :     OSL_ENSURE( Lower() && Lower()->IsPageFrm(), "No page available." );
    1591             : 
    1592           0 :     const SwPageFrm *pPage = (const SwPageFrm*)Lower();
    1593             :     while ( true )
    1594             :     {
    1595           0 :         if ( pPage->GetPhyPageNum() >= nPageNum || !pPage->GetNext() )
    1596           0 :             break;
    1597           0 :         pPage = (const SwPageFrm*)pPage->GetNext();
    1598             :     }
    1599           0 :     return pPage->Frm().Pos();
    1600             : }
    1601             : 
    1602             : /** get page frame by phyiscal page number
    1603             :  *
    1604             :  * @return pointer to the page frame with the given physical page number
    1605             :  */
    1606           0 : SwPageFrm* SwRootFrm::GetPageByPageNum( sal_uInt16 _nPageNum ) const
    1607             : {
    1608           0 :     const SwPageFrm* pPageFrm = static_cast<const SwPageFrm*>( Lower() );
    1609           0 :     while ( pPageFrm && pPageFrm->GetPhyPageNum() < _nPageNum )
    1610             :     {
    1611           0 :           pPageFrm = static_cast<const SwPageFrm*>( pPageFrm->GetNext() );
    1612             :     }
    1613             : 
    1614           0 :     if ( pPageFrm && pPageFrm->GetPhyPageNum() == _nPageNum )
    1615             :     {
    1616           0 :         return const_cast<SwPageFrm*>( pPageFrm );
    1617             :     }
    1618             :     else
    1619             :     {
    1620           0 :         return 0;
    1621             :     }
    1622             : }
    1623             : 
    1624             : /**
    1625             :  * @return true, when the given physical pagenumber does't exist or this page is an empty page.
    1626             :  */
    1627           0 : bool SwRootFrm::IsDummyPage( sal_uInt16 nPageNum ) const
    1628             : {
    1629           0 :     if( !Lower() || !nPageNum || nPageNum > GetPageNum() )
    1630           0 :         return true;
    1631             : 
    1632           0 :     const SwPageFrm *pPage = (const SwPageFrm*)Lower();
    1633           0 :     while( pPage && nPageNum < pPage->GetPhyPageNum() )
    1634           0 :         pPage = (const SwPageFrm*)pPage->GetNext();
    1635           0 :     return !pPage || pPage->IsEmptyPage();
    1636             : }
    1637             : 
    1638             : /** Is the Frm or rather the Section in which it lies protected?
    1639             :  *
    1640             :  * Also Fly in Fly in ... and Footnotes
    1641             :  */
    1642       33124 : bool SwFrm::IsProtected() const
    1643             : {
    1644       33124 :     if (this->IsCntntFrm() && ((SwCntntFrm*)this)->GetNode())
    1645             :     {
    1646       33072 :         const SwDoc *pDoc=((SwCntntFrm*)this)->GetNode()->GetDoc();
    1647       33072 :         bool isFormProtected=pDoc->GetDocumentSettingManager().get(IDocumentSettingAccess::PROTECT_FORM );
    1648       33072 :         if (isFormProtected)
    1649             :         {
    1650           4 :             return false; // TODO a hack for now, well deal with it later, I we return true here we have a "double" locking
    1651             :         }
    1652             :     }
    1653             :     //The Frm can be protected in borders, cells or sections.
    1654             :     //Also goes up FlyFrms recursive and from footnote to anchor.
    1655       33120 :     const SwFrm *pFrm = this;
    1656      136971 :     do
    1657             :     {
    1658      136983 :         if ( pFrm->IsCntntFrm() )
    1659             :         {
    1660       66240 :             if ( ((SwCntntFrm*)pFrm)->GetNode() &&
    1661       33120 :                  ((SwCntntFrm*)pFrm)->GetNode()->IsInProtectSect() )
    1662          12 :                 return true;
    1663             :         }
    1664             :         else
    1665             :         {
    1666      207726 :             if ( ((SwLayoutFrm*)pFrm)->GetFmt() &&
    1667      103863 :                  ((SwLayoutFrm*)pFrm)->GetFmt()->
    1668      103863 :                  GetProtect().IsCntntProtected() )
    1669           0 :                 return true;
    1670      103863 :             if ( pFrm->IsCoveredCell() )
    1671           0 :                 return true;
    1672             :         }
    1673      136971 :         if ( pFrm->IsFlyFrm() )
    1674             :         {
    1675             :             //In a chain the protection of the content can be specified by the
    1676             :             //master of the chain.
    1677          30 :             if ( ((SwFlyFrm*)pFrm)->GetPrevLink() )
    1678             :             {
    1679           0 :                 SwFlyFrm *pMaster = (SwFlyFrm*)pFrm;
    1680           0 :                 do
    1681           0 :                 {   pMaster = pMaster->GetPrevLink();
    1682           0 :                 } while ( pMaster->GetPrevLink() );
    1683           0 :                 if ( pMaster->IsProtected() )
    1684           0 :                     return true;
    1685             :             }
    1686          30 :             pFrm = ((SwFlyFrm*)pFrm)->GetAnchorFrm();
    1687             :         }
    1688      136941 :         else if ( pFrm->IsFtnFrm() )
    1689          26 :             pFrm = ((SwFtnFrm*)pFrm)->GetRef();
    1690             :         else
    1691      136915 :             pFrm = pFrm->GetUpper();
    1692             : 
    1693             :     } while ( pFrm );
    1694             : 
    1695       33108 :     return false;
    1696             : }
    1697             : 
    1698             : /** @return the physical page number */
    1699       20588 : sal_uInt16 SwFrm::GetPhyPageNum() const
    1700             : {
    1701       20588 :     const SwPageFrm *pPage = FindPageFrm();
    1702       20588 :     return pPage ? pPage->GetPhyPageNum() : 0;
    1703             : }
    1704             : 
    1705             : /** Decides if the page want to be a rightpage or not.
    1706             :  *
    1707             :  * If the first content of the page has a page descriptor, we take the follow
    1708             :  * of the page descriptor of the last not empty page. If this descriptor allows
    1709             :  * only right(left) pages and the page isn't an empty page then it wanna be
    1710             :  * such right(left) page. If the descriptor allows right and left pages, we
    1711             :  * look for a number offset in the first content. If there is one, odd number
    1712             :  * results right pages, even number results left pages.
    1713             :  * If there is no number offset, we take the physical page number instead,
    1714             :  * but a previous empty page don't count.
    1715             :  */
    1716        1990 : bool SwFrm::WannaRightPage() const
    1717             : {
    1718        1990 :     const SwPageFrm *pPage = FindPageFrm();
    1719        1990 :     if ( !pPage || !pPage->GetUpper() )
    1720           0 :         return true;
    1721             : 
    1722        1990 :     const SwFrm *pFlow = pPage->FindFirstBodyCntnt();
    1723        1990 :     const SwPageDesc *pDesc = 0;
    1724        1990 :     ::boost::optional<sal_uInt16> oPgNum;
    1725        1990 :     if ( pFlow )
    1726             :     {
    1727        1684 :         if ( pFlow->IsInTab() )
    1728         116 :             pFlow = pFlow->FindTabFrm();
    1729        1684 :         const SwFlowFrm *pTmp = SwFlowFrm::CastFlowFrm( pFlow );
    1730        1684 :         if ( !pTmp->IsFollow() )
    1731             :         {
    1732        1538 :             const SwFmtPageDesc& rPgDesc = pFlow->GetAttrSet()->GetPageDesc();
    1733        1538 :             pDesc = rPgDesc.GetPageDesc();
    1734        1538 :             oPgNum = rPgDesc.GetNumOffset();
    1735             :         }
    1736             :     }
    1737        1990 :     if ( !pDesc )
    1738             :     {
    1739        1726 :         SwPageFrm *pPrv = (SwPageFrm*)pPage->GetPrev();
    1740        1726 :         if( pPrv && pPrv->IsEmptyPage() )
    1741           0 :             pPrv = (SwPageFrm*)pPrv->GetPrev();
    1742        1726 :         if( pPrv )
    1743        1390 :             pDesc = pPrv->GetPageDesc()->GetFollow();
    1744             :         else
    1745             :         {
    1746         336 :             const SwDoc* pDoc = pPage->GetFmt()->GetDoc();
    1747         336 :             pDesc = &pDoc->GetPageDesc( 0 );
    1748             :         }
    1749             :     }
    1750             :     OSL_ENSURE( pDesc, "No pagedescriptor" );
    1751             :     bool bOdd;
    1752        1990 :     if( oPgNum )
    1753          68 :         bOdd = (oPgNum.get() % 2) != 0;
    1754             :     else
    1755             :     {
    1756        1922 :         bOdd = pPage->OnRightPage();
    1757        1922 :         if( pPage->GetPrev() && ((SwPageFrm*)pPage->GetPrev())->IsEmptyPage() )
    1758           8 :             bOdd = !bOdd;
    1759             :     }
    1760        1990 :     if( !pPage->IsEmptyPage() )
    1761             :     {
    1762        1964 :         if( !pDesc->GetRightFmt() )
    1763           8 :             bOdd = false;
    1764        1956 :         else if( !pDesc->GetLeftFmt() )
    1765          10 :             bOdd = true;
    1766             :     }
    1767        1990 :     return bOdd;
    1768             : }
    1769             : 
    1770        3818 : bool SwFrm::OnFirstPage() const
    1771             : {
    1772        3818 :     bool bRet = false;
    1773        3818 :     const SwPageFrm *pPage = FindPageFrm();
    1774             : 
    1775        3818 :     if (pPage)
    1776             :     {
    1777        3818 :         const SwPageFrm* pPrevFrm = dynamic_cast<const SwPageFrm*>(pPage->GetPrev());
    1778        3818 :         if (pPrevFrm)
    1779             :         {
    1780        3346 :             const SwPageDesc* pDesc = pPage->GetPageDesc();
    1781        3346 :             bRet = pPrevFrm->GetPageDesc() != pDesc;
    1782             :         }
    1783             :         else
    1784         472 :             bRet = true;
    1785             :     }
    1786        3818 :     return bRet;
    1787             : }
    1788             : 
    1789             : /** @return the virtual page number with the offset. */
    1790        5667 : sal_uInt16 SwFrm::GetVirtPageNum() const
    1791             : {
    1792        5667 :     const SwPageFrm *pPage = FindPageFrm();
    1793        5667 :     if ( !pPage || !pPage->GetUpper() )
    1794           0 :         return 0;
    1795             : 
    1796        5667 :     sal_uInt16 nPhyPage = pPage->GetPhyPageNum();
    1797        5667 :     if ( !(static_cast<const SwRootFrm*>(pPage->GetUpper()))->IsVirtPageNum() )
    1798        5261 :         return nPhyPage;
    1799             : 
    1800             :     //Search the nearest section using the virtual page number.
    1801             :     //Because searching backwards needs a lot of time we search specific using
    1802             :     //the dependencies. From the PageDescs we get the attributes and from the
    1803             :     //attributes we get the sections.
    1804         406 :     const SwPageFrm *pVirtPage = 0;
    1805         406 :     const SwFrm *pFrm = 0;
    1806         406 :     const SfxItemPool &rPool = pPage->GetFmt()->GetDoc()->GetAttrPool();
    1807             :     const SfxPoolItem* pItem;
    1808         406 :     sal_uInt32 nMaxItems = rPool.GetItemCount2( RES_PAGEDESC );
    1809        3172 :     for( sal_uInt32 n = 0; n < nMaxItems; ++n )
    1810             :     {
    1811        2766 :         if( 0 == (pItem = rPool.GetItem2( RES_PAGEDESC, n ) ))
    1812        1180 :             continue;
    1813             : 
    1814        1586 :         const SwFmtPageDesc *pDesc = (SwFmtPageDesc*)pItem;
    1815        1586 :         if ( pDesc->GetNumOffset() && pDesc->GetDefinedIn() )
    1816             :         {
    1817         626 :             const SwModify *pMod = pDesc->GetDefinedIn();
    1818         626 :             SwVirtPageNumInfo aInfo( pPage );
    1819         626 :             pMod->GetInfo( aInfo );
    1820         626 :             if ( aInfo.GetPage() )
    1821             :             {
    1822         372 :                 if( !pVirtPage || ( pVirtPage && aInfo.GetPage()->
    1823          44 :                     GetPhyPageNum() > pVirtPage->GetPhyPageNum() ) )
    1824             :                 {
    1825         326 :                     pVirtPage = aInfo.GetPage();
    1826         326 :                     pFrm = aInfo.GetFrm();
    1827             :                 }
    1828         626 :             }
    1829             :         }
    1830             :     }
    1831         406 :     if ( pFrm )
    1832             :     {
    1833         284 :         ::boost::optional<sal_uInt16> oNumOffset = pFrm->GetAttrSet()->GetPageDesc().GetNumOffset();
    1834         284 :         if (oNumOffset)
    1835             :         {
    1836         284 :             return nPhyPage - pFrm->GetPhyPageNum() + oNumOffset.get();
    1837             :         }
    1838             :         else
    1839             :         {
    1840           0 :             return nPhyPage - pFrm->GetPhyPageNum();
    1841         284 :         }
    1842             :     }
    1843         122 :     return nPhyPage;
    1844             : }
    1845             : 
    1846             : /** Determines and sets those cells which are enclosed by the selection. */
    1847         826 : bool SwRootFrm::MakeTblCrsrs( SwTableCursor& rTblCrsr )
    1848             : {
    1849             :     //Find Union-Rects and tables (Follows) of the selection.
    1850             :     OSL_ENSURE( rTblCrsr.GetCntntNode() && rTblCrsr.GetCntntNode( false ),
    1851             :             "Tabselection nicht auf Cnt." );
    1852             : 
    1853         826 :     bool bRet = false;
    1854             : 
    1855             :     // For new table models there's no need to ask the layout..
    1856         826 :     if( rTblCrsr.NewTableSelection() )
    1857         826 :         return true;
    1858             : 
    1859           0 :     Point aPtPt, aMkPt;
    1860             :     {
    1861           0 :         SwShellCrsr* pShCrsr = dynamic_cast<SwShellCrsr*>(&rTblCrsr);
    1862             : 
    1863           0 :         if( pShCrsr )
    1864             :         {
    1865           0 :             aPtPt = pShCrsr->GetPtPos();
    1866           0 :             aMkPt = pShCrsr->GetMkPos();
    1867             :         }
    1868             :     }
    1869             : 
    1870             :     // #151012# Made code robust here
    1871           0 :     const SwCntntNode* pTmpStartNode = rTblCrsr.GetCntntNode();
    1872           0 :     const SwCntntNode* pTmpEndNode   = rTblCrsr.GetCntntNode(false);
    1873             : 
    1874           0 :     const SwFrm* pTmpStartFrm = pTmpStartNode ? pTmpStartNode->getLayoutFrm( this, &aPtPt, 0, false ) : 0;
    1875           0 :     const SwFrm* pTmpEndFrm   = pTmpEndNode   ?   pTmpEndNode->getLayoutFrm( this, &aMkPt, 0, false ) : 0;
    1876             : 
    1877           0 :     const SwLayoutFrm* pStart = pTmpStartFrm ? pTmpStartFrm->GetUpper() : 0;
    1878           0 :     const SwLayoutFrm* pEnd   = pTmpEndFrm   ? pTmpEndFrm->GetUpper() : 0;
    1879             : 
    1880             :     OSL_ENSURE( pStart && pEnd, "MakeTblCrsrs: Good to have the code robust here!" );
    1881             : 
    1882             :     /* #109590# Only change table boxes if the frames are
    1883             :         valid. Needed because otherwise the table cursor after moving
    1884             :         table cells by dnd resulted in an empty tables cursor.  */
    1885           0 :     if ( pStart && pEnd && pStart->IsValid() && pEnd->IsValid())
    1886             :     {
    1887           0 :         SwSelUnions aUnions;
    1888           0 :         ::MakeSelUnions( aUnions, pStart, pEnd );
    1889             : 
    1890           0 :         SwSelBoxes aNew;
    1891             : 
    1892           0 :         const bool bReadOnlyAvailable = rTblCrsr.IsReadOnlyAvailable();
    1893             : 
    1894           0 :         for ( size_t i = 0; i < aUnions.size(); ++i )
    1895             :         {
    1896           0 :             SwSelUnion *pUnion = &aUnions[i];
    1897           0 :             const SwTabFrm *pTable = pUnion->GetTable();
    1898             : 
    1899             :             // Skip any repeated headlines in the follow:
    1900           0 :             SwLayoutFrm* pRow = pTable->IsFollow() ?
    1901             :                                 pTable->GetFirstNonHeadlineRow() :
    1902           0 :                                 (SwLayoutFrm*)pTable->Lower();
    1903             : 
    1904           0 :             while ( pRow )
    1905             :             {
    1906           0 :                 if ( pRow->Frm().IsOver( pUnion->GetUnion() ) )
    1907             :                 {
    1908           0 :                     const SwLayoutFrm *pCell = pRow->FirstCell();
    1909             : 
    1910           0 :                     while ( pCell && pRow->IsAnLower( pCell ) )
    1911             :                     {
    1912             :                         OSL_ENSURE( pCell->IsCellFrm(), "Frame without cell" );
    1913           0 :                         if( IsFrmInTblSel( pUnion->GetUnion(), pCell ) &&
    1914           0 :                             (bReadOnlyAvailable ||
    1915           0 :                              !pCell->GetFmt()->GetProtect().IsCntntProtected()))
    1916             :                         {
    1917             :                             SwTableBox* pInsBox = (SwTableBox*)
    1918           0 :                                 ((SwCellFrm*)pCell)->GetTabBox();
    1919           0 :                             aNew.insert( pInsBox );
    1920             :                         }
    1921           0 :                         if ( pCell->GetNext() )
    1922             :                         {
    1923           0 :                             pCell = (const SwLayoutFrm*)pCell->GetNext();
    1924           0 :                             if ( pCell->Lower() && pCell->Lower()->IsRowFrm() )
    1925           0 :                                 pCell = pCell->FirstCell();
    1926             :                         }
    1927             :                         else
    1928             :                         {
    1929           0 :                             const SwLayoutFrm* pLastCell = pCell;
    1930           0 :                             do
    1931             :                             {
    1932           0 :                                 pCell = pCell->GetNextLayoutLeaf();
    1933           0 :                             } while ( pCell && pLastCell->IsAnLower( pCell ) );
    1934             :                             // For sections with columns
    1935           0 :                             if( pCell && pCell->IsInTab() )
    1936             :                             {
    1937           0 :                                 while( !pCell->IsCellFrm() )
    1938             :                                 {
    1939           0 :                                     pCell = pCell->GetUpper();
    1940             :                                     OSL_ENSURE( pCell, "Where's my cell?" );
    1941             :                                 }
    1942             :                             }
    1943             :                         }
    1944             :                     }
    1945             :                 }
    1946           0 :                 pRow = (SwLayoutFrm*)pRow->GetNext();
    1947             :             }
    1948             :         }
    1949             : 
    1950           0 :         rTblCrsr.ActualizeSelection( aNew );
    1951           0 :         bRet = true;
    1952             :     }
    1953             : 
    1954           0 :     return bRet;
    1955             : }
    1956             : 
    1957        2410 : inline void Sub( SwRegionRects& rRegion, const SwRect& rRect )
    1958             : {
    1959        4604 :     if( rRect.Width() > 1 && rRect.Height() > 1 &&
    1960        2194 :         rRect.IsOver( rRegion.GetOrigin() ))
    1961        2120 :         rRegion -= rRect;
    1962        2410 : }
    1963             : 
    1964           0 : inline void Add( SwRegionRects& rRegion, const SwRect& rRect )
    1965             : {
    1966           0 :     if( rRect.Width() > 1 && rRect.Height() > 1 )
    1967           0 :         rRegion += rRect;
    1968           0 : }
    1969             : 
    1970             : /*
    1971             :  * The following situations can happen:
    1972             :  *  1. Start and end lie in one screen-row and in the same node
    1973             :  *     -> one rectangle out of start and end; and we're okay
    1974             :  *  2. Start and end lie in one frame (therefore in the same node!)
    1975             :  *     -> expand start to the right, end to the left and if more than two
    1976             :  *        screen-rows are involved - calculate the in-between
    1977             :  *  3. Start and end lie in different frames
    1978             :  *     -> expand start to the right until frame-end, calculate Rect
    1979             :  *        expand end to the left until frame-start, calculate Rect
    1980             :  *        and if more than two frames are involved add the PrtArea of all
    1981             :  *        frames which lie in between
    1982             :  *
    1983             :  * Big reorganization because of the FlyFrm - those need to be locked out.
    1984             :  * Exceptions:  - The Fly in which the selection took place (if it took place
    1985             :  *                 in a Fly)
    1986             :  *              - The Flys which are underrun by the text
    1987             :  *              - The Flys which are anchored to somewhere inside the selection.
    1988             :  * Functioning: First a SwRegion with a root gets initialized.
    1989             :  *              Out of the region the inverted sections are cut out. The
    1990             :  *              section gets compressed and finally inverted and thereby the
    1991             :  *              inverted rectangles are available.
    1992             :  *              In the end the Flys are cut out of the section.
    1993             :  */
    1994        1502 : void SwRootFrm::CalcFrmRects(SwShellCrsr &rCrsr)
    1995             : {
    1996        1502 :     SwPosition *pStartPos = rCrsr.Start(),
    1997        1502 :                *pEndPos   = rCrsr.GetPoint() == pStartPos ? rCrsr.GetMark() : rCrsr.GetPoint();
    1998             : 
    1999        1502 :     SwViewShell *pSh = GetCurrShell();
    2000             : 
    2001             :     // #i12836# enhanced pdf
    2002        1502 :     SwRegionRects aRegion( pSh && !pSh->GetViewOptions()->IsPDFExport() ?
    2003             :                            pSh->VisArea() :
    2004        3004 :                            Frm() );
    2005        4506 :     if( !pStartPos->nNode.GetNode().IsCntntNode() ||
    2006        3004 :         !pStartPos->nNode.GetNode().GetCntntNode()->getLayoutFrm(this) ||
    2007        1766 :         ( pStartPos->nNode != pEndPos->nNode &&
    2008         528 :           ( !pEndPos->nNode.GetNode().IsCntntNode() ||
    2009         264 :             !pEndPos->nNode.GetNode().GetCntntNode()->getLayoutFrm(this) ) ) )
    2010             :     {
    2011        1502 :         return;
    2012             :     }
    2013             : 
    2014             :     //First obtain the CntntFrms for the start and the end - those are needed
    2015             :     //anyway.
    2016        1502 :     SwCntntFrm const* pStartFrm = pStartPos->nNode.GetNode().
    2017        3004 :         GetCntntNode()->getLayoutFrm( this, &rCrsr.GetSttPos(), pStartPos );
    2018             : 
    2019        1502 :     SwCntntFrm const* pEndFrm   = pEndPos->nNode.GetNode().
    2020        3004 :         GetCntntNode()->getLayoutFrm( this, &rCrsr.GetEndPos(), pEndPos );
    2021             : 
    2022             :     OSL_ENSURE( (pStartFrm && pEndFrm), "Keine CntntFrms gefunden." );
    2023             : 
    2024             :     //Do not subtract the FlyFrms in which selected Frames lie.
    2025        3004 :     SwSortedObjs aSortObjs;
    2026        1502 :     if ( pStartFrm->IsInFly() )
    2027             :     {
    2028           0 :         const SwAnchoredObject* pObj = pStartFrm->FindFlyFrm();
    2029             :         OSL_ENSURE( pObj, "No Start Object." );
    2030           0 :         if (pObj) aSortObjs.Insert( *(const_cast<SwAnchoredObject*>(pObj)) );
    2031           0 :         const SwAnchoredObject* pObj2 = pEndFrm->FindFlyFrm();
    2032             :         OSL_ENSURE( pObj2, "SwRootFrm::CalcFrmRects(..) - FlyFrame missing - looks like an invalid selection" );
    2033           0 :         if ( pObj2 != NULL && pObj2 != pObj )
    2034             :         {
    2035           0 :             aSortObjs.Insert( *(const_cast<SwAnchoredObject*>(pObj2)) );
    2036             :         }
    2037             :     }
    2038             : 
    2039             :     // if a selection which is not allowed exists, we correct what is not
    2040             :     // allowed (header/footer/table-headline) for two pages.
    2041             :     do {    // middle check loop
    2042        1502 :         const SwLayoutFrm* pSttLFrm = pStartFrm->GetUpper();
    2043        1502 :         const sal_uInt16 cHdFtTblHd = FRM_HEADER | FRM_FOOTER | FRM_TAB;
    2044       12006 :         while( pSttLFrm &&
    2045        4524 :             ! (cHdFtTblHd & pSttLFrm->GetType() ))
    2046        4478 :             pSttLFrm = pSttLFrm->GetUpper();
    2047        1502 :         if( !pSttLFrm )
    2048        1456 :             break;
    2049          46 :         const SwLayoutFrm* pEndLFrm = pEndFrm->GetUpper();
    2050         366 :         while( pEndLFrm &&
    2051         138 :             ! (cHdFtTblHd & pEndLFrm->GetType() ))
    2052         136 :             pEndLFrm = pEndLFrm->GetUpper();
    2053          46 :         if( !pEndLFrm )
    2054          44 :             break;
    2055             : 
    2056             :         OSL_ENSURE( pEndLFrm->GetType() == pSttLFrm->GetType(),
    2057             :             "Selection over different content" );
    2058           2 :         switch( pSttLFrm->GetType() )
    2059             :         {
    2060             :         case FRM_HEADER:
    2061             :         case FRM_FOOTER:
    2062             :             // On different pages? Then always on the start-page
    2063           0 :             if( pEndLFrm->FindPageFrm() != pSttLFrm->FindPageFrm() )
    2064             :             {
    2065             :                 // Set end- to the start-CntntFrame
    2066           0 :                 if( pStartPos == rCrsr.GetPoint() )
    2067           0 :                     pEndFrm = pStartFrm;
    2068             :                 else
    2069           0 :                     pStartFrm = pEndFrm;
    2070             :             }
    2071           0 :             break;
    2072             :         case FRM_TAB:
    2073             :             // On different pages? Then check for table-headline
    2074             :             {
    2075           2 :                 const SwTabFrm* pTabFrm = (SwTabFrm*)pSttLFrm;
    2076           6 :                 if( ( pTabFrm->GetFollow() ||
    2077           2 :                     ((SwTabFrm*)pEndLFrm)->GetFollow() ) &&
    2078           0 :                     pTabFrm->GetTable()->GetRowsToRepeat() > 0 &&
    2079           2 :                     pTabFrm->GetLower() != ((SwTabFrm*)pEndLFrm)->GetLower() &&
    2080           0 :                     ( lcl_IsInRepeatedHeadline( pStartFrm ) ||
    2081           0 :                     lcl_IsInRepeatedHeadline( pEndFrm ) ) )
    2082             :                 {
    2083             :                     // Set end- to the start-CntntFrame
    2084           0 :                     if( pStartPos == rCrsr.GetPoint() )
    2085           0 :                         pEndFrm = pStartFrm;
    2086             :                     else
    2087           0 :                         pStartFrm = pEndFrm;
    2088             :                 }
    2089             :             }
    2090           2 :             break;
    2091             :         }
    2092             :     } while( false );
    2093             : 
    2094        1502 :     SwCrsrMoveState aTmpState( MV_NONE );
    2095        1502 :     aTmpState.b2Lines = true;
    2096        1502 :     aTmpState.bNoScroll = true;
    2097        1502 :     aTmpState.nCursorBidiLevel = pStartFrm->IsRightToLeft() ? 1 : 0;
    2098             : 
    2099             :     //CntntRects to Start- and EndFrms.
    2100        1502 :     SwRect aStRect, aEndRect;
    2101        1502 :     pStartFrm->GetCharRect( aStRect, *pStartPos, &aTmpState );
    2102        1502 :     Sw2LinesPos *pSt2Pos = aTmpState.p2Lines;
    2103        1502 :     aTmpState.p2Lines = NULL;
    2104        1502 :     aTmpState.nCursorBidiLevel = pEndFrm->IsRightToLeft() ? 1 : 0;
    2105             : 
    2106        1502 :     pEndFrm->GetCharRect( aEndRect, *pEndPos, &aTmpState );
    2107        1502 :     Sw2LinesPos *pEnd2Pos = aTmpState.p2Lines;
    2108             : 
    2109        1502 :     SwRect aStFrm ( pStartFrm->UnionFrm( true ) );
    2110        1502 :     aStFrm.Intersection( pStartFrm->PaintArea() );
    2111        1502 :     SwRect aEndFrm( pStartFrm == pEndFrm ? aStFrm : pEndFrm->UnionFrm( true ) );
    2112        1502 :     if( pStartFrm != pEndFrm )
    2113             :     {
    2114         270 :         aEndFrm.Intersection( pEndFrm->PaintArea() );
    2115             :     }
    2116        1502 :     SWRECTFN( pStartFrm )
    2117        1502 :     const bool bR2L = pStartFrm->IsRightToLeft();
    2118        1502 :     const bool bEndR2L = pEndFrm->IsRightToLeft();
    2119             : 
    2120             :     // If there's no doubleline portion involved or start and end are both
    2121             :     // in the same doubleline portion, all works fine, but otherwise
    2122             :     // we need the following...
    2123        1502 :     if( pSt2Pos != pEnd2Pos && ( !pSt2Pos || !pEnd2Pos ||
    2124           0 :         pSt2Pos->aPortion != pEnd2Pos->aPortion ) )
    2125             :     {
    2126             :         // If we have a start(end) position inside a doubleline portion
    2127             :         // the surrounded part of the doubleline portion is subtracted
    2128             :         // from the region and the aStRect(aEndRect) is set to the
    2129             :         // end(start) of the doubleline portion.
    2130         136 :         if( pSt2Pos )
    2131             :         {
    2132           0 :             SwRect aTmp( aStRect );
    2133             : 
    2134             :             // BiDi-Portions are swimming against the current.
    2135           0 :             const bool bPorR2L = ( MT_BIDI == pSt2Pos->nMultiType ) ?
    2136             :                 ! bR2L :
    2137           0 :             bR2L;
    2138             : 
    2139           0 :             if( MT_BIDI == pSt2Pos->nMultiType &&
    2140           0 :                 (pSt2Pos->aPortion2.*fnRect->fnGetWidth)() )
    2141             :             {
    2142             :                 // nested bidi portion
    2143           0 :                 long nRightAbs = (pSt2Pos->aPortion.*fnRect->fnGetRight)();
    2144           0 :                 nRightAbs -= (pSt2Pos->aPortion2.*fnRect->fnGetLeft)();
    2145           0 :                 long nLeftAbs = nRightAbs - (pSt2Pos->aPortion2.*fnRect->fnGetWidth)();
    2146             : 
    2147           0 :                 (aTmp.*fnRect->fnSetRight)( nRightAbs );
    2148             : 
    2149           0 :                 if ( ! pEnd2Pos || pEnd2Pos->aPortion != pSt2Pos->aPortion )
    2150             :                 {
    2151           0 :                     SwRect aTmp2( pSt2Pos->aPortion );
    2152           0 :                     (aTmp2.*fnRect->fnSetRight)( nLeftAbs );
    2153           0 :                     aTmp2.Intersection( aEndFrm );
    2154           0 :                     Sub( aRegion, aTmp2 );
    2155             :                 }
    2156             :             }
    2157             :             else
    2158             :             {
    2159           0 :                 if( bPorR2L )
    2160             :                     (aTmp.*fnRect->fnSetLeft)(
    2161           0 :                         (pSt2Pos->aPortion.*fnRect->fnGetLeft)() );
    2162             :                 else
    2163             :                     (aTmp.*fnRect->fnSetRight)(
    2164           0 :                         (pSt2Pos->aPortion.*fnRect->fnGetRight)() );
    2165             :             }
    2166             : 
    2167           0 :             if( MT_ROT_90 == pSt2Pos->nMultiType ||
    2168           0 :                 (pSt2Pos->aPortion.*fnRect->fnGetTop)() ==
    2169           0 :                 (aTmp.*fnRect->fnGetTop)() )
    2170             :             {
    2171             :                 (aTmp.*fnRect->fnSetTop)(
    2172           0 :                     (pSt2Pos->aLine.*fnRect->fnGetTop)() );
    2173             :             }
    2174             : 
    2175           0 :             aTmp.Intersection( aStFrm );
    2176           0 :             Sub( aRegion, aTmp );
    2177             : 
    2178           0 :             SwTwips nTmp = (pSt2Pos->aLine.*fnRect->fnGetBottom)();
    2179           0 :             if( MT_ROT_90 != pSt2Pos->nMultiType &&
    2180           0 :                 (aStRect.*fnRect->fnBottomDist)( nTmp ) > 0 )
    2181             :             {
    2182           0 :                 (aTmp.*fnRect->fnSetTop)( (aTmp.*fnRect->fnGetBottom)() );
    2183           0 :                 (aTmp.*fnRect->fnSetBottom)( nTmp );
    2184           0 :                 if( (aStRect.*fnRect->fnBottomDist)(
    2185           0 :                     (pSt2Pos->aPortion.*fnRect->fnGetBottom)() ) > 0 )
    2186             :                 {
    2187           0 :                     if( bPorR2L )
    2188             :                         (aTmp.*fnRect->fnSetRight)(
    2189           0 :                             (pSt2Pos->aPortion.*fnRect->fnGetRight)() );
    2190             :                     else
    2191             :                         (aTmp.*fnRect->fnSetLeft)(
    2192           0 :                             (pSt2Pos->aPortion.*fnRect->fnGetLeft)() );
    2193             :                 }
    2194           0 :                 aTmp.Intersection( aStFrm );
    2195           0 :                 Sub( aRegion, aTmp );
    2196             :             }
    2197             : 
    2198           0 :             aStRect = pSt2Pos->aLine;
    2199             :             (aStRect.*fnRect->fnSetLeft)( bR2L ?
    2200           0 :                     (pSt2Pos->aPortion.*fnRect->fnGetLeft)() :
    2201           0 :                     (pSt2Pos->aPortion.*fnRect->fnGetRight)() );
    2202           0 :             (aStRect.*fnRect->fnSetWidth)( 1 );
    2203             :         }
    2204             : 
    2205         136 :         if( pEnd2Pos )
    2206             :         {
    2207         136 :             SWRECTFNX( pEndFrm )
    2208         136 :             SwRect aTmp( aEndRect );
    2209             : 
    2210             :             // BiDi-Portions are swimming against the current.
    2211         136 :             const bool bPorR2L = ( MT_BIDI == pEnd2Pos->nMultiType ) ?
    2212             :                                        ! bEndR2L :
    2213         136 :                                          bEndR2L;
    2214             : 
    2215         136 :             if( MT_BIDI == pEnd2Pos->nMultiType &&
    2216           0 :                 (pEnd2Pos->aPortion2.*fnRectX->fnGetWidth)() )
    2217             :             {
    2218             :                 // nested bidi portion
    2219           0 :                 long nRightAbs = (pEnd2Pos->aPortion.*fnRectX->fnGetRight)();
    2220           0 :                 nRightAbs = nRightAbs - (pEnd2Pos->aPortion2.*fnRectX->fnGetLeft)();
    2221           0 :                 long nLeftAbs = nRightAbs - (pEnd2Pos->aPortion2.*fnRectX->fnGetWidth)();
    2222             : 
    2223           0 :                 (aTmp.*fnRectX->fnSetLeft)( nLeftAbs );
    2224             : 
    2225           0 :                 if ( ! pSt2Pos || pSt2Pos->aPortion != pEnd2Pos->aPortion )
    2226             :                 {
    2227           0 :                     SwRect aTmp2( pEnd2Pos->aPortion );
    2228           0 :                     (aTmp2.*fnRectX->fnSetLeft)( nRightAbs );
    2229           0 :                     aTmp2.Intersection( aEndFrm );
    2230           0 :                     Sub( aRegion, aTmp2 );
    2231             :                 }
    2232             :             }
    2233             :             else
    2234             :             {
    2235         136 :                 if ( bPorR2L )
    2236             :                     (aTmp.*fnRectX->fnSetRight)(
    2237           0 :                         (pEnd2Pos->aPortion.*fnRectX->fnGetRight)() );
    2238             :                 else
    2239             :                     (aTmp.*fnRectX->fnSetLeft)(
    2240         136 :                         (pEnd2Pos->aPortion.*fnRectX->fnGetLeft)() );
    2241             :             }
    2242             : 
    2243         272 :             if( MT_ROT_90 == pEnd2Pos->nMultiType ||
    2244         136 :                 (pEnd2Pos->aPortion.*fnRectX->fnGetBottom)() ==
    2245         136 :                 (aEndRect.*fnRectX->fnGetBottom)() )
    2246             :             {
    2247             :                 (aTmp.*fnRectX->fnSetBottom)(
    2248          48 :                     (pEnd2Pos->aLine.*fnRectX->fnGetBottom)() );
    2249             :             }
    2250             : 
    2251         136 :             aTmp.Intersection( aEndFrm );
    2252         136 :             Sub( aRegion, aTmp );
    2253             : 
    2254             :             // The next statement means neither ruby nor rotate(90):
    2255         136 :             if( !( MT_RUBY & pEnd2Pos->nMultiType ) )
    2256             :             {
    2257          30 :                 SwTwips nTmp = (pEnd2Pos->aLine.*fnRectX->fnGetTop)();
    2258          30 :                 if( (aEndRect.*fnRectX->fnGetTop)() != nTmp )
    2259             :                 {
    2260             :                     (aTmp.*fnRectX->fnSetBottom)(
    2261          30 :                         (aTmp.*fnRectX->fnGetTop)() );
    2262          30 :                     (aTmp.*fnRectX->fnSetTop)( nTmp );
    2263          60 :                     if( (aEndRect.*fnRectX->fnGetTop)() !=
    2264          30 :                         (pEnd2Pos->aPortion.*fnRectX->fnGetTop)() )
    2265             :                     {
    2266          30 :                         if( bPorR2L )
    2267             :                             (aTmp.*fnRectX->fnSetLeft)(
    2268           0 :                                 (pEnd2Pos->aPortion.*fnRectX->fnGetLeft)() );
    2269             :                         else
    2270             :                             (aTmp.*fnRectX->fnSetRight)(
    2271          30 :                                 (pEnd2Pos->aPortion.*fnRectX->fnGetRight)() );
    2272             :                     }
    2273          30 :                     aTmp.Intersection( aEndFrm );
    2274          30 :                     Sub( aRegion, aTmp );
    2275             :                 }
    2276             :             }
    2277             : 
    2278         136 :             aEndRect = pEnd2Pos->aLine;
    2279             :             (aEndRect.*fnRectX->fnSetLeft)( bEndR2L ?
    2280           0 :                     (pEnd2Pos->aPortion.*fnRectX->fnGetRight)() :
    2281         136 :                     (pEnd2Pos->aPortion.*fnRectX->fnGetLeft)() );
    2282         136 :             (aEndRect.*fnRectX->fnSetWidth)( 1 );
    2283             :         }
    2284             :     }
    2285        1366 :     else if( pSt2Pos && pEnd2Pos &&
    2286           0 :              MT_BIDI == pSt2Pos->nMultiType &&
    2287           0 :              MT_BIDI == pEnd2Pos->nMultiType &&
    2288        1366 :              pSt2Pos->aPortion == pEnd2Pos->aPortion &&
    2289           0 :              pSt2Pos->aPortion2 != pEnd2Pos->aPortion2 )
    2290             :     {
    2291             :         // This is the ugly special case, where the selection starts and
    2292             :         // ends in the same bidi portion but one start or end is inside a
    2293             :         // nested bidi portion.
    2294             : 
    2295           0 :         if ( (pSt2Pos->aPortion2.*fnRect->fnGetWidth)() )
    2296             :         {
    2297           0 :             SwRect aTmp( aStRect );
    2298           0 :             long nRightAbs = (pSt2Pos->aPortion.*fnRect->fnGetRight)();
    2299           0 :             nRightAbs -= (pSt2Pos->aPortion2.*fnRect->fnGetLeft)();
    2300           0 :             long nLeftAbs = nRightAbs - (pSt2Pos->aPortion2.*fnRect->fnGetWidth)();
    2301             : 
    2302           0 :             (aTmp.*fnRect->fnSetRight)( nRightAbs );
    2303           0 :             aTmp.Intersection( aStFrm );
    2304           0 :             Sub( aRegion, aTmp );
    2305             : 
    2306           0 :             aStRect = pSt2Pos->aLine;
    2307           0 :             (aStRect.*fnRect->fnSetLeft)( bR2L ? nRightAbs : nLeftAbs );
    2308           0 :             (aStRect.*fnRect->fnSetWidth)( 1 );
    2309             :         }
    2310             : 
    2311           0 :         SWRECTFNX( pEndFrm )
    2312           0 :         if ( (pEnd2Pos->aPortion2.*fnRectX->fnGetWidth)() )
    2313             :         {
    2314           0 :             SwRect aTmp( aEndRect );
    2315           0 :             long nRightAbs = (pEnd2Pos->aPortion.*fnRectX->fnGetRight)();
    2316           0 :             nRightAbs -= (pEnd2Pos->aPortion2.*fnRectX->fnGetLeft)();
    2317           0 :             long nLeftAbs = nRightAbs - (pEnd2Pos->aPortion2.*fnRectX->fnGetWidth)();
    2318             : 
    2319           0 :             (aTmp.*fnRectX->fnSetLeft)( nLeftAbs );
    2320           0 :             aTmp.Intersection( aEndFrm );
    2321           0 :             Sub( aRegion, aTmp );
    2322             : 
    2323           0 :             aEndRect = pEnd2Pos->aLine;
    2324           0 :             (aEndRect.*fnRectX->fnSetLeft)( bEndR2L ? nLeftAbs : nRightAbs );
    2325           0 :             (aEndRect.*fnRectX->fnSetWidth)( 1 );
    2326             :         }
    2327             :     }
    2328             : 
    2329             :     // The charrect may be outside the paintarea (for cursortravelling)
    2330             :     // but the selection has to be restricted to the paintarea
    2331        1502 :     if( aStRect.Left() < aStFrm.Left() )
    2332           2 :         aStRect.Left( aStFrm.Left() );
    2333        1500 :     else if( aStRect.Left() > aStFrm.Right() )
    2334           0 :         aStRect.Left( aStFrm.Right() );
    2335        1502 :     SwTwips nTmp = aStRect.Right();
    2336        1502 :     if( nTmp < aStFrm.Left() )
    2337           2 :         aStRect.Right( aStFrm.Left() );
    2338        1500 :     else if( nTmp > aStFrm.Right() )
    2339           0 :         aStRect.Right( aStFrm.Right() );
    2340        1502 :     if( aEndRect.Left() < aEndFrm.Left() )
    2341           2 :         aEndRect.Left( aEndFrm.Left() );
    2342        1500 :     else if( aEndRect.Left() > aEndFrm.Right() )
    2343           0 :         aEndRect.Left( aEndFrm.Right() );
    2344        1502 :     nTmp = aEndRect.Right();
    2345        1502 :     if( nTmp < aEndFrm.Left() )
    2346           2 :         aEndRect.Right( aEndFrm.Left() );
    2347        1500 :     else if( nTmp > aEndFrm.Right() )
    2348           0 :         aEndRect.Right( aEndFrm.Right() );
    2349             : 
    2350        1502 :     if( pStartFrm == pEndFrm )
    2351             :     {
    2352           0 :         bool bSameRotatedOrBidi = pSt2Pos && pEnd2Pos &&
    2353        1232 :             ( MT_BIDI & pSt2Pos->nMultiType ) &&
    2354        1232 :             pSt2Pos->aPortion == pEnd2Pos->aPortion;
    2355             :         //case 1: (Same frame and same row)
    2356        2464 :         if( bSameRotatedOrBidi ||
    2357        1232 :             (aStRect.*fnRect->fnGetTop)() == (aEndRect.*fnRect->fnGetTop)() )
    2358             :         {
    2359        1162 :             Point aTmpSt( aStRect.Pos() );
    2360        1162 :             Point aTmpEnd( aEndRect.Right(), aEndRect.Bottom() );
    2361        1162 :             if( bSameRotatedOrBidi || bR2L )
    2362             :             {
    2363           0 :                 if( aTmpSt.Y() > aTmpEnd.Y() )
    2364             :                 {
    2365           0 :                     long nTmpY = aTmpEnd.Y();
    2366           0 :                     aTmpEnd.Y() = aTmpSt.Y();
    2367           0 :                     aTmpSt.Y() = nTmpY;
    2368             :                 }
    2369           0 :                 if( aTmpSt.X() > aTmpEnd.X() )
    2370             :                 {
    2371           0 :                     long nTmpX = aTmpEnd.X();
    2372           0 :                     aTmpEnd.X() = aTmpSt.X();
    2373           0 :                     aTmpSt.X() = nTmpX;
    2374             :                 }
    2375             :             }
    2376             : 
    2377        1162 :             SwRect aTmp = SwRect( aTmpSt, aTmpEnd );
    2378             :             // Bug 34888: If content is selected which doesn't take space
    2379             :             //            away (i.e. PostIts, RefMarks, TOXMarks), then at
    2380             :             //            least set the width of the Crsr.
    2381        1330 :             if( 1 == (aTmp.*fnRect->fnGetWidth)() &&
    2382         168 :                 pStartPos->nContent.GetIndex() !=
    2383         168 :                 pEndPos->nContent.GetIndex() )
    2384             :             {
    2385         138 :                 OutputDevice* pOut = pSh->GetOut();
    2386         138 :                 long nCrsrWidth = pOut->GetSettings().GetStyleSettings().
    2387         138 :                     GetCursorSize();
    2388             :                 (aTmp.*fnRect->fnSetWidth)( pOut->PixelToLogic(
    2389         138 :                     Size( nCrsrWidth, 0 ) ).Width() );
    2390             :             }
    2391        1162 :             aTmp.Intersection( aStFrm );
    2392        1162 :             Sub( aRegion, aTmp );
    2393             :         }
    2394             :         //case 2: (Same frame, but not the same line)
    2395             :         else
    2396             :         {
    2397             :             SwTwips lLeft, lRight;
    2398          70 :             if( pSt2Pos && pEnd2Pos && pSt2Pos->aPortion == pEnd2Pos->aPortion )
    2399             :             {
    2400           0 :                 lLeft = (pSt2Pos->aPortion.*fnRect->fnGetLeft)();
    2401           0 :                 lRight = (pSt2Pos->aPortion.*fnRect->fnGetRight)();
    2402             :             }
    2403             :             else
    2404             :             {
    2405          70 :                 lLeft = (pStartFrm->Frm().*fnRect->fnGetLeft)() +
    2406          70 :                     (pStartFrm->Prt().*fnRect->fnGetLeft)();
    2407          70 :                 lRight = (pStartFrm->Frm().*fnRect->fnGetLeft)() +
    2408          70 :                     (pStartFrm->Prt().*fnRect->fnGetRight)();
    2409             :             }
    2410          70 :             if( lLeft < (aStFrm.*fnRect->fnGetLeft)() )
    2411           0 :                 lLeft = (aStFrm.*fnRect->fnGetLeft)();
    2412          70 :             if( lRight > (aStFrm.*fnRect->fnGetRight)() )
    2413           0 :                 lRight = (aStFrm.*fnRect->fnGetRight)();
    2414          70 :             SwRect aSubRect( aStRect );
    2415             :             //First line
    2416          70 :             if( bR2L )
    2417           0 :                 (aSubRect.*fnRect->fnSetLeft)( lLeft );
    2418             :             else
    2419          70 :                 (aSubRect.*fnRect->fnSetRight)( lRight );
    2420          70 :             Sub( aRegion, aSubRect );
    2421             : 
    2422             :             //If there's at least a twips between start- and endline,
    2423             :             //so the whole area between will be added.
    2424          70 :             SwTwips aTmpBottom = (aStRect.*fnRect->fnGetBottom)();
    2425          70 :             SwTwips aTmpTop = (aEndRect.*fnRect->fnGetTop)();
    2426          70 :             if( aTmpBottom != aTmpTop )
    2427             :             {
    2428          10 :                 (aSubRect.*fnRect->fnSetLeft)( lLeft );
    2429          10 :                 (aSubRect.*fnRect->fnSetRight)( lRight );
    2430          10 :                 (aSubRect.*fnRect->fnSetTop)( aTmpBottom );
    2431          10 :                 (aSubRect.*fnRect->fnSetBottom)( aTmpTop );
    2432          10 :                 Sub( aRegion, aSubRect );
    2433             :             }
    2434             :             //and the last line
    2435          70 :             aSubRect = aEndRect;
    2436          70 :             if( bR2L )
    2437           0 :                 (aSubRect.*fnRect->fnSetRight)( lRight );
    2438             :             else
    2439          70 :                 (aSubRect.*fnRect->fnSetLeft)( lLeft );
    2440          70 :             Sub( aRegion, aSubRect );
    2441             :         }
    2442             :     }
    2443             :     //case 3: (Different frames, maybe with other frames between)
    2444             :     else
    2445             :     {
    2446             :         //The startframe first...
    2447         270 :         SwRect aSubRect( aStRect );
    2448         270 :         if( bR2L )
    2449           0 :             (aSubRect.*fnRect->fnSetLeft)( (aStFrm.*fnRect->fnGetLeft)());
    2450             :         else
    2451         270 :             (aSubRect.*fnRect->fnSetRight)( (aStFrm.*fnRect->fnGetRight)());
    2452         270 :         Sub( aRegion, aSubRect );
    2453         270 :         SwTwips nTmpTwips = (aStRect.*fnRect->fnGetBottom)();
    2454         270 :         if( (aStFrm.*fnRect->fnGetBottom)() != nTmpTwips )
    2455             :         {
    2456          80 :             aSubRect = aStFrm;
    2457          80 :             (aSubRect.*fnRect->fnSetTop)( nTmpTwips );
    2458          80 :             Sub( aRegion, aSubRect );
    2459             :         }
    2460             : 
    2461             :         //Now the frames between, if there are any
    2462         270 :         bool const bBody = pStartFrm->IsInDocBody();
    2463         270 :         const SwTableBox* pCellBox = pStartFrm->GetUpper()->IsCellFrm() ?
    2464         270 :             ((SwCellFrm*)pStartFrm->GetUpper())->GetTabBox() : 0;
    2465         270 :         if (pSh->IsSelectAll())
    2466          44 :             pCellBox = 0;
    2467             : 
    2468         270 :         const SwCntntFrm *pCntnt = pStartFrm->GetNextCntntFrm();
    2469         270 :         SwRect aPrvRect;
    2470             : 
    2471             :         OSL_ENSURE( pCntnt,
    2472             :             "<SwRootFrm::CalcFrmRects(..)> - no content frame. This is a serious defect -> please inform OD" );
    2473         816 :         while ( pCntnt && pCntnt != pEndFrm )
    2474             :         {
    2475         276 :             if ( pCntnt->IsInFly() )
    2476             :             {
    2477           0 :                 const SwAnchoredObject* pObj = pCntnt->FindFlyFrm();
    2478           0 :                 aSortObjs.Insert( *(const_cast<SwAnchoredObject*>(pObj)) );
    2479             :             }
    2480             : 
    2481             :             // Consider only frames which have the same IsInDocBody value like pStartFrm
    2482             :             // If pStartFrm is inside a SwCellFrm, consider only frames which are inside the
    2483             :             // same cell frame (or its follow cell)
    2484         276 :             const SwTableBox* pTmpCellBox = pCntnt->GetUpper()->IsCellFrm() ?
    2485         276 :                 ((SwCellFrm*)pCntnt->GetUpper())->GetTabBox() : 0;
    2486         276 :             if (pSh->IsSelectAll())
    2487          92 :                 pTmpCellBox = 0;
    2488         552 :             if ( bBody == pCntnt->IsInDocBody() &&
    2489           0 :                 ( !pCellBox || pCellBox == pTmpCellBox ) )
    2490             :             {
    2491         276 :                 SwRect aCRect( pCntnt->UnionFrm( true ) );
    2492         276 :                 aCRect.Intersection( pCntnt->PaintArea() );
    2493         276 :                 if( aCRect.IsOver( aRegion.GetOrigin() ))
    2494             :                 {
    2495         208 :                     SwRect aTmp( aPrvRect );
    2496         208 :                     aTmp.Union( aCRect );
    2497         624 :                     if ( (aPrvRect.Height() * aPrvRect.Width() +
    2498         208 :                         aCRect.Height()   * aCRect.Width()) ==
    2499         208 :                         (aTmp.Height() * aTmp.Width()) )
    2500             :                     {
    2501          22 :                         aPrvRect.Union( aCRect );
    2502             :                     }
    2503             :                     else
    2504             :                     {
    2505         186 :                         if ( aPrvRect.HasArea() )
    2506          60 :                             Sub( aRegion, aPrvRect );
    2507         186 :                         aPrvRect = aCRect;
    2508             :                     }
    2509             :                 }
    2510             :             }
    2511         276 :             pCntnt = pCntnt->GetNextCntntFrm();
    2512             :             OSL_ENSURE( pCntnt,
    2513             :                 "<SwRootFrm::CalcFrmRects(..)> - no content frame. This is a serious defect!" );
    2514             :         }
    2515         270 :         if ( aPrvRect.HasArea() )
    2516         126 :             Sub( aRegion, aPrvRect );
    2517             : 
    2518             :         //At least the endframe...
    2519         270 :         bVert = pEndFrm->IsVertical();
    2520         270 :         bRev = pEndFrm->IsReverse();
    2521           0 :         fnRect = bVert ? ( bRev ? fnRectVL2R : ( pEndFrm->IsVertLR() ? fnRectVertL2R : fnRectVert ) ) :
    2522         270 :             ( bRev ? fnRectB2T : fnRectHori );
    2523         270 :         nTmpTwips = (aEndRect.*fnRect->fnGetTop)();
    2524         270 :         if( (aEndFrm.*fnRect->fnGetTop)() != nTmpTwips )
    2525             :         {
    2526         126 :             aSubRect = aEndFrm;
    2527         126 :             (aSubRect.*fnRect->fnSetBottom)( nTmpTwips );
    2528         126 :             Sub( aRegion, aSubRect );
    2529             :         }
    2530         270 :         aSubRect = aEndRect;
    2531         270 :         if( bEndR2L )
    2532           0 :             (aSubRect.*fnRect->fnSetRight)((aEndFrm.*fnRect->fnGetRight)());
    2533             :         else
    2534         270 :             (aSubRect.*fnRect->fnSetLeft)( (aEndFrm.*fnRect->fnGetLeft)() );
    2535         270 :         Sub( aRegion, aSubRect );
    2536             :     }
    2537             : 
    2538        1502 :     aRegion.Invert();
    2539        1502 :     delete pSt2Pos;
    2540        1502 :     delete pEnd2Pos;
    2541             : 
    2542             :     // Cut out Flys during loop. We don't cut out Flys when:
    2543             :     // - the Lower is StartFrm/EndFrm (FlyInCnt and all other Flys which again
    2544             :     //   sit in it)
    2545             :     // - if in the Z-order we have Flys above those in which the StartFrm is
    2546             :     //   placed
    2547             :     // - if they are anchored to inside the selection and thus part of it
    2548        1502 :     const SwPageFrm *pPage      = pStartFrm->FindPageFrm();
    2549        1502 :     const SwPageFrm *pEndPage   = pEndFrm->FindPageFrm();
    2550             : 
    2551        3018 :     while ( pPage )
    2552             :     {
    2553        1516 :         if ( pPage->GetSortedObjs() )
    2554             :         {
    2555           0 :             const SwSortedObjs &rObjs = *pPage->GetSortedObjs();
    2556           0 :             for ( size_t i = 0; i < rObjs.size(); ++i )
    2557             :             {
    2558           0 :                 SwAnchoredObject* pAnchoredObj = rObjs[i];
    2559           0 :                 if ( !pAnchoredObj->ISA(SwFlyFrm) )
    2560           0 :                     continue;
    2561           0 :                 const SwFlyFrm* pFly = static_cast<const SwFlyFrm*>(pAnchoredObj);
    2562           0 :                 const SwVirtFlyDrawObj* pObj = pFly->GetVirtDrawObj();
    2563           0 :                 const SwFmtSurround &rSur = pFly->GetFmt()->GetSurround();
    2564           0 :                 const SwPosition* anchoredAt = pAnchoredObj->GetFrmFmt().GetAnchor().GetCntntAnchor();
    2565           0 :                 bool inSelection = ( anchoredAt != NULL && *pStartPos <= *anchoredAt && *anchoredAt < *pEndPos );
    2566           0 :                 if( anchoredAt != NULL && *anchoredAt == *pEndPos )
    2567             :                 {
    2568           0 :                     const SwNodes& nodes = anchoredAt->GetDoc()->GetNodes();
    2569           0 :                     if( *pEndPos == SwPosition( nodes.GetEndOfContent()))
    2570           0 :                         inSelection = true;
    2571             :                     else
    2572             :                     {
    2573           0 :                         SwNodeIndex idx( nodes.GetEndOfContent());
    2574           0 :                      if( SwCntntNode* last = nodes.GoPrevious( &idx ))
    2575           0 :                         inSelection = *pEndPos == SwPosition( *last, last->Len());
    2576             :                     }
    2577             :                 }
    2578           0 :                 if( inSelection )
    2579           0 :                         Add( aRegion, pFly->Frm() );
    2580           0 :                 else if ( !pFly->IsAnLower( pStartFrm ) &&
    2581           0 :                     (rSur.GetSurround() != SURROUND_THROUGHT &&
    2582           0 :                     !rSur.IsContour()) )
    2583             :                 {
    2584           0 :                     if ( aSortObjs.Contains( *pAnchoredObj ) )
    2585           0 :                         continue;
    2586             : 
    2587           0 :                     bool bSub = true;
    2588           0 :                     const sal_uInt32 nPos = pObj->GetOrdNum();
    2589           0 :                     for ( size_t k = 0; bSub && k < aSortObjs.size(); ++k )
    2590             :                     {
    2591             :                         OSL_ENSURE( aSortObjs[k]->ISA(SwFlyFrm),
    2592             :                             "<SwRootFrm::CalcFrmRects(..)> - object in <aSortObjs> of unexpected type" );
    2593           0 :                         const SwFlyFrm* pTmp = static_cast<SwFlyFrm*>(aSortObjs[k]);
    2594           0 :                         do
    2595             :                         {
    2596           0 :                             if ( nPos < pTmp->GetVirtDrawObj()->GetOrdNumDirect() )
    2597             :                             {
    2598           0 :                                 bSub = false;
    2599             :                             }
    2600             :                             else
    2601             :                             {
    2602           0 :                                 pTmp = pTmp->GetAnchorFrm()->FindFlyFrm();
    2603             :                             }
    2604           0 :                         } while ( bSub && pTmp );
    2605             :                     }
    2606           0 :                     if ( bSub )
    2607           0 :                         Sub( aRegion, pFly->Frm() );
    2608             :                 }
    2609             :             }
    2610             :         }
    2611        1516 :         if ( pPage == pEndPage )
    2612        1502 :             break;
    2613             :         else
    2614          14 :             pPage = (SwPageFrm*)pPage->GetNext();
    2615             :     }
    2616             : 
    2617             :     //Because it looks better, we close the DropCaps.
    2618        1502 :     SwRect aDropRect;
    2619        1502 :     if ( pStartFrm->IsTxtFrm() )
    2620             :     {
    2621        1502 :         if ( ((SwTxtFrm*)pStartFrm)->GetDropRect( aDropRect ) )
    2622           0 :             Sub( aRegion, aDropRect );
    2623             :     }
    2624        1502 :     if ( pEndFrm != pStartFrm && pEndFrm->IsTxtFrm() )
    2625             :     {
    2626         270 :         if ( ((SwTxtFrm*)pEndFrm)->GetDropRect( aDropRect ) )
    2627           0 :             Sub( aRegion, aDropRect );
    2628             :     }
    2629             : 
    2630        3004 :     rCrsr.assign( aRegion.begin(), aRegion.end() );
    2631         270 : }
    2632             : 
    2633             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10