LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sw/source/core/layout - trvlfrm.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 590 1310 45.0 %
Date: 2013-07-09 Functions: 30 50 60.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <hintids.hxx>
      21             : #include <hints.hxx>
      22             : #include <tools/bigint.hxx>
      23             : #include <tools/line.hxx>
      24             : #include <editeng/opaqitem.hxx>
      25             : #include <editeng/protitem.hxx>
      26             : #include <vcl/settings.hxx>
      27             : #include <vcl/outdev.hxx>
      28             : #include <fmtpdsc.hxx>
      29             : #include <fmtsrnd.hxx>
      30             : #include <pagedesc.hxx>
      31             : #include <pagefrm.hxx>
      32             : #include <rootfrm.hxx>
      33             : #include <cntfrm.hxx>
      34             : #include <ftnfrm.hxx>
      35             : #include <flyfrm.hxx>
      36             : #include <tabfrm.hxx>
      37             : #include <rowfrm.hxx>
      38             : #include <cellfrm.hxx>
      39             : #include <txtfrm.hxx>
      40             : #include <viewsh.hxx>
      41             : #include <viewopt.hxx>
      42             : #include <doc.hxx>
      43             : #include <viscrs.hxx>
      44             : #include <frmfmt.hxx>
      45             : #include <swtable.hxx>
      46             : #include <dflyobj.hxx>
      47             : #include <crstate.hxx>
      48             : #include <frmtool.hxx>
      49             : #include <ndtxt.hxx>
      50             : #include <dcontact.hxx>
      51             : // OD 2004-05-24 #i28701#
      52             : #include <sortedobjs.hxx>
      53             : #include <txatbase.hxx>
      54             : #include <fmtfld.hxx>
      55             : #include <fldbas.hxx>
      56             : 
      57             : // FLT_MAX
      58             : #include <cfloat>
      59             : #include <swselectionlist.hxx>
      60             : 
      61             : #include <basegfx/numeric/ftools.hxx>
      62             : 
      63             : namespace {
      64           0 :     bool lcl_GetCrsrOfst_Objects( const SwPageFrm* pPageFrm, bool bSearchBackground,
      65             :            SwPosition *pPos, Point& rPoint, SwCrsrMoveState* pCMS  )
      66             :     {
      67           0 :         bool bRet = false;
      68           0 :         Point aPoint( rPoint );
      69           0 :         SwOrderIter aIter( pPageFrm );
      70           0 :         aIter.Top();
      71           0 :         while ( aIter() )
      72             :         {
      73             :             const SwVirtFlyDrawObj* pObj =
      74           0 :                                 static_cast<const SwVirtFlyDrawObj*>(aIter());
      75           0 :             const SwAnchoredObject* pAnchoredObj = GetUserCall( aIter() )->GetAnchoredObj( aIter() );
      76           0 :             const SwFmtSurround& rSurround = pAnchoredObj->GetFrmFmt().GetSurround();
      77           0 :             const SvxOpaqueItem& rOpaque = pAnchoredObj->GetFrmFmt().GetOpaque();
      78           0 :             bool bInBackground = ( rSurround.GetSurround() == SURROUND_THROUGHT ) && !rOpaque.GetValue();
      79             : 
      80           0 :             bool bBackgroundMatches = ( bInBackground && bSearchBackground ) ||
      81           0 :                                       ( !bInBackground && !bSearchBackground );
      82             : 
      83           0 :             const SwFlyFrm* pFly = pObj ? pObj->GetFlyFrm() : 0;
      84           0 :             if ( pFly && bBackgroundMatches &&
      85           0 :                  ( ( pCMS ? pCMS->bSetInReadOnly : false ) ||
      86           0 :                    !pFly->IsProtected() ) &&
      87           0 :                  pFly->GetCrsrOfst( pPos, aPoint, pCMS ) )
      88             :             {
      89           0 :                 bRet = true;
      90           0 :                 break;
      91             :             }
      92             : 
      93           0 :             if ( pCMS && pCMS->bStop )
      94           0 :                 return false;
      95           0 :             aIter.Prev();
      96             :         }
      97           0 :         return bRet;
      98             :     }
      99             : 
     100           0 :     double lcl_getDistance( const SwRect& rRect, const Point& rPoint )
     101             :     {
     102           0 :         double nDist = 0.0;
     103             : 
     104             :         // If the point is inside the rectangle, then distance is 0
     105             :         // Otherwise, compute the distance to the center of the rectangle.
     106           0 :         if ( !rRect.IsInside( rPoint ) )
     107             :         {
     108           0 :             Line aLine( rPoint, rRect.Center( ) );
     109           0 :             nDist = aLine.GetLength( );
     110             :         }
     111             : 
     112           0 :         return nDist;
     113             :     }
     114             : }
     115             : 
     116             : 
     117             : //Fuer SwFlyFrm::GetCrsrOfst
     118             : class SwCrsrOszControl
     119             : {
     120             : public:
     121             :     // damit schon der Compiler die Klasse initialisieren kann, keinen
     122             :     // DTOR und member als publics:
     123             :     const SwFlyFrm *pEntry;
     124             :     const SwFlyFrm *pStk1;
     125             :     const SwFlyFrm *pStk2;
     126             : 
     127             : //public:
     128             : //    SwCrsrOszControl() : pStk1( 0 ), pStk2( 0 ) {}; // ; <- ????
     129             : 
     130           0 :     bool ChkOsz( const SwFlyFrm *pFly )
     131             :         {
     132           0 :             bool bRet = true;
     133           0 :             if ( pFly != pStk1 && pFly != pStk2 )
     134             :             {
     135           0 :                 pStk1 = pStk2;
     136           0 :                 pStk2 = pFly;
     137           0 :                 bRet  = false;
     138             :             }
     139           0 :             return bRet;
     140             :         }
     141           0 :     void Entry( const SwFlyFrm *pFly )
     142             :         {
     143           0 :             if ( !pEntry )
     144           0 :                 pEntry = pStk1 = pFly;
     145           0 :         }
     146           0 :     void Exit( const SwFlyFrm *pFly )
     147             :         {
     148           0 :             if ( pFly == pEntry )
     149           0 :                 pEntry = pStk1 = pStk2 = 0;
     150           0 :         }
     151             : };
     152             : 
     153             : static SwCrsrOszControl aOszCtrl = { 0, 0, 0 };
     154             : 
     155             : /*************************************************************************
     156             : |*
     157             : |*  SwLayoutFrm::GetCrsrOfst()
     158             : |*
     159             : |*  Beschreibung:       Sucht denjenigen CntntFrm, innerhalb dessen
     160             : |*                      PrtArea der Point liegt.
     161             : |*
     162             : |*************************************************************************/
     163         469 : sal_Bool SwLayoutFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint,
     164             :                                SwCrsrMoveState* pCMS, bool ) const
     165             : {
     166         469 :     sal_Bool bRet = sal_False;
     167         469 :     const SwFrm *pFrm = Lower();
     168        1407 :     while ( !bRet && pFrm )
     169             :     {
     170         469 :         pFrm->Calc();
     171             : 
     172             :         // #i43742# New function
     173         469 :         const bool bCntntCheck = pFrm->IsTxtFrm() && pCMS && pCMS->bCntntCheck;
     174             :         const SwRect aPaintRect( bCntntCheck ?
     175             :                                  pFrm->UnionFrm() :
     176         469 :                                  pFrm->PaintArea() );
     177             : 
     178         681 :         if ( aPaintRect.IsInside( rPoint ) &&
     179         342 :              ( bCntntCheck || pFrm->GetCrsrOfst( pPos, rPoint, pCMS ) ) )
     180         212 :             bRet = sal_True;
     181             :         else
     182         257 :             pFrm = pFrm->GetNext();
     183         469 :         if ( pCMS && pCMS->bStop )
     184           0 :             return sal_False;
     185             :     }
     186         469 :     return bRet;
     187             : }
     188             : 
     189             : /*************************************************************************
     190             : |*
     191             : |*  SwPageFrm::GetCrsrOfst()
     192             : |*
     193             : |*  Beschreibung:       Sucht die Seite, innerhalb der der gesuchte Point
     194             : |*                      liegt.
     195             : |*
     196             : |*************************************************************************/
     197             : 
     198         236 : sal_Bool SwPageFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint,
     199             :                              SwCrsrMoveState* pCMS, bool bTestBackground ) const
     200             : {
     201         236 :     sal_Bool bRet     = sal_False;
     202         236 :     Point aPoint( rPoint );
     203             : 
     204             :     // check, if we have to adjust the point
     205         236 :     if ( !Frm().IsInside( aPoint ) )
     206             :     {
     207           1 :         aPoint.X() = std::max( aPoint.X(), Frm().Left() );
     208           1 :         aPoint.X() = std::min( aPoint.X(), Frm().Right() );
     209           1 :         aPoint.Y() = std::max( aPoint.Y(), Frm().Top() );
     210           1 :         aPoint.Y() = std::min( aPoint.Y(), Frm().Bottom() );
     211             :     }
     212             : 
     213         236 :     sal_Bool bTextRet, bBackRet = sal_False;
     214             : 
     215             :     //Koennte ein Freifliegender gemeint sein?
     216             :     //Wenn sein Inhalt geschuetzt werden soll, so ist nix mit Crsr
     217             :     //hineinsetzen, dadurch sollten alle Aenderungen unmoeglich sein.
     218         236 :     if ( GetSortedObjs() )
     219             :     {
     220           0 :         bRet = lcl_GetCrsrOfst_Objects( this, false, pPos, rPoint, pCMS );
     221             :     }
     222             : 
     223         236 :     if ( !bRet )
     224             :     {
     225         236 :         SwPosition aBackPos( *pPos );
     226         472 :         SwPosition aTextPos( *pPos );
     227             : 
     228             :         //Wenn kein Cntnt unterhalb der Seite 'antwortet', so korrigieren
     229             :         //wir den StartPoint und fangen nochmal eine Seite vor der
     230             :         //aktuellen an. Mit Flys ist es dann allerdings vorbei.
     231         236 :         if ( SwLayoutFrm::GetCrsrOfst( &aTextPos, aPoint, pCMS ) )
     232             :         {
     233         106 :             bTextRet = sal_True;
     234             :         }
     235             :         else
     236             :         {
     237         130 :             if ( pCMS && (pCMS->bStop || pCMS->bExactOnly) )
     238             :             {
     239           0 :                 ((SwCrsrMoveState*)pCMS)->bStop = sal_True;
     240           0 :                 return sal_False;
     241             :             }
     242         130 :             const SwCntntFrm *pCnt = GetCntntPos( aPoint, sal_False, sal_False, sal_False, pCMS, sal_False );
     243         130 :             if ( pCMS && pCMS->bStop )
     244           0 :                 return sal_False;
     245             : 
     246             :             OSL_ENSURE( pCnt, "Crsr is gone to a Black hole" );
     247         130 :             if( pCMS && pCMS->pFill && pCnt->IsTxtFrm() )
     248           0 :                 bTextRet = pCnt->GetCrsrOfst( &aTextPos, rPoint, pCMS );
     249             :             else
     250         130 :                 bTextRet = pCnt->GetCrsrOfst( &aTextPos, aPoint, pCMS );
     251             : 
     252         130 :             if ( !bTextRet )
     253             :             {
     254             :                 // Set point to pCnt, delete mark
     255             :                 // this may happen, if pCnt is hidden
     256           9 :                 aTextPos = SwPosition( *pCnt->GetNode(), SwIndex( (SwTxtNode*)pCnt->GetNode(), 0 ) );
     257           9 :                 bTextRet = sal_True;
     258             :             }
     259             :         }
     260             : 
     261         236 :         SwCntntNode* pTextNd = aTextPos.nNode.GetNode( ).GetCntntNode( );
     262         236 :         bool bConsiderBackground = true;
     263             :         // If the text position is a clickable field, then that should have priority.
     264         236 :         if (pTextNd && pTextNd->IsTxtNode())
     265             :         {
     266         236 :             SwTxtNode* pTxtNd = pTextNd->GetTxtNode();
     267         236 :             SwTxtAttr* pTxtAttr = pTxtNd->GetTxtAttrForCharAt(aTextPos.nContent.GetIndex(), RES_TXTATR_FIELD);
     268         236 :             if (pTxtAttr)
     269             :             {
     270           0 :                 const SwField* pField = pTxtAttr->GetFld().GetFld();
     271           0 :                 if (pField->IsClickable())
     272           0 :                     bConsiderBackground = false;
     273             :             }
     274             :         }
     275             : 
     276             :         // Check objects in the background if nothing else matched
     277         236 :         if ( GetSortedObjs() )
     278             :         {
     279           0 :             bBackRet = lcl_GetCrsrOfst_Objects( this, true, &aBackPos, rPoint, pCMS );
     280             :         }
     281             : 
     282         236 :         if ( ( bConsiderBackground && bTestBackground && bBackRet ) || !bTextRet )
     283             :         {
     284           0 :             bRet = bBackRet;
     285           0 :             (*pPos) = aBackPos;
     286             :         }
     287         236 :         else if (bTextRet && !bBackRet)
     288             :         {
     289         236 :             bRet = bTextRet;
     290         236 :             (*pPos) = aTextPos;
     291             :         }
     292             :         else
     293             :         {
     294             :             /* In order to provide a selection as accurable as possible when we have both
     295             :              * text and brackground object, then we compute the distance between both
     296             :              * would-be positions and the click point. The shortest distance wins.
     297             :              */
     298           0 :             double nTextDistance = 0;
     299           0 :             bool bValidTextDistance = false;
     300           0 :             if ( pTextNd )
     301             :             {
     302           0 :                 SwCntntFrm* pTextFrm = pTextNd->getLayoutFrm( getRootFrm( ) );
     303           0 :                 SwRect rTextRect;
     304           0 :                 pTextFrm->GetCharRect( rTextRect, aTextPos );
     305             : 
     306           0 :                 nTextDistance = lcl_getDistance( rTextRect, rPoint );
     307           0 :                 bValidTextDistance = true;
     308             :             }
     309             : 
     310           0 :             double nBackDistance = 0;
     311           0 :             bool bValidBackDistance = false;
     312           0 :             SwCntntNode* pBackNd = aBackPos.nNode.GetNode( ).GetCntntNode( );
     313           0 :             if ( pBackNd && bConsiderBackground)
     314             :             {
     315             :                 // FIXME There are still cases were we don't have the proper node here.
     316           0 :                 SwCntntFrm* pBackFrm = pBackNd->getLayoutFrm( getRootFrm( ) );
     317           0 :                 SwRect rBackRect;
     318           0 :                 if (pBackFrm)
     319             :                 {
     320           0 :                     pBackFrm->GetCharRect( rBackRect, aBackPos );
     321             : 
     322           0 :                     nBackDistance = lcl_getDistance( rBackRect, rPoint );
     323           0 :                     bValidBackDistance = true;
     324             :                 }
     325             :             }
     326             : 
     327           0 :             if ( bValidTextDistance && bValidBackDistance && basegfx::fTools::more( nTextDistance, nBackDistance ) )
     328             :             {
     329           0 :                 bRet = bBackRet;
     330           0 :                 (*pPos) = aBackPos;
     331             :             }
     332             :             else
     333             :             {
     334           0 :                 bRet = bTextRet;
     335           0 :                 (*pPos) = aTextPos;
     336             :             }
     337         236 :         }
     338             :     }
     339             : 
     340         236 :     if ( bRet )
     341         236 :         rPoint = aPoint;
     342             : 
     343         236 :     return bRet;
     344             : }
     345             : 
     346           0 : bool SwLayoutFrm::FillSelection( SwSelectionList& rList, const SwRect& rRect ) const
     347             : {
     348           0 :     bool bRet = false;
     349           0 :     if( rRect.IsOver(PaintArea()) )
     350             :     {
     351           0 :         const SwFrm* pFrm = Lower();
     352           0 :         while( pFrm )
     353             :         {
     354           0 :             pFrm->FillSelection( rList, rRect );
     355           0 :             pFrm = pFrm->GetNext();
     356             :         }
     357             :     }
     358           0 :     return bRet;
     359             : }
     360             : 
     361           0 : bool SwPageFrm::FillSelection( SwSelectionList& rList, const SwRect& rRect ) const
     362             : {
     363           0 :     bool bRet = false;
     364           0 :     if( rRect.IsOver(PaintArea()) )
     365             :     {
     366           0 :         bRet = SwLayoutFrm::FillSelection( rList, rRect );
     367           0 :         if( GetSortedObjs() )
     368             :         {
     369           0 :             const SwSortedObjs &rObjs = *GetSortedObjs();
     370           0 :             for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
     371             :             {
     372           0 :                 const SwAnchoredObject* pAnchoredObj = rObjs[i];
     373           0 :                 if( !pAnchoredObj->ISA(SwFlyFrm) )
     374           0 :                     continue;
     375           0 :                 const SwFlyFrm* pFly = static_cast<const SwFlyFrm*>(pAnchoredObj);
     376           0 :                 if( pFly->FillSelection( rList, rRect ) )
     377           0 :                     bRet = true;
     378             :             }
     379             :         }
     380             :     }
     381           0 :     return bRet;
     382             : }
     383             : 
     384           0 : bool SwRootFrm::FillSelection( SwSelectionList& aSelList, const SwRect& rRect) const
     385             : {
     386           0 :     const SwFrm *pPage = Lower();
     387           0 :     const long nBottom = rRect.Bottom();
     388           0 :     while( pPage )
     389             :     {
     390           0 :         if( pPage->Frm().Top() < nBottom )
     391             :         {
     392           0 :             if( pPage->Frm().Bottom() > rRect.Top() )
     393           0 :                 pPage->FillSelection( aSelList, rRect );
     394           0 :             pPage = pPage->GetNext();
     395             :         }
     396             :         else
     397           0 :             pPage = 0;
     398             :     }
     399           0 :     return !aSelList.isEmpty();
     400             : }
     401             : 
     402             : /*************************************************************************
     403             : |*
     404             : |*  SwRootFrm::GetCrsrOfst()
     405             : |*
     406             : |*  Beschreibung:       Reicht Primaer den Aufruf an die erste Seite weiter.
     407             : |*                      Wenn der 'reingereichte Point veraendert wird,
     408             : |*                      so wird sal_False zurueckgegeben.
     409             : |*
     410             : |*************************************************************************/
     411         236 : sal_Bool SwRootFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint,
     412             :                              SwCrsrMoveState* pCMS, bool bTestBackground ) const
     413             : {
     414         236 :     sal_Bool bOldAction = IsCallbackActionEnabled();
     415         236 :     ((SwRootFrm*)this)->SetCallbackActionEnabled( sal_False );
     416             :     OSL_ENSURE( (Lower() && Lower()->IsPageFrm()), "Keinen PageFrm gefunden." );
     417         236 :     if( pCMS && pCMS->pFill )
     418           0 :         ((SwCrsrMoveState*)pCMS)->bFillRet = sal_False;
     419         236 :     Point aOldPoint = rPoint;
     420             : 
     421             :     // search for page containing rPoint. The borders around the pages are considerd
     422         236 :     const SwPageFrm* pPage = GetPageAtPos( rPoint, 0, true );
     423             : 
     424             :     // #i95626#
     425             :     // special handling for <rPoint> beyond root frames area
     426         236 :     if ( !pPage &&
     427         236 :          rPoint.X() > Frm().Right() &&
     428           0 :          rPoint.Y() > Frm().Bottom() )
     429             :     {
     430           0 :         pPage = dynamic_cast<const SwPageFrm*>(Lower());
     431           0 :         while ( pPage && pPage->GetNext() )
     432             :         {
     433           0 :             pPage = dynamic_cast<const SwPageFrm*>(pPage->GetNext());
     434             :         }
     435             :     }
     436         236 :     if ( pPage )
     437             :     {
     438         236 :         pPage->SwPageFrm::GetCrsrOfst( pPos, rPoint, pCMS, bTestBackground );
     439             :     }
     440             : 
     441         236 :     ((SwRootFrm*)this)->SetCallbackActionEnabled( bOldAction );
     442         236 :     if( pCMS )
     443             :     {
     444         236 :         if( pCMS->bStop )
     445           0 :             return sal_False;
     446         236 :         if( pCMS->pFill )
     447           0 :             return pCMS->bFillRet;
     448             :     }
     449         236 :     return aOldPoint == rPoint;
     450             : }
     451             : 
     452             : /*************************************************************************
     453             : |*
     454             : |*  SwCellFrm::GetCrsrOfst()
     455             : |*
     456             : |*  Beschreibung        Wenn es sich um eine Cntnt-tragende Cell handelt wird
     457             : |*                      der Crsr notfalls mit Gewalt in einen der CntntFrms
     458             : |*                      gesetzt.
     459             : |*                      In geschuetzte Zellen gibt es hier keinen Eingang.
     460             : |*
     461             : |*************************************************************************/
     462           0 : sal_Bool SwCellFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint,
     463             :                              SwCrsrMoveState* pCMS, bool ) const
     464             : {
     465             :     // cell frame does not necessarily have a lower (split table cell)
     466           0 :     if ( !Lower() )
     467           0 :         return sal_False;
     468             : 
     469           0 :     if ( !(pCMS?pCMS->bSetInReadOnly:sal_False) &&
     470           0 :          GetFmt()->GetProtect().IsCntntProtected() )
     471           0 :         return sal_False;
     472             : 
     473           0 :     if ( pCMS && pCMS->eState == MV_TBLSEL )
     474             :     {
     475           0 :         const SwTabFrm *pTab = FindTabFrm();
     476           0 :         if ( pTab->IsFollow() && pTab->IsInHeadline( *this ) )
     477             :         {
     478           0 :             ((SwCrsrMoveState*)pCMS)->bStop = sal_True;
     479           0 :             return sal_False;
     480             :         }
     481             :     }
     482             : 
     483           0 :     if ( Lower() )
     484             :     {
     485           0 :         if ( Lower()->IsLayoutFrm() )
     486           0 :             return SwLayoutFrm::GetCrsrOfst( pPos, rPoint, pCMS );
     487             :         else
     488             :         {
     489           0 :             Calc();
     490           0 :             sal_Bool bRet = sal_False;
     491             : 
     492           0 :             const SwFrm *pFrm = Lower();
     493           0 :             while ( pFrm && !bRet )
     494             :             {
     495           0 :                 pFrm->Calc();
     496           0 :                 if ( pFrm->Frm().IsInside( rPoint ) )
     497             :                 {
     498           0 :                     bRet = pFrm->GetCrsrOfst( pPos, rPoint, pCMS );
     499           0 :                     if ( pCMS && pCMS->bStop )
     500           0 :                         return sal_False;
     501             :                 }
     502           0 :                 pFrm = pFrm->GetNext();
     503             :             }
     504           0 :             if ( !bRet )
     505             :             {
     506           0 :                 Point *pPoint = pCMS && pCMS->pFill ? new Point( rPoint ) : NULL;
     507           0 :                 const SwCntntFrm *pCnt = GetCntntPos( rPoint, sal_True );
     508           0 :                 if( pPoint && pCnt->IsTxtFrm() )
     509             :                 {
     510           0 :                     pCnt->GetCrsrOfst( pPos, *pPoint, pCMS );
     511           0 :                     rPoint = *pPoint;
     512             :                 }
     513             :                 else
     514           0 :                     pCnt->GetCrsrOfst( pPos, rPoint, pCMS );
     515           0 :                 delete pPoint;
     516             :             }
     517           0 :             return sal_True;
     518             :         }
     519             :     }
     520             : 
     521           0 :     return sal_False;
     522             : }
     523             : 
     524             : /*************************************************************************
     525             : |*
     526             : |*  SwFlyFrm::GetCrsrOfst()
     527             : |*
     528             : |*************************************************************************/
     529             : //Problem: Wenn zwei Flys genau gleich gross sind und auf derselben
     530             : //Position stehen, so liegt jeder innerhalb des anderen.
     531             : //Da jeweils geprueft wird, ob der Point nicht zufaellig innerhalb eines
     532             : //anderen Flys liegt, der sich vollstaendig innerhalb des aktuellen befindet
     533             : //und ggf. ein rekursiver Aufruf erfolgt wuerde o.g. Situation zu einer
     534             : //endlosen Rekursion fuehren.
     535             : //Mit der Hilfsklasse SwCrsrOszControl unterbinden wir die Rekursion. Das
     536             : //GetCrsrOfst entscheidet sich bei einer Rekursion fuer denjenigen der
     537             : //am weitesten oben liegt.
     538             : 
     539           0 : sal_Bool SwFlyFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint,
     540             :                             SwCrsrMoveState* pCMS, bool ) const
     541             : {
     542           0 :     aOszCtrl.Entry( this );
     543             : 
     544             :     //Wenn der Point innerhalb des Fly sitzt wollen wir energisch
     545             :     //versuchen den Crsr hineinzusetzen.
     546             :     //Wenn der Point allerdings in einem Flys sitzt, der sich vollstaendig
     547             :     //innerhalb des aktuellen befindet, so wird fuer diesen das
     548             :     //GetCrsrOfst gerufen.
     549           0 :     Calc();
     550           0 :     sal_Bool bInside = Frm().IsInside( rPoint ) && Lower(),
     551           0 :          bRet = sal_False;
     552             : 
     553             :     //Wenn der Frm eine Grafik enthaelt, aber nur Text gewuenscht ist, so
     554             :     //nimmt er den Crsr grundsaetzlich nicht an.
     555           0 :     if ( bInside && pCMS && pCMS->eState == MV_SETONLYTEXT &&
     556           0 :          (!Lower() || Lower()->IsNoTxtFrm()) )
     557           0 :         bInside = sal_False;
     558             : 
     559           0 :     const SwPageFrm *pPage = FindPageFrm();
     560           0 :     if ( bInside && pPage && pPage->GetSortedObjs() )
     561             :     {
     562           0 :         SwOrderIter aIter( pPage );
     563           0 :         aIter.Top();
     564           0 :         while ( aIter() && !bRet )
     565             :         {
     566           0 :             const SwVirtFlyDrawObj* pObj = static_cast<const SwVirtFlyDrawObj*>(aIter());
     567           0 :             const SwFlyFrm* pFly = pObj ? pObj->GetFlyFrm() : 0;
     568           0 :             if ( pFly && pFly->Frm().IsInside( rPoint ) &&
     569           0 :                  Frm().IsInside( pFly->Frm() ) )
     570             :             {
     571           0 :                 if ( aOszCtrl.ChkOsz( pFly ) ||
     572           0 :                      sal_True == (bRet = pFly->GetCrsrOfst( pPos, rPoint, pCMS )))
     573           0 :                     break;
     574           0 :                 if ( pCMS && pCMS->bStop )
     575           0 :                     return sal_False;
     576             :             }
     577           0 :             aIter.Next();
     578             :         }
     579             :     }
     580             : 
     581           0 :     while ( bInside && !bRet )
     582             :     {
     583           0 :         const SwFrm *pFrm = Lower();
     584           0 :         while ( pFrm && !bRet )
     585             :         {
     586           0 :             pFrm->Calc();
     587           0 :             if ( pFrm->Frm().IsInside( rPoint ) )
     588             :             {
     589           0 :                 bRet = pFrm->GetCrsrOfst( pPos, rPoint, pCMS );
     590           0 :                 if ( pCMS && pCMS->bStop )
     591           0 :                     return sal_False;
     592             :             }
     593           0 :             pFrm = pFrm->GetNext();
     594             :         }
     595           0 :         if ( !bRet )
     596             :         {
     597           0 :             Point *pPoint = pCMS && pCMS->pFill ? new Point( rPoint ) : NULL;
     598             :             const SwCntntFrm *pCnt = GetCntntPos(
     599           0 :                                             rPoint, sal_True, sal_False, sal_False, pCMS );
     600           0 :             if ( pCMS && pCMS->bStop )
     601           0 :                 return sal_False;
     602           0 :             if( pPoint && pCnt->IsTxtFrm() )
     603             :             {
     604           0 :                 pCnt->GetCrsrOfst( pPos, *pPoint, pCMS );
     605           0 :                 rPoint = *pPoint;
     606             :             }
     607             :             else
     608           0 :                 pCnt->GetCrsrOfst( pPos, rPoint, pCMS );
     609           0 :             delete pPoint;
     610           0 :             bRet = sal_True;
     611             :         }
     612             :     }
     613           0 :     aOszCtrl.Exit( this );
     614           0 :     return bRet;
     615             : }
     616             : 
     617             : /*************************************************************************
     618             : |*
     619             : |*    Beschreibung      Layoutabhaengiges Cursortravelling
     620             : |*
     621             : |*************************************************************************/
     622           0 : sal_Bool SwCntntFrm::LeftMargin(SwPaM *pPam) const
     623             : {
     624           0 :     if( pPam->GetNode() != (SwCntntNode*)GetNode() )
     625           0 :         return sal_False;
     626           0 :     ((SwCntntNode*)GetNode())->
     627           0 :         MakeStartIndex((SwIndex *) &pPam->GetPoint()->nContent);
     628           0 :     return sal_True;
     629             : }
     630             : 
     631           0 : sal_Bool SwCntntFrm::RightMargin(SwPaM *pPam, sal_Bool) const
     632             : {
     633           0 :     if( pPam->GetNode() != (SwCntntNode*)GetNode() )
     634           0 :         return sal_False;
     635           0 :     ((SwCntntNode*)GetNode())->
     636           0 :         MakeEndIndex((SwIndex *) &pPam->GetPoint()->nContent);
     637           0 :     return sal_True;
     638             : }
     639             : 
     640           2 : static const SwCntntFrm *lcl_GetNxtCnt( const SwCntntFrm* pCnt )
     641             : {
     642           2 :     return pCnt->GetNextCntntFrm();
     643             : }
     644             : 
     645           4 : static const SwCntntFrm *lcl_GetPrvCnt( const SwCntntFrm* pCnt )
     646             : {
     647           4 :     return pCnt->GetPrevCntntFrm();
     648             : }
     649             : 
     650             : typedef const SwCntntFrm *(*GetNxtPrvCnt)( const SwCntntFrm* );
     651             : 
     652             : //Frame in wiederholter Headline?
     653           6 : static bool lcl_IsInRepeatedHeadline( const SwFrm *pFrm,
     654             :                                     const SwTabFrm** ppTFrm = 0 )
     655             : {
     656           6 :     const SwTabFrm *pTab = pFrm->FindTabFrm();
     657           6 :     if( ppTFrm )
     658           0 :         *ppTFrm = pTab;
     659           6 :     return pTab && pTab->IsFollow() && pTab->IsInHeadline( *pFrm );
     660             : }
     661             : 
     662             : 
     663             : //Ueberspringen geschuetzter Tabellenzellen. Optional auch
     664             : //Ueberspringen von wiederholten Headlines.
     665             : //MA 26. Jan. 98: Chg auch andere Geschuetzte Bereiche ueberspringen.
     666             : // FME: Skip follow flow cells
     667         137 : static const SwCntntFrm * lcl_MissProtectedFrames( const SwCntntFrm *pCnt,
     668             :                                                        GetNxtPrvCnt fnNxtPrv,
     669             :                                                        sal_Bool bMissHeadline,
     670             :                                                        sal_Bool bInReadOnly,
     671             :                                                        sal_Bool bMissFollowFlowLine )
     672             : {
     673         137 :     if ( pCnt && pCnt->IsInTab() )
     674             :     {
     675           6 :         sal_Bool bProtect = sal_True;
     676          18 :         while ( pCnt && bProtect )
     677             :         {
     678           6 :             const SwLayoutFrm *pCell = pCnt->GetUpper();
     679          12 :             while ( pCell && !pCell->IsCellFrm() )
     680           0 :                 pCell = pCell->GetUpper();
     681          12 :             if ( !pCell ||
     682           0 :                     (( ( bInReadOnly || !pCell->GetFmt()->GetProtect().IsCntntProtected() ) &&
     683           6 :                       ( !bMissHeadline || !lcl_IsInRepeatedHeadline( pCell ) ) &&
     684           6 :                       ( !bMissFollowFlowLine || !pCell->IsInFollowFlowRow() ) &&
     685           6 :                        !pCell->IsCoveredCell()) ) )
     686           6 :                 bProtect = sal_False;
     687             :             else
     688           0 :                 pCnt = (*fnNxtPrv)( pCnt );
     689             :         }
     690             :     }
     691         131 :     else if ( !bInReadOnly )
     692         246 :         while ( pCnt && pCnt->IsProtected() )
     693           0 :             pCnt = (*fnNxtPrv)( pCnt );
     694             : 
     695         137 :     return pCnt;
     696             : }
     697             : 
     698           3 : static sal_Bool lcl_UpDown( SwPaM *pPam, const SwCntntFrm *pStart,
     699             :                     GetNxtPrvCnt fnNxtPrv, sal_Bool bInReadOnly )
     700             : {
     701             :     OSL_ENSURE( pPam->GetNode() == (SwCntntNode*)pStart->GetNode(),
     702             :             "lcl_UpDown arbeitet nicht fuer andere." );
     703             : 
     704           3 :     const SwCntntFrm *pCnt = 0;
     705             : 
     706             :     //Wenn gerade eine Tabellenselection laeuft muss ein bischen getricktst
     707             :     //werden: Beim hochlaufen an den Anfang der Zelle gehen, beim runterlaufen
     708             :     //an das Ende der Zelle gehen.
     709           3 :     sal_Bool bTblSel = false;
     710           6 :     if ( pStart->IsInTab() &&
     711           3 :         pPam->GetNode( sal_True )->StartOfSectionNode() !=
     712           3 :         pPam->GetNode( sal_False )->StartOfSectionNode() )
     713             :     {
     714           0 :         bTblSel = true;
     715           0 :         const SwLayoutFrm  *pCell = pStart->GetUpper();
     716           0 :         while ( !pCell->IsCellFrm() )
     717           0 :             pCell = pCell->GetUpper();
     718             : 
     719             :         //
     720             :         // Check, if cell has a Prev/Follow cell:
     721             :         //
     722           0 :         const bool bFwd = ( fnNxtPrv == lcl_GetNxtCnt );
     723             :         const SwLayoutFrm* pTmpCell = bFwd ?
     724             :             ((SwCellFrm*)pCell)->GetFollowCell() :
     725           0 :             ((SwCellFrm*)pCell)->GetPreviousCell();
     726             : 
     727           0 :         const SwCntntFrm* pTmpStart = pStart;
     728           0 :         while ( pTmpCell && 0 != ( pTmpStart = pTmpCell->ContainsCntnt() ) )
     729             :         {
     730           0 :             pCell = pTmpCell;
     731             :             pTmpCell = bFwd ?
     732             :                 ((SwCellFrm*)pCell)->GetFollowCell() :
     733           0 :                 ((SwCellFrm*)pCell)->GetPreviousCell();
     734             :         }
     735           0 :         const SwCntntFrm *pNxt = pCnt = pTmpStart;
     736             : 
     737           0 :         while ( pCell->IsAnLower( pNxt ) )
     738             :         {
     739           0 :             pCnt = pNxt;
     740           0 :             pNxt = (*fnNxtPrv)( pNxt );
     741             :         }
     742             :     }
     743             : 
     744           3 :     pCnt = (*fnNxtPrv)( pCnt ? pCnt : pStart );
     745           3 :     pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, sal_True, bInReadOnly, bTblSel );
     746             : 
     747             : 
     748           3 :     const SwTabFrm *pStTab = pStart->FindTabFrm();
     749           3 :     const SwTabFrm *pTable = 0;
     750           3 :     const sal_Bool bTab = pStTab || (pCnt && pCnt->IsInTab()) ? sal_True : sal_False;
     751           3 :     sal_Bool bEnd = bTab ? sal_False : sal_True;
     752             : 
     753           3 :     const SwFrm* pVertRefFrm = pStart;
     754           3 :     if ( bTblSel && pStTab )
     755           0 :         pVertRefFrm = pStTab;
     756           3 :     SWRECTFN( pVertRefFrm )
     757             : 
     758           3 :     SwTwips nX = 0;
     759           3 :     if ( bTab )
     760             :     {
     761             :         //
     762             :         // pStart or pCnt is inside a table. nX will be used for travelling:
     763             :         //
     764           3 :         SwRect aRect( pStart->Frm() );
     765           3 :         pStart->GetCharRect( aRect, *pPam->GetPoint() );
     766           3 :         Point aCenter = aRect.Center();
     767           3 :         nX = bVert ? aCenter.Y() : aCenter.X();
     768             : 
     769           3 :         pTable = pCnt ? pCnt->FindTabFrm() : 0;
     770           3 :         if ( !pTable )
     771           0 :             pTable = pStTab;
     772             : 
     773           6 :         if ( pStTab &&
     774           6 :             !pStTab->GetUpper()->IsInTab() &&
     775           3 :             !pTable->GetUpper()->IsInTab() )
     776             :         {
     777           3 :             const SwFrm *pCell = pStart->GetUpper();
     778           6 :             while ( pCell && !pCell->IsCellFrm() )
     779           0 :                 pCell = pCell->GetUpper();
     780             :             OSL_ENSURE( pCell, "Zelle nicht gefunden." );
     781           3 :             nX =  (pCell->Frm().*fnRect->fnGetLeft)() +
     782           3 :                   (pCell->Frm().*fnRect->fnGetWidth)() / 2;
     783             : 
     784             :             //Der Fluss fuehrt von einer Tabelle in die nachste. Der X-Wert
     785             :             //muss ausgehend von der Mitte der Startzelle um die Verschiebung
     786             :             //der Tabellen korrigiert werden.
     787           3 :             if ( pStTab != pTable )
     788             :             {
     789           0 :                 nX += (pTable->Frm().*fnRect->fnGetLeft)() -
     790           0 :                       (pStTab->Frm().*fnRect->fnGetLeft)();
     791             :             }
     792             :         }
     793             : 
     794             :         //
     795             :         // Restrict nX to the left and right borders of pTab:
     796             :         // (is this really necessary?)
     797             :         //
     798           3 :         if ( !pTable->GetUpper()->IsInTab() )
     799             :         {
     800           3 :             const sal_Bool bRTL = pTable->IsRightToLeft();
     801             :             const long nPrtLeft = bRTL ?
     802           0 :                                 (pTable->*fnRect->fnGetPrtRight)() :
     803           3 :                                 (pTable->*fnRect->fnGetPrtLeft)();
     804           3 :             if ( bRTL != (nX < nPrtLeft) )
     805           0 :                 nX = nPrtLeft;
     806             :             else
     807             :             {
     808             :                    const long nPrtRight = bRTL ?
     809           0 :                                     (pTable->*fnRect->fnGetPrtLeft)() :
     810           3 :                                     (pTable->*fnRect->fnGetPrtRight)();
     811           3 :                 if ( bRTL != (nX > nPrtRight) )
     812           0 :                     nX = nPrtRight;
     813             :             }
     814             :         }
     815             :     }
     816             : 
     817           6 :     do
     818             :     {
     819             :         //Wenn ich im DokumentBody bin, so will ich da auch bleiben
     820           6 :         if ( pStart->IsInDocBody() )
     821             :         {
     822          18 :             while ( pCnt && (!pCnt->IsInDocBody() ||
     823          12 :                              (pCnt->IsTxtFrm() && ((SwTxtFrm*)pCnt)->IsHiddenNow())))
     824             :             {
     825           0 :                 pCnt = (*fnNxtPrv)( pCnt );
     826           0 :                 pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, sal_True, bInReadOnly, bTblSel );
     827             :             }
     828             :         }
     829             : 
     830             :         //Wenn ich im Fussnotenbereich bin, so versuche ich notfalls den naechsten
     831             :         //Fussnotenbereich zu erreichen.
     832           0 :         else if ( pStart->IsInFtn() )
     833             :         {
     834           0 :             while ( pCnt && (!pCnt->IsInFtn() ||
     835           0 :                             (pCnt->IsTxtFrm() && ((SwTxtFrm*)pCnt)->IsHiddenNow())))
     836             :             {
     837           0 :                 pCnt = (*fnNxtPrv)( pCnt );
     838           0 :                 pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, sal_True, bInReadOnly, bTblSel );
     839             :             }
     840             :         }
     841             : 
     842             :         //In Flys kann es Blind weitergehen solange ein Cntnt
     843             :         //gefunden wird.
     844           0 :         else if ( pStart->IsInFly() )
     845             :         {
     846           0 :             if ( pCnt && pCnt->IsTxtFrm() && ((SwTxtFrm*)pCnt)->IsHiddenNow() )
     847             :             {
     848           0 :                 pCnt = (*fnNxtPrv)( pCnt );
     849           0 :                 pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, sal_True, bInReadOnly, bTblSel );
     850             :             }
     851             :         }
     852             : 
     853             :         //Andernfalls weigere ich mich einfach den derzeitigen Bereich zu
     854             :         //verlassen.
     855           0 :         else if ( pCnt )
     856             :         {
     857           0 :             const SwFrm *pUp = pStart->GetUpper();               //Head/Foot
     858           0 :             while ( pUp && pUp->GetUpper() && !(pUp->GetType() & 0x0018 ) )
     859           0 :                 pUp = pUp->GetUpper();
     860           0 :             sal_Bool bSame = sal_False;
     861           0 :             const SwFrm *pCntUp = pCnt->GetUpper();
     862           0 :             while ( pCntUp && !bSame )
     863           0 :             {   if ( pUp == pCntUp )
     864           0 :                     bSame = sal_True;
     865             :                 else
     866           0 :                     pCntUp = pCntUp->GetUpper();
     867             :             }
     868           0 :             if ( !bSame )
     869           0 :                 pCnt = 0;
     870           0 :             else if ( pCnt && pCnt->IsTxtFrm() && ((SwTxtFrm*)pCnt)->IsHiddenNow() ) // i73332
     871             :             {
     872           0 :                 pCnt = (*fnNxtPrv)( pCnt );
     873           0 :                 pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, sal_True, bInReadOnly, bTblSel );
     874             :             }
     875             :         }
     876             : 
     877           6 :         if ( bTab )
     878             :         {
     879           6 :             if ( !pCnt )
     880           0 :                 bEnd = sal_True;
     881             :             else
     882           6 :             {   const SwTabFrm *pTab = pCnt->FindTabFrm();
     883           6 :                 if( !pTab )
     884           0 :                     bEnd = sal_True;
     885             :                 else
     886             :                 {
     887           6 :                     if ( pTab != pTable )
     888             :                     {
     889             :                         //Der Fluss fuehrt von einer Tabelle in die nachste. Der
     890             :                         //X-Wert muss um die Verschiebung der Tabellen korrigiert
     891             :                         //werden.
     892           0 :                          if ( pTable &&
     893           0 :                               !pTab->GetUpper()->IsInTab() &&
     894           0 :                             !pTable->GetUpper()->IsInTab() )
     895           0 :                             nX += pTab->Frm().Left() - pTable->Frm().Left();
     896           0 :                         pTable = pTab;
     897             :                     }
     898           6 :                     const SwLayoutFrm *pCell = pTable ? pCnt->GetUpper() : 0;
     899          12 :                     while ( pCell && !pCell->IsCellFrm() )
     900           0 :                         pCell = pCell->GetUpper();
     901             : 
     902           6 :                     Point aInsideCell;
     903           6 :                     Point aInsideCnt;
     904           6 :                     if ( pCell )
     905             :                     {
     906           6 :                         long nTmpTop = (pCell->Frm().*fnRect->fnGetTop)();
     907           6 :                         if ( bVert )
     908             :                         {
     909           0 :                             if ( nTmpTop )
     910           0 :                                 --nTmpTop;
     911             : 
     912           0 :                             aInsideCell = Point( nTmpTop, nX );
     913             :                         }
     914             :                         else
     915           6 :                             aInsideCell = Point( nX, nTmpTop );
     916             :                     }
     917             : 
     918           6 :                     long nTmpTop = (pCnt->Frm().*fnRect->fnGetTop)();
     919           6 :                     if ( bVert )
     920             :                     {
     921           0 :                         if ( nTmpTop )
     922           0 :                             --nTmpTop;
     923             : 
     924           0 :                         aInsideCnt = Point( nTmpTop, nX );
     925             :                     }
     926             :                     else
     927           6 :                         aInsideCnt = Point( nX, nTmpTop );
     928             : 
     929           6 :                     if ( pCell && pCell->Frm().IsInside( aInsideCell ) )
     930             :                     {
     931           3 :                         bEnd = sal_True;
     932             :                         //Jetzt noch schnell den richtigen Cntnt in der Zelle
     933             :                         //greifen.
     934           3 :                         if ( !pCnt->Frm().IsInside( aInsideCnt ) )
     935             :                         {
     936           0 :                             pCnt = pCell->ContainsCntnt();
     937           0 :                             if ( fnNxtPrv == lcl_GetPrvCnt )
     938           0 :                                 while ( pCell->IsAnLower(pCnt->GetNextCntntFrm()) )
     939           0 :                                     pCnt = pCnt->GetNextCntntFrm();
     940             :                         }
     941             :                     }
     942           3 :                     else if ( pCnt->Frm().IsInside( aInsideCnt ) )
     943           0 :                         bEnd = sal_True;
     944             :                 }
     945             :             }
     946           6 :             if ( !bEnd )
     947             :             {
     948           3 :                 pCnt = (*fnNxtPrv)( pCnt );
     949           3 :                 pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, sal_True, bInReadOnly, bTblSel );
     950             :             }
     951             :         }
     952             : 
     953           9 :     } while ( !bEnd ||
     954           3 :               (pCnt && pCnt->IsTxtFrm() && ((SwTxtFrm*)pCnt)->IsHiddenNow()));
     955             : 
     956           3 :     if( pCnt )
     957             :     {   // setze den Point auf den Content-Node
     958           3 :         SwCntntNode *pCNd = (SwCntntNode*)pCnt->GetNode();
     959           3 :         pPam->GetPoint()->nNode = *pCNd;
     960           3 :         if ( fnNxtPrv == lcl_GetPrvCnt )
     961           2 :             pCNd->MakeEndIndex( (SwIndex*)&pPam->GetPoint()->nContent );
     962             :         else
     963           1 :             pCNd->MakeStartIndex( (SwIndex*)&pPam->GetPoint()->nContent );
     964           3 :         return sal_True;
     965             :     }
     966           0 :     return sal_False;
     967             : }
     968             : 
     969           2 : sal_Bool SwCntntFrm::UnitUp( SwPaM* pPam, const SwTwips, sal_Bool bInReadOnly ) const
     970             : {
     971           2 :     return ::lcl_UpDown( pPam, this, lcl_GetPrvCnt, bInReadOnly );
     972             : }
     973             : 
     974           1 : sal_Bool SwCntntFrm::UnitDown( SwPaM* pPam, const SwTwips, sal_Bool bInReadOnly ) const
     975             : {
     976           1 :     return ::lcl_UpDown( pPam, this, lcl_GetNxtCnt, bInReadOnly );
     977             : }
     978             : 
     979             : /*************************************************************************
     980             : |*
     981             : |*  SwRootFrm::GetCurrPage()
     982             : |*
     983             : |*  Beschreibung:       Liefert die Nummer der aktuellen Seite.
     984             : |*          Wenn die Methode einen PaM bekommt, so ist die aktuelle Seite
     985             : |*          diejenige in der der PaM sitzt. Anderfalls ist die aktuelle
     986             : |*          Seite die erste Seite innerhalb der VisibleArea.
     987             : |*          Es wird nur auf den vorhandenen Seiten gearbeitet!
     988             : |*
     989             : |*************************************************************************/
     990           0 : sal_uInt16 SwRootFrm::GetCurrPage( const SwPaM *pActualCrsr ) const
     991             : {
     992             :     OSL_ENSURE( pActualCrsr, "Welche Seite soll's denn sein?" );
     993           0 :     SwFrm const*const pActFrm = pActualCrsr->GetPoint()->nNode.GetNode().
     994             :                                     GetCntntNode()->getLayoutFrm( this, 0,
     995             :                                                     pActualCrsr->GetPoint(),
     996           0 :                                                     sal_False );
     997           0 :     return pActFrm->FindPageFrm()->GetPhyPageNum();
     998             : }
     999             : 
    1000             : /*************************************************************************
    1001             : |*
    1002             : |*  SwRootFrm::SetCurrPage()
    1003             : |*
    1004             : |*  Beschreibung:       Liefert einen PaM der am Anfang der gewuenschten
    1005             : |*          Seite sitzt.
    1006             : |*          Formatiert wird soweit notwendig
    1007             : |*          Liefert Null, wenn die Operation nicht moeglich ist.
    1008             : |*          Der PaM sitzt in der letzten Seite, wenn die Seitenzahl zu gross
    1009             : |*          gewaehlt wurde.
    1010             : |*
    1011             : |*************************************************************************/
    1012           1 : sal_uInt16 SwRootFrm::SetCurrPage( SwCursor* pToSet, sal_uInt16 nPageNum )
    1013             : {
    1014             :     OSL_ENSURE( Lower() && Lower()->IsPageFrm(), "Keine Seite vorhanden." );
    1015             : 
    1016           1 :     SwPageFrm *pPage = (SwPageFrm*)Lower();
    1017           1 :     sal_Bool bEnd =sal_False;
    1018           2 :     while ( !bEnd && pPage->GetPhyPageNum() != nPageNum )
    1019           0 :     {   if ( pPage->GetNext() )
    1020           0 :             pPage = (SwPageFrm*)pPage->GetNext();
    1021             :         else
    1022             :         {   //Ersten CntntFrm Suchen, und solange Formatieren bis
    1023             :             //eine neue Seite angefangen wird oder bis die CntntFrm's alle
    1024             :             //sind.
    1025           0 :             const SwCntntFrm *pCntnt = pPage->ContainsCntnt();
    1026           0 :             while ( pCntnt && pPage->IsAnLower( pCntnt ) )
    1027             :             {
    1028           0 :                 pCntnt->Calc();
    1029           0 :                 pCntnt = pCntnt->GetNextCntntFrm();
    1030             :             }
    1031             :             //Jetzt ist entweder eine neue Seite da, oder die letzte Seite
    1032             :             //ist gefunden.
    1033           0 :             if ( pPage->GetNext() )
    1034           0 :                 pPage = (SwPageFrm*)pPage->GetNext();
    1035             :             else
    1036           0 :                 bEnd = sal_True;
    1037             :         }
    1038             :     }
    1039             :     //pPage zeigt jetzt auf die 'gewuenschte' Seite. Jetzt muss noch der
    1040             :     //PaM auf den Anfang des ersten CntntFrm im Body-Text erzeugt werden.
    1041             :     //Wenn es sich um eine Fussnotenseite handelt, wird der PaM in die erste
    1042             :     //Fussnote gesetzt.
    1043           1 :     const SwCntntFrm *pCntnt = pPage->ContainsCntnt();
    1044           1 :     if ( pPage->IsFtnPage() )
    1045           0 :         while ( pCntnt && !pCntnt->IsInFtn() )
    1046           0 :             pCntnt = pCntnt->GetNextCntntFrm();
    1047             :     else
    1048           2 :         while ( pCntnt && !pCntnt->IsInDocBody() )
    1049           0 :             pCntnt = pCntnt->GetNextCntntFrm();
    1050           1 :     if ( pCntnt )
    1051             :     {
    1052           1 :         SwCntntNode* pCNd = (SwCntntNode*)pCntnt->GetNode();
    1053           1 :         pToSet->GetPoint()->nNode = *pCNd;
    1054           1 :         pCNd->MakeStartIndex( (SwIndex*)&pToSet->GetPoint()->nContent );
    1055           1 :         pToSet->GetPoint()->nContent = ((SwTxtFrm*)pCntnt)->GetOfst();
    1056             : 
    1057           1 :         SwShellCrsr* pSCrsr = dynamic_cast<SwShellCrsr*>(pToSet);
    1058           1 :         if( pSCrsr )
    1059             :         {
    1060           1 :             Point &rPt = pSCrsr->GetPtPos();
    1061           1 :             rPt = pCntnt->Frm().Pos();
    1062           1 :             rPt += pCntnt->Prt().Pos();
    1063             :         }
    1064           1 :         return pPage->GetPhyPageNum();
    1065             :     }
    1066           0 :     return 0;
    1067             : }
    1068             : 
    1069             : /*************************************************************************
    1070             : |*
    1071             : |*    SwCntntFrm::StartxxPage(), EndxxPage()
    1072             : |*
    1073             : |*    Beschreibung      Cursor an Anfang/Ende der aktuellen/vorherigen/
    1074             : |*      naechsten Seite. Alle sechs Methoden rufen GetFrmInPage() mit der
    1075             : |*      entsprechenden Parametrisierung.
    1076             : |*      Zwei Parameter steuern die Richtung: einer bestimmt die Seite, der
    1077             : |*      andere Anfang/Ende.
    1078             : |*      Fuer die Bestimmung der Seite und des Cntnt (Anfang/Ende) werden
    1079             : |*      die im folgenden definierten Funktionen benutzt.
    1080             : |*
    1081             : |*************************************************************************/
    1082          16 : SwCntntFrm *GetFirstSub( const SwLayoutFrm *pLayout )
    1083             : {
    1084          16 :     return ((SwPageFrm*)pLayout)->FindFirstBodyCntnt();
    1085             : }
    1086             : 
    1087           2 : SwCntntFrm *GetLastSub( const SwLayoutFrm *pLayout )
    1088             : {
    1089           2 :     return ((SwPageFrm*)pLayout)->FindLastBodyCntnt();
    1090             : }
    1091             : 
    1092           1 : SwLayoutFrm *GetNextFrm( const SwLayoutFrm *pFrm )
    1093             : {
    1094             :     SwLayoutFrm *pNext =
    1095           2 :         (pFrm->GetNext() && pFrm->GetNext()->IsLayoutFrm()) ?
    1096           2 :                                             (SwLayoutFrm*)pFrm->GetNext() : 0;
    1097             :     // #i39402# in case of an empty page
    1098           1 :     if(pNext && !pNext->ContainsCntnt())
    1099           0 :         pNext = (pNext->GetNext() && pNext->GetNext()->IsLayoutFrm()) ?
    1100           0 :                                             (SwLayoutFrm*)pNext->GetNext() : 0;
    1101           1 :     return pNext;
    1102             : }
    1103             : 
    1104          16 : SwLayoutFrm *GetThisFrm( const SwLayoutFrm *pFrm )
    1105             : {
    1106          16 :     return (SwLayoutFrm*)pFrm;
    1107             : }
    1108             : 
    1109           1 : SwLayoutFrm *GetPrevFrm( const SwLayoutFrm *pFrm )
    1110             : {
    1111             :     SwLayoutFrm *pPrev =
    1112           2 :         (pFrm->GetPrev() && pFrm->GetPrev()->IsLayoutFrm()) ?
    1113           2 :                                             (SwLayoutFrm*)pFrm->GetPrev() : 0;
    1114             :     // #i39402# in case of an empty page
    1115           1 :     if(pPrev && !pPrev->ContainsCntnt())
    1116           0 :         pPrev = (pPrev->GetPrev() && pPrev->GetPrev()->IsLayoutFrm()) ?
    1117           0 :                                             (SwLayoutFrm*)pPrev->GetPrev() : 0;
    1118           1 :     return pPrev;
    1119             : }
    1120             : 
    1121             : //Jetzt koennen auch die Funktionspointer initalisiert werden;
    1122             : //sie sind in cshtyp.hxx declariert.
    1123             : SwPosPage fnPageStart = GetFirstSub;
    1124             : SwPosPage fnPageEnd = GetLastSub;
    1125             : SwWhichPage fnPagePrev = GetPrevFrm;
    1126             : SwWhichPage fnPageCurr = GetThisFrm;
    1127             : SwWhichPage fnPageNext = GetNextFrm;
    1128             : 
    1129             : //Liefert den ersten/den letzten Contentframe (gesteuert ueber
    1130             : //den Parameter fnPosPage) in der
    1131             : //aktuellen/vorhergehenden/folgenden Seite (gesteuert durch den
    1132             : //Parameter fnWhichPage).
    1133          18 : sal_Bool GetFrmInPage( const SwCntntFrm *pCnt, SwWhichPage fnWhichPage,
    1134             :                    SwPosPage fnPosPage, SwPaM *pPam )
    1135             : {
    1136             :     //Erstmal die gewuenschte Seite besorgen, anfangs die aktuelle, dann
    1137             :     //die die per fnWichPage gewuenscht wurde
    1138          18 :     const SwLayoutFrm *pLayoutFrm = pCnt->FindPageFrm();
    1139          18 :     if ( !pLayoutFrm || (0 == (pLayoutFrm = (*fnWhichPage)(pLayoutFrm))) )
    1140           0 :         return sal_False;
    1141             : 
    1142             :     //Jetzt den gewuenschen CntntFrm unterhalb der Seite
    1143          18 :     if( 0 == (pCnt = (*fnPosPage)(pLayoutFrm)) )
    1144           0 :         return sal_False;
    1145             :     else
    1146             :     {
    1147             :         // repeated headlines in tables
    1148          18 :         if ( pCnt->IsInTab() && fnPosPage == GetFirstSub )
    1149             :         {
    1150           1 :             const SwTabFrm* pTab = pCnt->FindTabFrm();
    1151           1 :             if ( pTab->IsFollow() )
    1152             :             {
    1153           1 :                 if ( pTab->IsInHeadline( *pCnt ) )
    1154             :                 {
    1155           0 :                     SwLayoutFrm* pRow = pTab->GetFirstNonHeadlineRow();
    1156           0 :                     if ( pRow )
    1157             :                     {
    1158             :                         // We are in the first line of a follow table
    1159             :                         // with repeated headings.
    1160             :                         // To actually make a "real" move we take the first content
    1161             :                         // of the next row
    1162           0 :                         pCnt = pRow->ContainsCntnt();
    1163           0 :                         if ( ! pCnt )
    1164           0 :                             return sal_False;
    1165             :                     }
    1166             :                 }
    1167             :             }
    1168             :         }
    1169             : 
    1170          18 :         SwCntntNode *pCNd = (SwCntntNode*)pCnt->GetNode();
    1171          18 :         pPam->GetPoint()->nNode = *pCNd;
    1172             :         xub_StrLen nIdx;
    1173          18 :         if( fnPosPage == GetFirstSub )
    1174          16 :             nIdx = ((SwTxtFrm*)pCnt)->GetOfst();
    1175             :         else
    1176           2 :             nIdx = pCnt->GetFollow() ?
    1177           2 :                     ((SwTxtFrm*)pCnt)->GetFollow()->GetOfst()-1 : pCNd->Len();
    1178          18 :         pPam->GetPoint()->nContent.Assign( pCNd, nIdx );
    1179          18 :         return sal_True;
    1180             :     }
    1181             : }
    1182             : 
    1183             : /*************************************************************************
    1184             : |*
    1185             : |*  SwLayoutFrm::GetCntntPos()
    1186             : |*
    1187             : |*  Beschreibung        Es wird der nachstliegende Cntnt zum uebergebenen
    1188             : |*                      gesucht. Betrachtet werden die vorhergehende, die
    1189             : |*                      aktuelle und die folgende Seite.
    1190             : |*                      Wenn kein Inhalt gefunden wird, so wird der Bereich
    1191             :  *                      erweitert bis einer gefunden wird.
    1192             : |*                      Zurueckgegeben wird die 'Semantisch richtige' Position
    1193             : |*                      innerhalb der PrtArea des gefundenen CntntFrm
    1194             : |*
    1195             : |*************************************************************************/
    1196         123 : sal_uLong CalcDiff( const Point &rPt1, const Point &rPt2 )
    1197             : {
    1198             :     //Jetzt die Entfernung zwischen den beiden Punkten berechnen.
    1199             :     //'Delta' X^2 + 'Delta'Y^2 = 'Entfernung'^2
    1200         369 :     sal_uInt32 dX = std::max( rPt1.X(), rPt2.X() ) -
    1201         246 :                std::min( rPt1.X(), rPt2.X() ),
    1202         369 :           dY = std::max( rPt1.Y(), rPt2.Y() ) -
    1203         246 :                std::min( rPt1.Y(), rPt2.Y() );
    1204         123 :     BigInt dX1( dX ), dY1( dY );
    1205         123 :     dX1 *= dX1; dY1 *= dY1;
    1206         123 :     return ::SqRt( dX1 + dY1 );
    1207             : }
    1208             : 
    1209             : // lcl_Inside ueberprueft, ob der Punkt innerhalb des Seitenteils liegt, in dem
    1210             : // auch der CntntFrame liegt. Als Seitenteile gelten in diesem Zusammenhang
    1211             : // Kopfzeile, Seitenbody, Fusszeile und FussnotenContainer.
    1212             : // Dies dient dazu, dass ein CntntFrm, der im "richtigen" Seitenteil liegt,
    1213             : // eher akzeptiert wird als ein anderer, der nicht dort liegt, auch wenn
    1214             : // dessen Abstand zum Punkt geringer ist.
    1215             : 
    1216         123 : static const SwLayoutFrm* lcl_Inside( const SwCntntFrm *pCnt, Point& rPt )
    1217             : {
    1218         123 :     const SwLayoutFrm* pUp = pCnt->GetUpper();
    1219         246 :     while( pUp )
    1220             :     {
    1221         123 :         if( pUp->IsPageBodyFrm() || pUp->IsFooterFrm() || pUp->IsHeaderFrm() )
    1222             :         {
    1223         123 :             if( rPt.Y() >= pUp->Frm().Top() && rPt.Y() <= pUp->Frm().Bottom() )
    1224         120 :                 return pUp;
    1225           3 :             return NULL;
    1226             :         }
    1227           0 :         if( pUp->IsFtnContFrm() )
    1228           0 :             return pUp->Frm().IsInside( rPt ) ? pUp : NULL;
    1229           0 :         pUp = pUp->GetUpper();
    1230             :     }
    1231           0 :     return NULL;
    1232             : }
    1233             : 
    1234         132 : const SwCntntFrm *SwLayoutFrm::GetCntntPos( Point& rPoint,
    1235             :                                             const sal_Bool bDontLeave,
    1236             :                                             const sal_Bool bBodyOnly,
    1237             :                                             const sal_Bool bCalc,
    1238             :                                             const SwCrsrMoveState *pCMS,
    1239             :                                             const sal_Bool bDefaultExpand ) const
    1240             : {
    1241             :     //Ersten CntntFrm ermitteln.
    1242         132 :     const SwLayoutFrm *pStart = (!bDontLeave && bDefaultExpand && GetPrev()) ?
    1243         132 :                                     (SwLayoutFrm*)GetPrev() : this;
    1244         132 :     const SwCntntFrm *pCntnt = pStart->ContainsCntnt();
    1245             : 
    1246         132 :     if ( !pCntnt && (GetPrev() && !bDontLeave) )
    1247           0 :         pCntnt = ContainsCntnt();
    1248             : 
    1249         132 :     if ( bBodyOnly && pCntnt && !pCntnt->IsInDocBody() )
    1250           0 :         while ( pCntnt && !pCntnt->IsInDocBody() )
    1251           0 :             pCntnt = pCntnt->GetNextCntntFrm();
    1252             : 
    1253         132 :     const SwCntntFrm *pActual= pCntnt;
    1254         132 :     const SwLayoutFrm *pInside = NULL;
    1255         132 :     sal_uInt16 nMaxPage = GetPhyPageNum() + (bDefaultExpand ? 1 : 0);
    1256         132 :     Point aPoint = rPoint;
    1257         132 :     sal_uLong nDistance = ULONG_MAX;
    1258             : 
    1259             :     while ( true )  //Sicherheitsschleifchen, damit immer einer gefunden wird.
    1260             :     {
    1261         528 :         while ( pCntnt &&
    1262         132 :                 ((!bDontLeave || IsAnLower( pCntnt )) &&
    1263         132 :                 (pCntnt->GetPhyPageNum() <= nMaxPage)) )
    1264             :         {
    1265         263 :             if ( ( bCalc || pCntnt->Frm().Width() ) &&
    1266           1 :                  ( !bBodyOnly || pCntnt->IsInDocBody() ) )
    1267             :             {
    1268             :                 //Wenn der Cntnt in einem geschuetzen Bereich (Zelle, Ftn, Section)
    1269             :                 //liegt, wird der nachste Cntnt der nicht geschuetzt ist gesucht.
    1270         131 :                 const SwCntntFrm *pComp = pCntnt;
    1271             :                 pCntnt = ::lcl_MissProtectedFrames( pCntnt, lcl_GetNxtCnt, sal_False,
    1272         131 :                                         pCMS ? pCMS->bSetInReadOnly : sal_False, sal_False );
    1273         131 :                 if ( pComp != pCntnt )
    1274           0 :                     continue;
    1275             : 
    1276         131 :                 if ( !pCntnt->IsTxtFrm() || !((SwTxtFrm*)pCntnt)->IsHiddenNow() )
    1277             :                 {
    1278         123 :                     if ( bCalc )
    1279           0 :                         pCntnt->Calc();
    1280             : 
    1281         123 :                     SwRect aCntFrm( pCntnt->UnionFrm() );
    1282         123 :                     if ( aCntFrm.IsInside( rPoint ) )
    1283             :                     {
    1284           0 :                         pActual = pCntnt;
    1285           0 :                         aPoint = rPoint;
    1286           0 :                         break;
    1287             :                     }
    1288             :                     //Die Strecke von rPoint zum dichtesten Punkt von pCntnt wird
    1289             :                     //jetzt berechnet.
    1290         123 :                     Point aCntntPoint( rPoint );
    1291             : 
    1292             :                     //Erst die Vertikale Position einstellen
    1293         123 :                     if ( aCntFrm.Top() > aCntntPoint.Y() )
    1294           3 :                         aCntntPoint.Y() = aCntFrm.Top();
    1295         120 :                     else if ( aCntFrm.Bottom() < aCntntPoint.Y() )
    1296         120 :                         aCntntPoint.Y() = aCntFrm.Bottom();
    1297             : 
    1298             :                     //Jetzt die Horizontale Position
    1299         123 :                     if ( aCntFrm.Left() > aCntntPoint.X() )
    1300           2 :                         aCntntPoint.X() = aCntFrm.Left();
    1301         121 :                     else if ( aCntFrm.Right() < aCntntPoint.X() )
    1302           0 :                         aCntntPoint.X() = aCntFrm.Right();
    1303             : 
    1304             :                     // pInside ist ein Seitenbereich, in dem der Punkt liegt,
    1305             :                     // sobald pInside!=0 ist, werden nur noch Frames akzeptiert,
    1306             :                     // die innerhalb liegen.
    1307         246 :                     if( !pInside || ( pInside->IsAnLower( pCntnt ) &&
    1308           0 :                         ( !pCntnt->IsInFtn() || pInside->IsFtnContFrm() ) ) )
    1309             :                     {
    1310         123 :                         const sal_uLong nDiff = ::CalcDiff( aCntntPoint, rPoint );
    1311         123 :                         sal_Bool bBetter = nDiff < nDistance;  // Dichter dran
    1312         123 :                         if( !pInside )
    1313             :                         {
    1314         123 :                             pInside = lcl_Inside( pCntnt, rPoint );
    1315         123 :                             if( pInside )  // Im "richtigen" Seitenteil
    1316         120 :                                 bBetter = sal_True;
    1317             :                         }
    1318         123 :                         if( bBetter )
    1319             :                         {
    1320         123 :                             aPoint = aCntntPoint;
    1321         123 :                             nDistance = nDiff;
    1322         123 :                             pActual = pCntnt;
    1323             :                         }
    1324             :                     }
    1325             :                 }
    1326             :             }
    1327         132 :             pCntnt = pCntnt->GetNextCntntFrm();
    1328         132 :             if ( bBodyOnly )
    1329           2 :                 while ( pCntnt && !pCntnt->IsInDocBody() )
    1330           0 :                     pCntnt = pCntnt->GetNextCntntFrm();
    1331             :         }
    1332         132 :         if ( !pActual )
    1333             :         {   //Wenn noch keiner gefunden wurde muss der Suchbereich erweitert
    1334             :             //werden, irgenwann muessen wir einen Finden!
    1335             :             //MA 09. Jan. 97: Opt fuer viele leere Seiten, wenn wir nur im
    1336             :             //Body suchen, koennen wir den Suchbereich gleich in einem
    1337             :             //Schritt hinreichend erweitern.
    1338           0 :             if ( bBodyOnly )
    1339             :             {
    1340           0 :                 while ( !pCntnt && pStart->GetPrev() )
    1341             :                 {
    1342           0 :                     ++nMaxPage;
    1343           0 :                     if( !pStart->GetPrev()->IsLayoutFrm() )
    1344           0 :                         return 0;
    1345           0 :                     pStart = (SwLayoutFrm*)pStart->GetPrev();
    1346           0 :                     pCntnt = pStart->IsInDocBody()
    1347             :                                 ? pStart->ContainsCntnt()
    1348           0 :                                 : pStart->FindPageFrm()->FindFirstBodyCntnt();
    1349             :                 }
    1350           0 :                 if ( !pCntnt )  //irgendwann muessen wir mit irgendeinem Anfangen!
    1351             :                 {
    1352           0 :                     pCntnt = pStart->FindPageFrm()->GetUpper()->ContainsCntnt();
    1353           0 :                     while ( pCntnt && !pCntnt->IsInDocBody() )
    1354           0 :                         pCntnt = pCntnt->GetNextCntntFrm();
    1355           0 :                     if ( !pCntnt )
    1356           0 :                         return 0;   //Es gibt noch keine Dokumentinhalt!
    1357             :                 }
    1358             :             }
    1359             :             else
    1360             :             {
    1361           0 :                 ++nMaxPage;
    1362           0 :                 if ( pStart->GetPrev() )
    1363             :                 {
    1364           0 :                     if( !pStart->GetPrev()->IsLayoutFrm() )
    1365           0 :                         return 0;
    1366           0 :                     pStart = (SwLayoutFrm*)pStart->GetPrev();
    1367           0 :                     pCntnt = pStart->ContainsCntnt();
    1368             :                 }
    1369             :                 else //irgendwann muessen wir mit irgendeinem Anfangen!
    1370           0 :                     pCntnt = pStart->FindPageFrm()->GetUpper()->ContainsCntnt();
    1371             :             }
    1372           0 :             pActual = pCntnt;
    1373             :         }
    1374             :         else
    1375         132 :             break;
    1376             :     }
    1377             : 
    1378             :     OSL_ENSURE( pActual, "no Cntnt found." );
    1379             :     OSL_ENSURE( !bBodyOnly || pActual->IsInDocBody(), "Cntnt not in Body." );
    1380             : 
    1381             :     //Spezialfall fuer das selektieren von Tabellen, nicht in wiederholte
    1382             :     //TblHedlines.
    1383         132 :     if ( pActual->IsInTab() && pCMS && pCMS->eState == MV_TBLSEL )
    1384             :     {
    1385           0 :         const SwTabFrm *pTab = pActual->FindTabFrm();
    1386           0 :         if ( pTab->IsFollow() && pTab->IsInHeadline( *pActual ) )
    1387             :         {
    1388           0 :             ((SwCrsrMoveState*)pCMS)->bStop = sal_True;
    1389           0 :             return 0;
    1390             :         }
    1391             :     }
    1392             : 
    1393             :     //Jetzt noch eine kleine Korrektur beim ersten/letzten
    1394         132 :     Size aActualSize( pActual->Prt().SSize() );
    1395         132 :     if ( aActualSize.Height() > pActual->GetUpper()->Prt().Height() )
    1396           0 :         aActualSize.Height() = pActual->GetUpper()->Prt().Height();
    1397             : 
    1398         132 :     SWRECTFN( pActual )
    1399         264 :     if ( !pActual->GetPrev() &&
    1400         264 :          (*fnRect->fnYDiff)( (pActual->*fnRect->fnGetPrtTop)(),
    1401         396 :                               bVert ? rPoint.X() : rPoint.Y() ) > 0 )
    1402             :     {
    1403           3 :         aPoint.Y() = pActual->Frm().Top() + pActual->Prt().Top();
    1404           9 :         aPoint.X() = pActual->Frm().Left() +
    1405           6 :                         ( pActual->IsRightToLeft() || bVert ?
    1406           0 :                           pActual->Prt().Right() :
    1407           6 :                           pActual->Prt().Left() );
    1408             :     }
    1409         258 :     else if ( !pActual->GetNext() &&
    1410         258 :               (*fnRect->fnYDiff)( (pActual->*fnRect->fnGetPrtBottom)(),
    1411         387 :                                    bVert ? rPoint.X() : rPoint.Y() ) < 0 )
    1412             :     {
    1413         126 :         aPoint.Y() = pActual->Frm().Top() + pActual->Prt().Bottom();
    1414         378 :         aPoint.X() = pActual->Frm().Left() +
    1415         252 :                         ( pActual->IsRightToLeft() || bVert ?
    1416           0 :                           pActual->Prt().Left() :
    1417         252 :                           pActual->Prt().Right() );
    1418             :     }
    1419             : 
    1420             :     //Und den Point in die PrtArea bringen
    1421         132 :     if ( bCalc )
    1422           0 :         pActual->Calc();
    1423         264 :     const SwRect aRect( pActual->Frm().Pos() + pActual->Prt().Pos(),
    1424         132 :                         aActualSize );
    1425         132 :     if ( aPoint.Y() < aRect.Top() )
    1426           0 :         aPoint.Y() = aRect.Top();
    1427         132 :     else if ( aPoint.Y() > aRect.Bottom() )
    1428           0 :         aPoint.Y() = aRect.Bottom();
    1429         132 :     if ( aPoint.X() < aRect.Left() )
    1430           0 :         aPoint.X() = aRect.Left();
    1431         132 :     else if ( aPoint.X() > aRect.Right() )
    1432           0 :         aPoint.X() = aRect.Right();
    1433         132 :     rPoint = aPoint;
    1434         132 :     return pActual;
    1435             : }
    1436             : 
    1437             : /*************************************************************************
    1438             : |*
    1439             : |*  SwPageFrm::GetCntntPosition()
    1440             : |*
    1441             : |*  Beschreibung        Analog zu SwLayoutFrm::GetCntntPos().
    1442             : |*                      Spezialisiert fuer Felder in Rahmen.
    1443             : |*
    1444             : |*************************************************************************/
    1445           0 : void SwPageFrm::GetCntntPosition( const Point &rPt, SwPosition &rPos ) const
    1446             : {
    1447             :     //Ersten CntntFrm ermitteln.
    1448           0 :     const SwCntntFrm *pCntnt = ContainsCntnt();
    1449           0 :     if ( pCntnt )
    1450             :     {
    1451             :         //Einen weiter zurueck schauen (falls moeglich).
    1452           0 :         const SwCntntFrm *pTmp = pCntnt->GetPrevCntntFrm();
    1453           0 :         while ( pTmp && !pTmp->IsInDocBody() )
    1454           0 :             pTmp = pTmp->GetPrevCntntFrm();
    1455           0 :         if ( pTmp )
    1456           0 :             pCntnt = pTmp;
    1457             :     }
    1458             :     else
    1459           0 :         pCntnt = GetUpper()->ContainsCntnt();
    1460             : 
    1461           0 :     const SwCntntFrm *pAct = pCntnt;
    1462           0 :     Point aAct       = rPt;
    1463           0 :     sal_uLong nDist      = ULONG_MAX;
    1464             : 
    1465           0 :     while ( pCntnt )
    1466             :     {
    1467           0 :         SwRect aCntFrm( pCntnt->UnionFrm() );
    1468           0 :         if ( aCntFrm.IsInside( rPt ) )
    1469             :         {
    1470             :             //dichter gehts nimmer.
    1471           0 :             pAct = pCntnt;
    1472           0 :             break;
    1473             :         }
    1474             : 
    1475             :         //Die Strecke von rPt zum dichtesten Punkt von pCntnt berechnen.
    1476           0 :         Point aPoint( rPt );
    1477             : 
    1478             :         //Erst die vertikale Position einstellen
    1479           0 :         if ( aCntFrm.Top() > rPt.Y() )
    1480           0 :             aPoint.Y() = aCntFrm.Top();
    1481           0 :         else if ( aCntFrm.Bottom() < rPt.Y() )
    1482           0 :             aPoint.Y() = aCntFrm.Bottom();
    1483             : 
    1484             :         //Jetzt die horizontale Position
    1485           0 :         if ( aCntFrm.Left() > rPt.X() )
    1486           0 :             aPoint.X() = aCntFrm.Left();
    1487           0 :         else if ( aCntFrm.Right() < rPt.X() )
    1488           0 :             aPoint.X() = aCntFrm.Right();
    1489             : 
    1490           0 :         const sal_uLong nDiff = ::CalcDiff( aPoint, rPt );
    1491           0 :         if ( nDiff < nDist )
    1492             :         {
    1493           0 :             aAct    = aPoint;
    1494           0 :             nDist   = nDiff;
    1495           0 :             pAct    = pCntnt;
    1496             :         }
    1497           0 :         else if ( aCntFrm.Top() > Frm().Bottom() )
    1498             :             //Dichter wirds im Sinne der Felder nicht mehr!
    1499           0 :             break;
    1500             : 
    1501           0 :         pCntnt = pCntnt->GetNextCntntFrm();
    1502           0 :         while ( pCntnt && !pCntnt->IsInDocBody() )
    1503           0 :             pCntnt = pCntnt->GetNextCntntFrm();
    1504             :     }
    1505             : 
    1506             :     //Und den Point in die PrtArea bringen
    1507           0 :     const SwRect aRect( pAct->Frm().Pos() + pAct->Prt().Pos(), pAct->Prt().SSize() );
    1508           0 :     if ( aAct.Y() < aRect.Top() )
    1509           0 :         aAct.Y() = aRect.Top();
    1510           0 :     else if ( aAct.Y() > aRect.Bottom() )
    1511           0 :         aAct.Y() = aRect.Bottom();
    1512           0 :     if ( aAct.X() < aRect.Left() )
    1513           0 :         aAct.X() = aRect.Left();
    1514           0 :     else if ( aAct.X() > aRect.Right() )
    1515           0 :         aAct.X() = aRect.Right();
    1516             : 
    1517           0 :     if( !pAct->IsValid() )
    1518             :     {
    1519             :         // CntntFrm nicht formatiert -> immer auf Node-Anfang
    1520           0 :         SwCntntNode* pCNd = (SwCntntNode*)pAct->GetNode();
    1521             :         OSL_ENSURE( pCNd, "Wo ist mein CntntNode?" );
    1522           0 :         rPos.nNode = *pCNd;
    1523           0 :         rPos.nContent.Assign( pCNd, 0 );
    1524             :     }
    1525             :     else
    1526             :     {
    1527           0 :         SwCrsrMoveState aTmpState( MV_SETONLYTEXT );
    1528           0 :         pAct->GetCrsrOfst( &rPos, aAct, &aTmpState );
    1529             :     }
    1530           0 : }
    1531             : 
    1532             : /*************************************************************************
    1533             : |*
    1534             : |*  SwRootFrm::GetNextPrevCntntPos()
    1535             : |*
    1536             : |*  Beschreibung        Es wird der naechstliegende Cntnt zum uebergebenen
    1537             : |*                      Point gesucht. Es wird nur im BodyText gesucht.
    1538             : |*
    1539             : |*************************************************************************/
    1540             : 
    1541             : // #123110# - helper class to disable creation of an action
    1542             : // by a callback event - e.g., change event from a drawing object
    1543             : class DisableCallbackAction
    1544             : {
    1545             :     private:
    1546             :         SwRootFrm& mrRootFrm;
    1547             :         sal_Bool mbOldCallbackActionState;
    1548             : 
    1549             :     public:
    1550           0 :         DisableCallbackAction( const SwRootFrm& _rRootFrm ) :
    1551             :             mrRootFrm( const_cast<SwRootFrm&>(_rRootFrm) ),
    1552           0 :             mbOldCallbackActionState( _rRootFrm.IsCallbackActionEnabled() )
    1553             :         {
    1554           0 :             mrRootFrm.SetCallbackActionEnabled( sal_False );
    1555           0 :         }
    1556             : 
    1557           0 :         ~DisableCallbackAction()
    1558             :         {
    1559           0 :             mrRootFrm.SetCallbackActionEnabled( mbOldCallbackActionState );
    1560           0 :         }
    1561             : };
    1562             : 
    1563             : //!!!!! Es wird nur der vertikal naechstliegende gesucht.
    1564             : //JP 11.10.2001: only in tables we try to find the right column - Bug 72294
    1565           0 : Point SwRootFrm::GetNextPrevCntntPos( const Point& rPoint, sal_Bool bNext ) const
    1566             : {
    1567             :     // #123110# - disable creation of an action by a callback
    1568             :     // event during processing of this method. Needed because formatting is
    1569             :     // triggered by this method.
    1570           0 :     DisableCallbackAction aDisableCallbackAction( *this );
    1571             :     //Ersten CntntFrm und seinen Nachfolger im Body-Bereich suchen
    1572             :     //Damit wir uns nicht tot suchen (und vor allem nicht zuviel formatieren)
    1573             :     //gehen wir schon mal von der richtigen Seite aus.
    1574           0 :     SwLayoutFrm *pPage = (SwLayoutFrm*)Lower();
    1575           0 :     if( pPage )
    1576           0 :         while( pPage->GetNext() && pPage->Frm().Bottom() < rPoint.Y() )
    1577           0 :             pPage = (SwLayoutFrm*)pPage->GetNext();
    1578             : 
    1579           0 :     const SwCntntFrm *pCnt = pPage ? pPage->ContainsCntnt() : ContainsCntnt();
    1580           0 :     while ( pCnt && !pCnt->IsInDocBody() )
    1581           0 :         pCnt = pCnt->GetNextCntntFrm();
    1582             : 
    1583           0 :     if ( !pCnt )
    1584           0 :         return Point( 0, 0 );
    1585             : 
    1586           0 :     pCnt->Calc();
    1587           0 :     if( !bNext )
    1588             :     {
    1589             :         // Solange der Point vor dem ersten CntntFrm liegt und es noch
    1590             :         // vorhergehende Seiten gibt gehe ich jeweils eine Seite nach vorn.
    1591           0 :         while ( rPoint.Y() < pCnt->Frm().Top() && pPage->GetPrev() )
    1592             :         {
    1593           0 :             pPage = (SwLayoutFrm*)pPage->GetPrev();
    1594           0 :             pCnt = pPage->ContainsCntnt();
    1595           0 :             while ( !pCnt )
    1596             :             {
    1597           0 :                 pPage = (SwLayoutFrm*)pPage->GetPrev();
    1598           0 :                 if ( pPage )
    1599           0 :                     pCnt = pPage->ContainsCntnt();
    1600             :                 else
    1601           0 :                     return ContainsCntnt()->UnionFrm().Pos();
    1602             :             }
    1603           0 :             pCnt->Calc();
    1604             :         }
    1605             :     }
    1606             : 
    1607             :     //Liegt der Point ueber dem ersten CntntFrm?
    1608           0 :     if ( rPoint.Y() < pCnt->Frm().Top() && !lcl_IsInRepeatedHeadline( pCnt ) )
    1609           0 :         return pCnt->UnionFrm().Pos();
    1610             : 
    1611           0 :     while ( pCnt )
    1612             :     {
    1613             :         //Liegt der Point im aktuellen CntntFrm?
    1614           0 :         SwRect aCntFrm( pCnt->UnionFrm() );
    1615           0 :         if ( aCntFrm.IsInside( rPoint ) && !lcl_IsInRepeatedHeadline( pCnt ))
    1616           0 :             return rPoint;
    1617             : 
    1618             :         //Ist der aktuelle der letzte CntntFrm? ||
    1619             :         //Wenn der naechste CntntFrm hinter dem Point liegt, ist der
    1620             :         //aktuelle der gesuchte.
    1621           0 :         const SwCntntFrm *pNxt = pCnt->GetNextCntntFrm();
    1622           0 :         while ( pNxt && !pNxt->IsInDocBody() )
    1623           0 :             pNxt = pNxt->GetNextCntntFrm();
    1624             : 
    1625             :         //Liegt der Point hinter dem letzten CntntFrm?
    1626           0 :         if ( !pNxt )
    1627           0 :             return Point( aCntFrm.Right(), aCntFrm.Bottom() );
    1628             : 
    1629             :         //Wenn der naechste CntntFrm hinter dem Point liegt ist er der
    1630             :         //gesuchte.
    1631             :         const SwTabFrm* pTFrm;
    1632           0 :         pNxt->Calc();
    1633           0 :         if( pNxt->Frm().Top() > rPoint.Y() &&
    1634           0 :             !lcl_IsInRepeatedHeadline( pCnt, &pTFrm ) &&
    1635           0 :             ( !pTFrm || pNxt->Frm().Left() > rPoint.X() ))
    1636             :         {
    1637           0 :             if( bNext )
    1638           0 :                 return pNxt->Frm().Pos();
    1639           0 :             return Point( aCntFrm.Right(), aCntFrm.Bottom() );
    1640             :         }
    1641           0 :         pCnt = pNxt;
    1642             :     }
    1643           0 :     return Point( 0, 0 );
    1644             : }
    1645             : 
    1646             : /*************************************************************************
    1647             : |*
    1648             : |*  SwRootFrm::GetPagePos()
    1649             : |*
    1650             : |*  Beschreibung:   Liefert die absolute Dokumentpositon der gewuenschten
    1651             : |*          Seite.
    1652             : |*          Formatiert wird nur soweit notwendig und nur dann wenn bFormat=sal_True
    1653             : |*          Liefert Null, wenn die Operation nicht moeglich ist.
    1654             : |*          Die Pos ist die der letzten Seite, wenn die Seitenzahl zu gross
    1655             : |*          gewaehlt wurde.
    1656             : |*
    1657             : |*************************************************************************/
    1658           0 : Point SwRootFrm::GetPagePos( sal_uInt16 nPageNum ) const
    1659             : {
    1660             :     OSL_ENSURE( Lower() && Lower()->IsPageFrm(), "Keine Seite vorhanden." );
    1661             : 
    1662           0 :     const SwPageFrm *pPage = (const SwPageFrm*)Lower();
    1663             :     while ( true )
    1664             :     {
    1665           0 :         if ( pPage->GetPhyPageNum() >= nPageNum || !pPage->GetNext() )
    1666           0 :             break;
    1667           0 :         pPage = (const SwPageFrm*)pPage->GetNext();
    1668             :     }
    1669           0 :     return pPage->Frm().Pos();
    1670             : }
    1671             : 
    1672             : /** get page frame by phyiscal page number
    1673             : 
    1674             :     OD 14.01.2003 #103492#
    1675             : 
    1676             :     @return pointer to the page frame with the given physical page number
    1677             : */
    1678           0 : SwPageFrm* SwRootFrm::GetPageByPageNum( sal_uInt16 _nPageNum ) const
    1679             : {
    1680           0 :     const SwPageFrm* pPageFrm = static_cast<const SwPageFrm*>( Lower() );
    1681           0 :     while ( pPageFrm && pPageFrm->GetPhyPageNum() < _nPageNum )
    1682             :     {
    1683           0 :           pPageFrm = static_cast<const SwPageFrm*>( pPageFrm->GetNext() );
    1684             :     }
    1685             : 
    1686           0 :     if ( pPageFrm && pPageFrm->GetPhyPageNum() == _nPageNum )
    1687             :     {
    1688           0 :         return const_cast<SwPageFrm*>( pPageFrm );
    1689             :     }
    1690             :     else
    1691             :     {
    1692           0 :         return 0;
    1693             :     }
    1694             : }
    1695             : 
    1696             : /*************************************************************************
    1697             : |*
    1698             : |*  SwRootFrm::IsDummyPage(sal_uInt16)
    1699             : |*
    1700             : |*  Description: Returns sal_True, when the given physical pagenumber does't exist
    1701             : |*               or this page is an empty page.
    1702             : |*************************************************************************/
    1703           0 : sal_Bool SwRootFrm::IsDummyPage( sal_uInt16 nPageNum ) const
    1704             : {
    1705           0 :     if( !Lower() || !nPageNum || nPageNum > GetPageNum() )
    1706           0 :         return sal_True;
    1707             : 
    1708           0 :     const SwPageFrm *pPage = (const SwPageFrm*)Lower();
    1709           0 :     while( pPage && nPageNum < pPage->GetPhyPageNum() )
    1710           0 :         pPage = (const SwPageFrm*)pPage->GetNext();
    1711           0 :     return pPage ? pPage->IsEmptyPage() : sal_True;
    1712             : }
    1713             : 
    1714             : 
    1715             : /*************************************************************************
    1716             : |*
    1717             : |*    SwFrm::IsProtected()
    1718             : |*
    1719             : |*    Beschreibung      Ist der Frm bzw. die Section in der er steht
    1720             : |*                      geschuetzt?
    1721             : |*                      Auch Fly in Fly in ... und Fussnoten
    1722             : |*
    1723             : |*
    1724             : |*************************************************************************/
    1725       12472 : sal_Bool SwFrm::IsProtected() const
    1726             : {
    1727       12472 :     if (this->IsCntntFrm() && ((SwCntntFrm*)this)->GetNode())
    1728             :     {
    1729       12461 :         const SwDoc *pDoc=((SwCntntFrm*)this)->GetNode()->GetDoc();
    1730       12461 :         bool isFormProtected=pDoc->get(IDocumentSettingAccess::PROTECT_FORM );
    1731       12461 :         if (isFormProtected)
    1732             :         {
    1733           0 :             return sal_False; // TODO a hack for now, well deal with it laster, I we return true here we have a "double" locking
    1734             :         }
    1735             :     }
    1736             :     //Der Frm kann in Rahmen, Zellen oder Bereichen geschuetzt sein.
    1737             :     //Geht auch FlyFrms rekursiv hoch. Geht auch von Fussnoten zum Anker.
    1738       12472 :     const SwFrm *pFrm = this;
    1739       50620 :     do
    1740             :     {
    1741       50620 :         if ( pFrm->IsCntntFrm() )
    1742             :         {
    1743       24952 :             if ( ((SwCntntFrm*)pFrm)->GetNode() &&
    1744       12476 :                  ((SwCntntFrm*)pFrm)->GetNode()->IsInProtectSect() )
    1745           0 :                 return sal_True;
    1746             :         }
    1747             :         else
    1748             :         {
    1749       76288 :             if ( ((SwLayoutFrm*)pFrm)->GetFmt() &&
    1750       38144 :                  ((SwLayoutFrm*)pFrm)->GetFmt()->
    1751       38144 :                  GetProtect().IsCntntProtected() )
    1752           0 :                 return sal_True;
    1753       38144 :             if ( pFrm->IsCoveredCell() )
    1754           0 :                 return sal_True;
    1755             :         }
    1756       50620 :         if ( pFrm->IsFlyFrm() )
    1757             :         {
    1758             :             //Der Schutz des Inhaltes kann bei Verkettung vom Master der Kette
    1759             :             //vorgegeben werden.
    1760          12 :             if ( ((SwFlyFrm*)pFrm)->GetPrevLink() )
    1761             :             {
    1762           0 :                 SwFlyFrm *pMaster = (SwFlyFrm*)pFrm;
    1763           0 :                 do
    1764           0 :                 {   pMaster = pMaster->GetPrevLink();
    1765           0 :                 } while ( pMaster->GetPrevLink() );
    1766           0 :                 if ( pMaster->IsProtected() )
    1767           0 :                     return sal_True;
    1768             :             }
    1769          12 :             pFrm = ((SwFlyFrm*)pFrm)->GetAnchorFrm();
    1770             :         }
    1771       50608 :         else if ( pFrm->IsFtnFrm() )
    1772           5 :             pFrm = ((SwFtnFrm*)pFrm)->GetRef();
    1773             :         else
    1774       50603 :             pFrm = pFrm->GetUpper();
    1775             : 
    1776             :     } while ( pFrm );
    1777             : 
    1778       12472 :     return sal_False;
    1779             : }
    1780             : 
    1781             : /*************************************************************************
    1782             : |*
    1783             : |*    SwFrm::GetPhyPageNum()
    1784             : |*    Beschreibung:     Liefert die physikalische Seitennummer
    1785             : |*
    1786             : |*
    1787             : |*************************************************************************/
    1788        1343 : sal_uInt16 SwFrm::GetPhyPageNum() const
    1789             : {
    1790        1343 :     const SwPageFrm *pPage = FindPageFrm();
    1791        1343 :     return pPage ? pPage->GetPhyPageNum() : 0;
    1792             : }
    1793             : 
    1794             : /*--------------------------------------------------
    1795             :  * SwFrm::WannaRightPage()
    1796             :  * decides if the page want to be a rightpage or not.
    1797             :  * If the first content of the page has a page descriptor,
    1798             :  * we take the follow of the page descriptor of the last not empty page.
    1799             :  * If this descriptor allows only right(left) pages and the page
    1800             :  * isn't an empty page then it wanna be such right(left) page.
    1801             :  * If the descriptor allows right and left pages, we look for a number offset
    1802             :  * in the first content. If there is one, odd number results right pages,
    1803             :  * even number results left pages.
    1804             :  * If there is no number offset, we take the physical page number instead,
    1805             :  * but a previous empty page don't count.
    1806             :  * --------------------------------------------------*/
    1807             : 
    1808         109 : sal_Bool SwFrm::WannaRightPage() const
    1809             : {
    1810         109 :     const SwPageFrm *pPage = FindPageFrm();
    1811         109 :     if ( !pPage || !pPage->GetUpper() )
    1812           0 :         return sal_True;
    1813             : 
    1814         109 :     const SwFrm *pFlow = pPage->FindFirstBodyCntnt();
    1815         109 :     const SwPageDesc *pDesc = 0;
    1816         109 :     sal_uInt16 nPgNum = 0;
    1817         109 :     if ( pFlow )
    1818             :     {
    1819         104 :         if ( pFlow->IsInTab() )
    1820          20 :             pFlow = pFlow->FindTabFrm();
    1821         104 :         const SwFlowFrm *pTmp = SwFlowFrm::CastFlowFrm( pFlow );
    1822         104 :         if ( !pTmp->IsFollow() )
    1823             :         {
    1824         100 :             const SwFmtPageDesc& rPgDesc = pFlow->GetAttrSet()->GetPageDesc();
    1825         100 :             pDesc = rPgDesc.GetPageDesc();
    1826         100 :             nPgNum = rPgDesc.GetNumOffset();
    1827             :         }
    1828             :     }
    1829         109 :     if ( !pDesc )
    1830             :     {
    1831          78 :         SwPageFrm *pPrv = (SwPageFrm*)pPage->GetPrev();
    1832          78 :         if( pPrv && pPrv->IsEmptyPage() )
    1833           0 :             pPrv = (SwPageFrm*)pPrv->GetPrev();
    1834          78 :         if( pPrv )
    1835           7 :             pDesc = pPrv->GetPageDesc()->GetFollow();
    1836             :         else
    1837             :         {
    1838          71 :             const SwDoc* pDoc = pPage->GetFmt()->GetDoc();
    1839          71 :             pDesc = &pDoc->GetPageDesc( 0 );
    1840             :         }
    1841             :     }
    1842             :     OSL_ENSURE( pDesc, "No pagedescriptor" );
    1843             :     sal_Bool bOdd;
    1844         109 :     if( nPgNum )
    1845           1 :         bOdd = (nPgNum % 2) ? sal_True : sal_False;
    1846             :     else
    1847             :     {
    1848         108 :         bOdd = pPage->OnRightPage();
    1849         108 :         if( pPage->GetPrev() && ((SwPageFrm*)pPage->GetPrev())->IsEmptyPage() )
    1850           4 :             bOdd = !bOdd;
    1851             :     }
    1852         109 :     if( !pPage->IsEmptyPage() )
    1853             :     {
    1854         107 :         if( !pDesc->GetRightFmt() )
    1855           4 :             bOdd = sal_False;
    1856         103 :         else if( !pDesc->GetLeftFmt() )
    1857           5 :             bOdd = sal_True;
    1858             :     }
    1859         109 :     return bOdd;
    1860             : }
    1861             : 
    1862         164 : bool SwFrm::OnFirstPage() const
    1863             : {
    1864         164 :     bool bRet = false;
    1865         164 :     const SwPageFrm *pPage = FindPageFrm();
    1866             : 
    1867         164 :     if (pPage)
    1868             :     {
    1869         164 :         const SwPageFrm* pPrevFrm = dynamic_cast<const SwPageFrm*>(pPage->GetPrev());
    1870         164 :         if (pPrevFrm)
    1871             :         {
    1872          67 :             const SwPageDesc* pDesc = pPage->GetPageDesc();
    1873          67 :             bRet = pPrevFrm->GetPageDesc() != pDesc && !pDesc->IsFirstShared();
    1874             :         }
    1875             :         else
    1876          97 :             bRet = true;
    1877             :     }
    1878         164 :     return bRet;
    1879             : }
    1880             : 
    1881             : /*************************************************************************
    1882             : |*
    1883             : |*    SwFrm::GetVirtPageNum()
    1884             : |*    Beschreibung:     Liefert die virtuelle Seitennummer mit Offset
    1885             : |*
    1886             : |*************************************************************************/
    1887        1023 : sal_uInt16 SwFrm::GetVirtPageNum() const
    1888             : {
    1889        1023 :     const SwPageFrm *pPage = FindPageFrm();
    1890        1023 :     if ( !pPage || !pPage->GetUpper() )
    1891           0 :         return 0;
    1892             : 
    1893        1023 :     sal_uInt16 nPhyPage = pPage->GetPhyPageNum();
    1894        1023 :     if ( !((SwRootFrm*)pPage->GetUpper())->IsVirtPageNum() )
    1895        1021 :         return nPhyPage;
    1896             : 
    1897             :     //Den am naechsten stehenden Absatz mit virtueller Seitennummer suchen.
    1898             :     //Da das rueckwaertsuchen insgesamt sehr viel Zeit verschlingt suchen
    1899             :     //wir jetzt gezielt ueber die Abhaengigkeiten.
    1900             :     //von den PageDescs bekommen wir die Attribute, von den Attributen
    1901             :     //wiederum bekommen wir die Absaetze.
    1902           2 :     const SwPageFrm *pVirtPage = 0;
    1903           2 :     const SwFrm *pFrm = 0;
    1904           2 :     const SfxItemPool &rPool = pPage->GetFmt()->GetDoc()->GetAttrPool();
    1905             :     const SfxPoolItem* pItem;
    1906           2 :     sal_uInt32 nMaxItems = rPool.GetItemCount2( RES_PAGEDESC );
    1907          26 :     for( sal_uInt32 n = 0; n < nMaxItems; ++n )
    1908             :     {
    1909          24 :         if( 0 == (pItem = rPool.GetItem2( RES_PAGEDESC, n ) ))
    1910           8 :             continue;
    1911             : 
    1912          16 :         const SwFmtPageDesc *pDesc = (SwFmtPageDesc*)pItem;
    1913          16 :         if ( pDesc->GetNumOffset() && pDesc->GetDefinedIn() )
    1914             :         {
    1915           0 :             const SwModify *pMod = pDesc->GetDefinedIn();
    1916           0 :             SwVirtPageNumInfo aInfo( pPage );
    1917           0 :             pMod->GetInfo( aInfo );
    1918           0 :             if ( aInfo.GetPage() )
    1919             :             {
    1920           0 :                 if( !pVirtPage || ( pVirtPage && aInfo.GetPage()->
    1921           0 :                     GetPhyPageNum() > pVirtPage->GetPhyPageNum() ) )
    1922             :                 {
    1923           0 :                     pVirtPage = aInfo.GetPage();
    1924           0 :                     pFrm = aInfo.GetFrm();
    1925             :                 }
    1926           0 :             }
    1927             :         }
    1928             :     }
    1929           2 :     if ( pFrm )
    1930           0 :         return nPhyPage - pFrm->GetPhyPageNum() +
    1931           0 :                pFrm->GetAttrSet()->GetPageDesc().GetNumOffset();
    1932           2 :     return nPhyPage;
    1933             : }
    1934             : 
    1935             : /*************************************************************************
    1936             : |*
    1937             : |*  SwRootFrm::MakeTblCrsrs()
    1938             : |*
    1939             : |*************************************************************************/
    1940             : //Ermitteln und einstellen derjenigen Zellen die von der Selektion
    1941             : //eingeschlossen sind.
    1942             : 
    1943         345 : bool SwRootFrm::MakeTblCrsrs( SwTableCursor& rTblCrsr )
    1944             : {
    1945             :     //Union-Rects und Tabellen (Follows) der Selektion besorgen.
    1946             :     OSL_ENSURE( rTblCrsr.GetCntntNode() && rTblCrsr.GetCntntNode( sal_False ),
    1947             :             "Tabselection nicht auf Cnt." );
    1948             : 
    1949         345 :     bool bRet = false;
    1950             : 
    1951             :     // For new table models there's no need to ask the layout..
    1952         345 :     if( rTblCrsr.NewTableSelection() )
    1953         345 :         return true;
    1954             : 
    1955           0 :     Point aPtPt, aMkPt;
    1956             :     {
    1957           0 :         SwShellCrsr* pShCrsr = dynamic_cast<SwShellCrsr*>(&rTblCrsr);
    1958             : 
    1959           0 :         if( pShCrsr )
    1960             :         {
    1961           0 :             aPtPt = pShCrsr->GetPtPos();
    1962           0 :             aMkPt = pShCrsr->GetMkPos();
    1963             :         }
    1964             :     }
    1965             : 
    1966             :     // #151012# Made code robust here
    1967           0 :     const SwCntntNode* pTmpStartNode = rTblCrsr.GetCntntNode();
    1968           0 :     const SwCntntNode* pTmpEndNode   = rTblCrsr.GetCntntNode(sal_False);
    1969             : 
    1970           0 :     const SwFrm* pTmpStartFrm = pTmpStartNode ? pTmpStartNode->getLayoutFrm( this, &aPtPt, 0, sal_False ) : 0;
    1971           0 :     const SwFrm* pTmpEndFrm   = pTmpEndNode   ?   pTmpEndNode->getLayoutFrm( this, &aMkPt, 0, sal_False ) : 0;
    1972             : 
    1973           0 :     const SwLayoutFrm* pStart = pTmpStartFrm ? pTmpStartFrm->GetUpper() : 0;
    1974           0 :     const SwLayoutFrm* pEnd   = pTmpEndFrm   ? pTmpEndFrm->GetUpper() : 0;
    1975             : 
    1976             :     OSL_ENSURE( pStart && pEnd, "MakeTblCrsrs: Good to have the code robust here!" );
    1977             : 
    1978             :     /* #109590# Only change table boxes if the frames are
    1979             :         valid. Needed because otherwise the table cursor after moving
    1980             :         table cells by dnd resulted in an empty tables cursor.  */
    1981           0 :     if ( pStart && pEnd && pStart->IsValid() && pEnd->IsValid())
    1982             :     {
    1983           0 :         SwSelUnions aUnions;
    1984           0 :         ::MakeSelUnions( aUnions, pStart, pEnd );
    1985             : 
    1986           0 :         SwSelBoxes aNew;
    1987             : 
    1988           0 :         const sal_Bool bReadOnlyAvailable = rTblCrsr.IsReadOnlyAvailable();
    1989             : 
    1990           0 :         for ( sal_uInt16 i = 0; i < aUnions.size(); ++i )
    1991             :         {
    1992           0 :             SwSelUnion *pUnion = &aUnions[i];
    1993           0 :             const SwTabFrm *pTable = pUnion->GetTable();
    1994             : 
    1995             :             // Skip any repeated headlines in the follow:
    1996           0 :             SwLayoutFrm* pRow = pTable->IsFollow() ?
    1997             :                                 pTable->GetFirstNonHeadlineRow() :
    1998           0 :                                 (SwLayoutFrm*)pTable->Lower();
    1999             : 
    2000           0 :             while ( pRow )
    2001             :             {
    2002           0 :                 if ( pRow->Frm().IsOver( pUnion->GetUnion() ) )
    2003             :                 {
    2004           0 :                     const SwLayoutFrm *pCell = pRow->FirstCell();
    2005             : 
    2006           0 :                     while ( pCell && pRow->IsAnLower( pCell ) )
    2007             :                     {
    2008             :                         OSL_ENSURE( pCell->IsCellFrm(), "Frame ohne Celle" );
    2009           0 :                         if( IsFrmInTblSel( pUnion->GetUnion(), pCell ) &&
    2010           0 :                             (bReadOnlyAvailable ||
    2011           0 :                              !pCell->GetFmt()->GetProtect().IsCntntProtected()))
    2012             :                         {
    2013             :                             SwTableBox* pInsBox = (SwTableBox*)
    2014           0 :                                 ((SwCellFrm*)pCell)->GetTabBox();
    2015           0 :                             aNew.insert( pInsBox );
    2016             :                         }
    2017           0 :                         if ( pCell->GetNext() )
    2018             :                         {
    2019           0 :                             pCell = (const SwLayoutFrm*)pCell->GetNext();
    2020           0 :                             if ( pCell->Lower() && pCell->Lower()->IsRowFrm() )
    2021           0 :                                 pCell = pCell->FirstCell();
    2022             :                         }
    2023             :                         else
    2024             :                         {
    2025           0 :                             const SwLayoutFrm* pLastCell = pCell;
    2026           0 :                             do
    2027             :                             {
    2028           0 :                                 pCell = pCell->GetNextLayoutLeaf();
    2029           0 :                             } while ( pCell && pLastCell->IsAnLower( pCell ) );
    2030             :                             // Fuer (spaltige) Bereiche...
    2031           0 :                             if( pCell && pCell->IsInTab() )
    2032             :                             {
    2033           0 :                                 while( !pCell->IsCellFrm() )
    2034             :                                 {
    2035           0 :                                     pCell = pCell->GetUpper();
    2036             :                                     OSL_ENSURE( pCell, "Where's my cell?" );
    2037             :                                 }
    2038             :                             }
    2039             :                         }
    2040             :                     }
    2041             :                 }
    2042           0 :                 pRow = (SwLayoutFrm*)pRow->GetNext();
    2043             :             }
    2044             :         }
    2045             : 
    2046           0 :         rTblCrsr.ActualizeSelection( aNew );
    2047           0 :         bRet = true;
    2048             :     }
    2049             : 
    2050           0 :     return bRet;
    2051             : }
    2052             : 
    2053             : 
    2054             : /*************************************************************************
    2055             : |*
    2056             : |*  SwRootFrm::CalcFrmRects
    2057             : |*
    2058             : |*************************************************************************/
    2059             : 
    2060             : /*
    2061             :  * nun koennen folgende Situationen auftreten:
    2062             :  *  1. Start und Ende liegen in einer Bildschirm - Zeile und im
    2063             :  *     gleichen Node
    2064             :  *      -> aus Start und End ein Rectangle, dann Ok
    2065             :  *  2. Start und Ende liegen in einem Frame (dadurch im gleichen Node!)
    2066             :  *      -> Start nach rechts, End nach links erweitern,
    2067             :  *         und bei mehr als 2 Bildschirm - Zeilen, das dazwischen
    2068             :  *         liegende berechnen
    2069             :  *  3. Start und Ende liegen in verschiedenen Frames
    2070             :  *      -> Start nach rechts erweitern, bis Frame-Ende Rect berechnen
    2071             :  *         Ende nach links erweitern, bis Frame-Start Rect berechnen
    2072             :  *         und bei mehr als 2 Frames von allen dazwischen liegenden
    2073             :  *         Frames die PrtArea dazu.
    2074             :  *  4. Wenn es sich um eine Tabellenselektion handelt wird fuer jeden
    2075             :  *     PaM im Ring der CellFrm besorgt, dessen PrtArea wird zu den
    2076             :  *     Rechtecken addiert.
    2077             :  *
    2078             :  * Grosser Umbau wg. der FlyFrm; denn diese muessen ausgespart werden.
    2079             :  * Ausnahmen: - Der Fly in dem die Selektion stattfindet (wenn sie in einem Fly
    2080             :  *              stattfindet).
    2081             :  *            - Die Flys, die vom Text unterlaufen werden.
    2082             :  * Arbeitsweise: Zuerst wird eine SwRegion mit der Root initialisiert.
    2083             :  *               Aus der Region werden die zu invertierenden Bereiche
    2084             :  *               ausgestantzt. Die Region wird Komprimiert und letztlich
    2085             :  *               invertiert. Damit liegen dann die zu invertierenden
    2086             :  *               Rechtecke vor.
    2087             :  *               Am Ende werden die Flys aus der Region ausgestanzt.
    2088             :  */
    2089             : 
    2090         349 : inline void Sub( SwRegionRects& rRegion, const SwRect& rRect )
    2091             : {
    2092         679 :     if( rRect.Width() > 1 && rRect.Height() > 1 &&
    2093         330 :         rRect.IsOver( rRegion.GetOrigin() ))
    2094         315 :         rRegion -= rRect;
    2095         349 : }
    2096             : 
    2097         233 : void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
    2098             : {
    2099         233 :     SwPosition *pStartPos = rCrsr.Start(),
    2100         233 :                *pEndPos   = rCrsr.GetPoint() == pStartPos ? rCrsr.GetMark() : rCrsr.GetPoint();
    2101             : 
    2102         233 :     ViewShell *pSh = GetCurrShell();
    2103             : 
    2104             : // #i12836# enhanced pdf
    2105         233 :     SwRegionRects aRegion( pSh && !pSh->GetViewOptions()->IsPDFExport() ?
    2106             :                            pSh->VisArea() :
    2107         466 :                            Frm() );
    2108         699 :     if( !pStartPos->nNode.GetNode().IsCntntNode() ||
    2109         466 :         !pStartPos->nNode.GetNode().GetCntntNode()->getLayoutFrm(this) ||
    2110         239 :         ( pStartPos->nNode != pEndPos->nNode &&
    2111          12 :           ( !pEndPos->nNode.GetNode().IsCntntNode() ||
    2112           6 :             !pEndPos->nNode.GetNode().GetCntntNode()->getLayoutFrm(this) ) ) )
    2113             :     {
    2114         233 :         return;
    2115             :     }
    2116             : 
    2117             :     //Erstmal die CntntFrms zum Start und End besorgen, die brauch ich auf
    2118             :     //jedenfall.
    2119         233 :     SwCntntFrm const* pStartFrm = pStartPos->nNode.GetNode().
    2120         466 :         GetCntntNode()->getLayoutFrm( this, &rCrsr.GetSttPos(), pStartPos );
    2121             : 
    2122         233 :     SwCntntFrm const* pEndFrm   = pEndPos->nNode.GetNode().
    2123         466 :         GetCntntNode()->getLayoutFrm( this, &rCrsr.GetEndPos(), pEndPos );
    2124             : 
    2125             :     OSL_ENSURE( (pStartFrm && pEndFrm), "Keine CntntFrms gefunden." );
    2126             : 
    2127             :     //Damit die FlyFrms, in denen selektierte Frames stecken, nicht
    2128             :     //abgezogen werden
    2129         466 :     SwSortedObjs aSortObjs;
    2130         233 :     if ( pStartFrm->IsInFly() )
    2131             :     {
    2132           0 :         const SwAnchoredObject* pObj = pStartFrm->FindFlyFrm();
    2133             :         OSL_ENSURE( pObj, "No Start Object." );
    2134           0 :         if (pObj) aSortObjs.Insert( *(const_cast<SwAnchoredObject*>(pObj)) );
    2135           0 :         const SwAnchoredObject* pObj2 = pEndFrm->FindFlyFrm();
    2136             :         OSL_ENSURE( pObj2, "SwRootFrm::CalcFrmRects(..) - FlyFrame missing - looks like an invalid selection" );
    2137           0 :         if ( pObj2 != NULL && pObj2 != pObj )
    2138             :         {
    2139           0 :             aSortObjs.Insert( *(const_cast<SwAnchoredObject*>(pObj2)) );
    2140             :         }
    2141             :     }
    2142             : 
    2143             :     //Fall 4: Tabellenselection
    2144         233 :     if( bIsTblMode )
    2145             :     {
    2146           0 :         const SwFrm *pCell = pStartFrm->GetUpper();
    2147           0 :         while ( !pCell->IsCellFrm() )
    2148           0 :             pCell = pCell->GetUpper();
    2149           0 :         SwRect aTmp( pCell->Prt() );
    2150           0 :         aTmp.Pos() += pCell->Frm().Pos();
    2151           0 :         aRegion.ChangeOrigin( aTmp );
    2152           0 :         aRegion.clear();
    2153           0 :         aRegion.push_back( aTmp);
    2154             :     }
    2155             :     else
    2156             :     {
    2157             :         // falls eine nicht erlaubte Selection besteht, dann korrigiere das
    2158             :         // nicht erlaubt ist Header/Footer/TableHeadline ueber 2 Seiten
    2159             :         do {    // middle check loop
    2160         233 :             const SwLayoutFrm* pSttLFrm = pStartFrm->GetUpper();
    2161         233 :             const sal_uInt16 cHdFtTblHd = FRM_HEADER | FRM_FOOTER | FRM_TAB;
    2162        1864 :             while( pSttLFrm &&
    2163         699 :                 ! (cHdFtTblHd & pSttLFrm->GetType() ))
    2164         699 :                 pSttLFrm = pSttLFrm->GetUpper();
    2165         233 :             if( !pSttLFrm )
    2166         233 :                 break;
    2167           0 :             const SwLayoutFrm* pEndLFrm = pEndFrm->GetUpper();
    2168           0 :             while( pEndLFrm &&
    2169           0 :                 ! (cHdFtTblHd & pEndLFrm->GetType() ))
    2170           0 :                 pEndLFrm = pEndLFrm->GetUpper();
    2171           0 :             if( !pEndLFrm )
    2172           0 :                 break;
    2173             : 
    2174             :             OSL_ENSURE( pEndLFrm->GetType() == pSttLFrm->GetType(),
    2175             :                 "Selection ueber unterschiedliche Inhalte" );
    2176           0 :             switch( pSttLFrm->GetType() )
    2177             :             {
    2178             :             case FRM_HEADER:
    2179             :             case FRM_FOOTER:
    2180             :                 // auf unterschiedlichen Seiten ??
    2181             :                 // dann immer auf die Start-Seite
    2182           0 :                 if( pEndLFrm->FindPageFrm() != pSttLFrm->FindPageFrm() )
    2183             :                 {
    2184             :                     // End- auf den Start-CntntFrame setzen
    2185           0 :                     if( pStartPos == rCrsr.GetPoint() )
    2186           0 :                         pEndFrm = pStartFrm;
    2187             :                     else
    2188           0 :                         pStartFrm = pEndFrm;
    2189             :                 }
    2190           0 :                 break;
    2191             :             case FRM_TAB:
    2192             :                 // auf unterschiedlichen Seiten ??
    2193             :                 // existiert
    2194             :                 // dann teste auf Tabelle-Headline
    2195             :                 {
    2196           0 :                     const SwTabFrm* pTabFrm = (SwTabFrm*)pSttLFrm;
    2197           0 :                     if( ( pTabFrm->GetFollow() ||
    2198           0 :                         ((SwTabFrm*)pEndLFrm)->GetFollow() ) &&
    2199           0 :                         pTabFrm->GetTable()->GetRowsToRepeat() > 0 &&
    2200           0 :                         pTabFrm->GetLower() != ((SwTabFrm*)pEndLFrm)->GetLower() &&
    2201           0 :                         ( lcl_IsInRepeatedHeadline( pStartFrm ) ||
    2202           0 :                         lcl_IsInRepeatedHeadline( pEndFrm ) ) )
    2203             :                     {
    2204             :                         // End- auf den Start-CntntFrame setzen
    2205           0 :                         if( pStartPos == rCrsr.GetPoint() )
    2206           0 :                             pEndFrm = pStartFrm;
    2207             :                         else
    2208           0 :                             pStartFrm = pEndFrm;
    2209             :                     }
    2210             :                 }
    2211           0 :                 break;
    2212             :             }
    2213             :         } while( false );
    2214             : 
    2215         233 :         SwCrsrMoveState aTmpState( MV_NONE );
    2216         233 :         aTmpState.b2Lines = sal_True;
    2217         233 :         aTmpState.bNoScroll = sal_True;
    2218         233 :         aTmpState.nCursorBidiLevel = pStartFrm->IsRightToLeft() ? 1 : 0;
    2219             : 
    2220             :         //CntntRects zu Start- und EndFrms.
    2221         233 :         SwRect aStRect, aEndRect;
    2222         233 :         pStartFrm->GetCharRect( aStRect, *pStartPos, &aTmpState );
    2223         233 :         Sw2LinesPos *pSt2Pos = aTmpState.p2Lines;
    2224         233 :         aTmpState.p2Lines = NULL;
    2225         233 :         aTmpState.nCursorBidiLevel = pEndFrm->IsRightToLeft() ? 1 : 0;
    2226             : 
    2227         233 :         pEndFrm->GetCharRect  ( aEndRect, *pEndPos, &aTmpState );
    2228         233 :         Sw2LinesPos *pEnd2Pos = aTmpState.p2Lines;
    2229             : 
    2230         233 :         SwRect aStFrm ( pStartFrm->UnionFrm( sal_True ) );
    2231         233 :         aStFrm.Intersection( pStartFrm->PaintArea() );
    2232         233 :         SwRect aEndFrm( pStartFrm == pEndFrm ? aStFrm : pEndFrm->UnionFrm( sal_True ) );
    2233         233 :         if( pStartFrm != pEndFrm )
    2234             :         {
    2235           9 :             aEndFrm.Intersection( pEndFrm->PaintArea() );
    2236             :         }
    2237         233 :         SWRECTFN( pStartFrm )
    2238         233 :         const sal_Bool bR2L = pStartFrm->IsRightToLeft();
    2239         233 :         const sal_Bool bEndR2L = pEndFrm->IsRightToLeft();
    2240             : 
    2241             :         // If there's no doubleline portion involved or start and end are both
    2242             :         // in the same doubleline portion, all works fine, but otherwise
    2243             :         // we need the following...
    2244         233 :         if( pSt2Pos != pEnd2Pos && ( !pSt2Pos || !pEnd2Pos ||
    2245           0 :             pSt2Pos->aPortion != pEnd2Pos->aPortion ) )
    2246             :         {
    2247             :             // If we have a start(end) position inside a doubleline portion
    2248             :             // the surrounded part of the doubleline portion is subtracted
    2249             :             // from the region and the aStRect(aEndRect) is set to the
    2250             :             // end(start) of the doubleline portion.
    2251          68 :             if( pSt2Pos )
    2252             :             {
    2253           0 :                 SwRect aTmp( aStRect );
    2254             : 
    2255             :                 // BiDi-Portions are swimming against the current.
    2256           0 :                 const sal_Bool bPorR2L = ( MT_BIDI == pSt2Pos->nMultiType ) ?
    2257           0 :                     ! bR2L :
    2258           0 :                 bR2L;
    2259             : 
    2260           0 :                 if( MT_BIDI == pSt2Pos->nMultiType &&
    2261           0 :                     (pSt2Pos->aPortion2.*fnRect->fnGetWidth)() )
    2262             :                 {
    2263             :                     // nested bidi portion
    2264           0 :                     long nRightAbs = (pSt2Pos->aPortion.*fnRect->fnGetRight)();
    2265           0 :                     nRightAbs -= (pSt2Pos->aPortion2.*fnRect->fnGetLeft)();
    2266           0 :                     long nLeftAbs = nRightAbs - (pSt2Pos->aPortion2.*fnRect->fnGetWidth)();
    2267             : 
    2268           0 :                     (aTmp.*fnRect->fnSetRight)( nRightAbs );
    2269             : 
    2270           0 :                     if ( ! pEnd2Pos || pEnd2Pos->aPortion != pSt2Pos->aPortion )
    2271             :                     {
    2272           0 :                         SwRect aTmp2( pSt2Pos->aPortion );
    2273           0 :                         (aTmp2.*fnRect->fnSetRight)( nLeftAbs );
    2274           0 :                         aTmp2.Intersection( aEndFrm );
    2275           0 :                         Sub( aRegion, aTmp2 );
    2276             :                     }
    2277             :                 }
    2278             :                 else
    2279             :                 {
    2280           0 :                     if( bPorR2L )
    2281             :                         (aTmp.*fnRect->fnSetLeft)(
    2282           0 :                             (pSt2Pos->aPortion.*fnRect->fnGetLeft)() );
    2283             :                     else
    2284             :                         (aTmp.*fnRect->fnSetRight)(
    2285           0 :                             (pSt2Pos->aPortion.*fnRect->fnGetRight)() );
    2286             :                 }
    2287             : 
    2288           0 :                 if( MT_ROT_90 == pSt2Pos->nMultiType ||
    2289           0 :                     (pSt2Pos->aPortion.*fnRect->fnGetTop)() ==
    2290           0 :                     (aTmp.*fnRect->fnGetTop)() )
    2291             :                 {
    2292             :                     (aTmp.*fnRect->fnSetTop)(
    2293           0 :                         (pSt2Pos->aLine.*fnRect->fnGetTop)() );
    2294             :                 }
    2295             : 
    2296           0 :                 aTmp.Intersection( aStFrm );
    2297           0 :                 Sub( aRegion, aTmp );
    2298             : 
    2299           0 :                 SwTwips nTmp = (pSt2Pos->aLine.*fnRect->fnGetBottom)();
    2300           0 :                 if( MT_ROT_90 != pSt2Pos->nMultiType &&
    2301           0 :                     (aStRect.*fnRect->fnBottomDist)( nTmp ) > 0 )
    2302             :                 {
    2303           0 :                     (aTmp.*fnRect->fnSetTop)( (aTmp.*fnRect->fnGetBottom)() );
    2304           0 :                     (aTmp.*fnRect->fnSetBottom)( nTmp );
    2305           0 :                     if( (aStRect.*fnRect->fnBottomDist)(
    2306           0 :                         (pSt2Pos->aPortion.*fnRect->fnGetBottom)() ) > 0 )
    2307             :                     {
    2308           0 :                         if( bPorR2L )
    2309             :                             (aTmp.*fnRect->fnSetRight)(
    2310           0 :                                 (pSt2Pos->aPortion.*fnRect->fnGetRight)() );
    2311             :                         else
    2312             :                             (aTmp.*fnRect->fnSetLeft)(
    2313           0 :                                 (pSt2Pos->aPortion.*fnRect->fnGetLeft)() );
    2314             :                     }
    2315           0 :                     aTmp.Intersection( aStFrm );
    2316           0 :                     Sub( aRegion, aTmp );
    2317             :                 }
    2318             : 
    2319           0 :                 aStRect = pSt2Pos->aLine;
    2320             :                 (aStRect.*fnRect->fnSetLeft)( bR2L ?
    2321           0 :                         (pSt2Pos->aPortion.*fnRect->fnGetLeft)() :
    2322           0 :                         (pSt2Pos->aPortion.*fnRect->fnGetRight)() );
    2323           0 :                 (aStRect.*fnRect->fnSetWidth)( 1 );
    2324             :             }
    2325             : 
    2326          68 :             if( pEnd2Pos )
    2327             :             {
    2328          68 :                 SWRECTFNX( pEndFrm )
    2329          68 :                 SwRect aTmp( aEndRect );
    2330             : 
    2331             :                 // BiDi-Portions are swimming against the current.
    2332          68 :                 const sal_Bool bPorR2L = ( MT_BIDI == pEnd2Pos->nMultiType ) ?
    2333           0 :                                            ! bEndR2L :
    2334          68 :                                              bEndR2L;
    2335             : 
    2336          68 :                 if( MT_BIDI == pEnd2Pos->nMultiType &&
    2337           0 :                     (pEnd2Pos->aPortion2.*fnRectX->fnGetWidth)() )
    2338             :                 {
    2339             :                     // nested bidi portion
    2340           0 :                     long nRightAbs = (pEnd2Pos->aPortion.*fnRectX->fnGetRight)();
    2341           0 :                     nRightAbs = nRightAbs - (pEnd2Pos->aPortion2.*fnRectX->fnGetLeft)();
    2342           0 :                     long nLeftAbs = nRightAbs - (pEnd2Pos->aPortion2.*fnRectX->fnGetWidth)();
    2343             : 
    2344           0 :                     (aTmp.*fnRectX->fnSetLeft)( nLeftAbs );
    2345             : 
    2346           0 :                     if ( ! pSt2Pos || pSt2Pos->aPortion != pEnd2Pos->aPortion )
    2347             :                     {
    2348           0 :                         SwRect aTmp2( pEnd2Pos->aPortion );
    2349           0 :                         (aTmp2.*fnRectX->fnSetLeft)( nRightAbs );
    2350           0 :                         aTmp2.Intersection( aEndFrm );
    2351           0 :                         Sub( aRegion, aTmp2 );
    2352             :                     }
    2353             :                 }
    2354             :                 else
    2355             :                 {
    2356          68 :                     if ( bPorR2L )
    2357             :                         (aTmp.*fnRectX->fnSetRight)(
    2358           0 :                             (pEnd2Pos->aPortion.*fnRectX->fnGetRight)() );
    2359             :                     else
    2360             :                         (aTmp.*fnRectX->fnSetLeft)(
    2361          68 :                             (pEnd2Pos->aPortion.*fnRectX->fnGetLeft)() );
    2362             :                 }
    2363             : 
    2364         136 :                 if( MT_ROT_90 == pEnd2Pos->nMultiType ||
    2365          68 :                     (pEnd2Pos->aPortion.*fnRectX->fnGetBottom)() ==
    2366          68 :                     (aEndRect.*fnRectX->fnGetBottom)() )
    2367             :                 {
    2368             :                     (aTmp.*fnRectX->fnSetBottom)(
    2369          24 :                         (pEnd2Pos->aLine.*fnRectX->fnGetBottom)() );
    2370             :                 }
    2371             : 
    2372          68 :                 aTmp.Intersection( aEndFrm );
    2373          68 :                 Sub( aRegion, aTmp );
    2374             : 
    2375             :                 // The next statement means neither ruby nor rotate(90):
    2376          68 :                 if( !( MT_RUBY & pEnd2Pos->nMultiType ) )
    2377             :                 {
    2378          15 :                     SwTwips nTmp = (pEnd2Pos->aLine.*fnRectX->fnGetTop)();
    2379          15 :                     if( (aEndRect.*fnRectX->fnGetTop)() != nTmp )
    2380             :                     {
    2381             :                         (aTmp.*fnRectX->fnSetBottom)(
    2382          15 :                             (aTmp.*fnRectX->fnGetTop)() );
    2383          15 :                         (aTmp.*fnRectX->fnSetTop)( nTmp );
    2384          30 :                         if( (aEndRect.*fnRectX->fnGetTop)() !=
    2385          15 :                             (pEnd2Pos->aPortion.*fnRectX->fnGetTop)() )
    2386             :                         {
    2387          15 :                             if( bPorR2L )
    2388             :                                 (aTmp.*fnRectX->fnSetLeft)(
    2389           0 :                                     (pEnd2Pos->aPortion.*fnRectX->fnGetLeft)() );
    2390             :                             else
    2391             :                                 (aTmp.*fnRectX->fnSetRight)(
    2392          15 :                                     (pEnd2Pos->aPortion.*fnRectX->fnGetRight)() );
    2393             :                         }
    2394          15 :                         aTmp.Intersection( aEndFrm );
    2395          15 :                         Sub( aRegion, aTmp );
    2396             :                     }
    2397             :                 }
    2398             : 
    2399          68 :                 aEndRect = pEnd2Pos->aLine;
    2400             :                 (aEndRect.*fnRectX->fnSetLeft)( bEndR2L ?
    2401           0 :                         (pEnd2Pos->aPortion.*fnRectX->fnGetRight)() :
    2402          68 :                         (pEnd2Pos->aPortion.*fnRectX->fnGetLeft)() );
    2403          68 :                 (aEndRect.*fnRectX->fnSetWidth)( 1 );
    2404             :             }
    2405             :         }
    2406         165 :         else if( pSt2Pos && pEnd2Pos &&
    2407           0 :                  MT_BIDI == pSt2Pos->nMultiType &&
    2408           0 :                  MT_BIDI == pEnd2Pos->nMultiType &&
    2409         165 :                  pSt2Pos->aPortion == pEnd2Pos->aPortion &&
    2410           0 :                  pSt2Pos->aPortion2 != pEnd2Pos->aPortion2 )
    2411             :         {
    2412             :             // This is the ugly special case, where the selection starts and
    2413             :             // ends in the same bidi portion but one start or end is inside a
    2414             :             // nested bidi portion.
    2415             : 
    2416           0 :             if ( (pSt2Pos->aPortion2.*fnRect->fnGetWidth)() )
    2417             :             {
    2418           0 :                 SwRect aTmp( aStRect );
    2419           0 :                 long nRightAbs = (pSt2Pos->aPortion.*fnRect->fnGetRight)();
    2420           0 :                 nRightAbs -= (pSt2Pos->aPortion2.*fnRect->fnGetLeft)();
    2421           0 :                 long nLeftAbs = nRightAbs - (pSt2Pos->aPortion2.*fnRect->fnGetWidth)();
    2422             : 
    2423           0 :                 (aTmp.*fnRect->fnSetRight)( nRightAbs );
    2424           0 :                 aTmp.Intersection( aStFrm );
    2425           0 :                 Sub( aRegion, aTmp );
    2426             : 
    2427           0 :                 aStRect = pSt2Pos->aLine;
    2428           0 :                 (aStRect.*fnRect->fnSetLeft)( bR2L ? nRightAbs : nLeftAbs );
    2429           0 :                 (aStRect.*fnRect->fnSetWidth)( 1 );
    2430             :             }
    2431             : 
    2432           0 :             SWRECTFNX( pEndFrm )
    2433           0 :             if ( (pEnd2Pos->aPortion2.*fnRectX->fnGetWidth)() )
    2434             :             {
    2435           0 :                 SwRect aTmp( aEndRect );
    2436           0 :                 long nRightAbs = (pEnd2Pos->aPortion.*fnRectX->fnGetRight)();
    2437           0 :                 nRightAbs -= (pEnd2Pos->aPortion2.*fnRectX->fnGetLeft)();
    2438           0 :                 long nLeftAbs = nRightAbs - (pEnd2Pos->aPortion2.*fnRectX->fnGetWidth)();
    2439             : 
    2440           0 :                 (aTmp.*fnRectX->fnSetLeft)( nLeftAbs );
    2441           0 :                 aTmp.Intersection( aEndFrm );
    2442           0 :                 Sub( aRegion, aTmp );
    2443             : 
    2444           0 :                 aEndRect = pEnd2Pos->aLine;
    2445           0 :                 (aEndRect.*fnRectX->fnSetLeft)( bEndR2L ? nLeftAbs : nRightAbs );
    2446           0 :                 (aEndRect.*fnRectX->fnSetWidth)( 1 );
    2447             :             }
    2448             :         }
    2449             : 
    2450             :         // The charrect may be outside the paintarea (for cursortravelling)
    2451             :         // but the selection has to be restricted to the paintarea
    2452         233 :         if( aStRect.Left() < aStFrm.Left() )
    2453           1 :             aStRect.Left( aStFrm.Left() );
    2454         232 :         else if( aStRect.Left() > aStFrm.Right() )
    2455           0 :             aStRect.Left( aStFrm.Right() );
    2456         233 :         SwTwips nTmp = aStRect.Right();
    2457         233 :         if( nTmp < aStFrm.Left() )
    2458           1 :             aStRect.Right( aStFrm.Left() );
    2459         232 :         else if( nTmp > aStFrm.Right() )
    2460           0 :             aStRect.Right( aStFrm.Right() );
    2461         233 :         if( aEndRect.Left() < aEndFrm.Left() )
    2462           1 :             aEndRect.Left( aEndFrm.Left() );
    2463         232 :         else if( aEndRect.Left() > aEndFrm.Right() )
    2464           0 :             aEndRect.Left( aEndFrm.Right() );
    2465         233 :         nTmp = aEndRect.Right();
    2466         233 :         if( nTmp < aEndFrm.Left() )
    2467           1 :             aEndRect.Right( aEndFrm.Left() );
    2468         232 :         else if( nTmp > aEndFrm.Right() )
    2469           0 :             aEndRect.Right( aEndFrm.Right() );
    2470             : 
    2471         233 :         if( pStartFrm == pEndFrm )
    2472             :         {
    2473           0 :             sal_Bool bSameRotatedOrBidi = pSt2Pos && pEnd2Pos &&
    2474         224 :                 ( MT_BIDI & pSt2Pos->nMultiType ) &&
    2475         224 :                 pSt2Pos->aPortion == pEnd2Pos->aPortion;
    2476             :             //case 1: (Same frame and same row)
    2477         448 :             if( bSameRotatedOrBidi ||
    2478         224 :                 (aStRect.*fnRect->fnGetTop)() == (aEndRect.*fnRect->fnGetTop)() )
    2479             :             {
    2480         219 :                 Point aTmpSt( aStRect.Pos() );
    2481         219 :                 Point aTmpEnd( aEndRect.Right(), aEndRect.Bottom() );
    2482         219 :                 if( bSameRotatedOrBidi || bR2L )
    2483             :                 {
    2484           0 :                     if( aTmpSt.Y() > aTmpEnd.Y() )
    2485             :                     {
    2486           0 :                         long nTmpY = aTmpEnd.Y();
    2487           0 :                         aTmpEnd.Y() = aTmpSt.Y();
    2488           0 :                         aTmpSt.Y() = nTmpY;
    2489             :                     }
    2490           0 :                     if( aTmpSt.X() > aTmpEnd.X() )
    2491             :                     {
    2492           0 :                         long nTmpX = aTmpEnd.X();
    2493           0 :                         aTmpEnd.X() = aTmpSt.X();
    2494           0 :                         aTmpSt.X() = nTmpX;
    2495             :                     }
    2496             :                 }
    2497             : 
    2498         219 :                 SwRect aTmp = SwRect( aTmpSt, aTmpEnd );
    2499             :                 // Bug 34888: falls Inhalt selektiert ist, der keinen Platz
    2500             :                 //            einnimmt (z.B. PostIts,RefMarks, TOXMarks),
    2501             :                 //            dann mindestens die Breite des Crsr setzen.
    2502         294 :                 if( 1 == (aTmp.*fnRect->fnGetWidth)() &&
    2503          75 :                     pStartPos->nContent.GetIndex() !=
    2504          75 :                     pEndPos->nContent.GetIndex() )
    2505             :                 {
    2506          69 :                     OutputDevice* pOut = pSh->GetOut();
    2507          69 :                     long nCrsrWidth = pOut->GetSettings().GetStyleSettings().
    2508          69 :                         GetCursorSize();
    2509             :                     (aTmp.*fnRect->fnSetWidth)( pOut->PixelToLogic(
    2510          69 :                         Size( nCrsrWidth, 0 ) ).Width() );
    2511             :                 }
    2512         219 :                 aTmp.Intersection( aStFrm );
    2513         219 :                 Sub( aRegion, aTmp );
    2514             :             }
    2515             :             //case 2: (Same frame, but not the same line)
    2516             :             else
    2517             :             {
    2518             :                 SwTwips lLeft, lRight;
    2519           5 :                 if( pSt2Pos && pEnd2Pos && pSt2Pos->aPortion == pEnd2Pos->aPortion )
    2520             :                 {
    2521           0 :                     lLeft = (pSt2Pos->aPortion.*fnRect->fnGetLeft)();
    2522           0 :                     lRight = (pSt2Pos->aPortion.*fnRect->fnGetRight)();
    2523             :                 }
    2524             :                 else
    2525             :                 {
    2526           5 :                     lLeft = (pStartFrm->Frm().*fnRect->fnGetLeft)() +
    2527           5 :                         (pStartFrm->Prt().*fnRect->fnGetLeft)();
    2528           5 :                     lRight = (pStartFrm->Frm().*fnRect->fnGetLeft)() +
    2529           5 :                         (pStartFrm->Prt().*fnRect->fnGetRight)();
    2530             :                 }
    2531           5 :                 if( lLeft < (aStFrm.*fnRect->fnGetLeft)() )
    2532           0 :                     lLeft = (aStFrm.*fnRect->fnGetLeft)();
    2533           5 :                 if( lRight > (aStFrm.*fnRect->fnGetRight)() )
    2534           0 :                     lRight = (aStFrm.*fnRect->fnGetRight)();
    2535           5 :                 SwRect aSubRect( aStRect );
    2536             :                 //First line
    2537           5 :                 if( bR2L )
    2538           0 :                     (aSubRect.*fnRect->fnSetLeft)( lLeft );
    2539             :                 else
    2540           5 :                     (aSubRect.*fnRect->fnSetRight)( lRight );
    2541           5 :                 Sub( aRegion, aSubRect );
    2542             : 
    2543             :                 //If there's at least a twips between start- and endline,
    2544             :                 //so the whole area between will be added.
    2545           5 :                 SwTwips aTmpBottom = (aStRect.*fnRect->fnGetBottom)();
    2546           5 :                 SwTwips aTmpTop = (aEndRect.*fnRect->fnGetTop)();
    2547           5 :                 if( aTmpBottom != aTmpTop )
    2548             :                 {
    2549           5 :                     (aSubRect.*fnRect->fnSetLeft)( lLeft );
    2550           5 :                     (aSubRect.*fnRect->fnSetRight)( lRight );
    2551           5 :                     (aSubRect.*fnRect->fnSetTop)( aTmpBottom );
    2552           5 :                     (aSubRect.*fnRect->fnSetBottom)( aTmpTop );
    2553           5 :                     Sub( aRegion, aSubRect );
    2554             :                 }
    2555             :                 //and the last line
    2556           5 :                 aSubRect = aEndRect;
    2557           5 :                 if( bR2L )
    2558           0 :                     (aSubRect.*fnRect->fnSetRight)( lRight );
    2559             :                 else
    2560           5 :                     (aSubRect.*fnRect->fnSetLeft)( lLeft );
    2561           5 :                 Sub( aRegion, aSubRect );
    2562             :             }
    2563             :         }
    2564             :         //case 3: (Different frames, maybe with ohther frames between
    2565             :         else
    2566             :         {
    2567             :             //The startframe first...
    2568           9 :             SwRect aSubRect( aStRect );
    2569           9 :             if( bR2L )
    2570           0 :                 (aSubRect.*fnRect->fnSetLeft)( (aStFrm.*fnRect->fnGetLeft)());
    2571             :             else
    2572           9 :                 (aSubRect.*fnRect->fnSetRight)( (aStFrm.*fnRect->fnGetRight)());
    2573           9 :             Sub( aRegion, aSubRect );
    2574           9 :             SwTwips nTmpTwips = (aStRect.*fnRect->fnGetBottom)();
    2575           9 :             if( (aStFrm.*fnRect->fnGetBottom)() != nTmpTwips )
    2576             :             {
    2577           7 :                 aSubRect = aStFrm;
    2578           7 :                 (aSubRect.*fnRect->fnSetTop)( nTmpTwips );
    2579           7 :                 Sub( aRegion, aSubRect );
    2580             :             }
    2581             : 
    2582             :             //Now the frames between, if there are any
    2583           9 :             bool const bBody = pStartFrm->IsInDocBody();
    2584           9 :             const SwTableBox* pCellBox = pStartFrm->GetUpper()->IsCellFrm() ?
    2585           9 :                 ((SwCellFrm*)pStartFrm->GetUpper())->GetTabBox() : 0;
    2586           9 :             const SwCntntFrm *pCntnt = pStartFrm->GetNextCntntFrm();
    2587           9 :             SwRect aPrvRect;
    2588             : 
    2589             :             OSL_ENSURE( pCntnt,
    2590             :                 "<SwRootFrm::CalcFrmRects(..)> - no content frame. This is a serious defect -> please inform OD" );
    2591          60 :             while ( pCntnt && pCntnt != pEndFrm )
    2592             :             {
    2593          42 :                 if ( pCntnt->IsInFly() )
    2594             :                 {
    2595           0 :                     const SwAnchoredObject* pObj = pCntnt->FindFlyFrm();
    2596           0 :                     aSortObjs.Insert( *(const_cast<SwAnchoredObject*>(pObj)) );
    2597             :                 }
    2598             : 
    2599             :                 // Consider only frames which have the same IsInDocBody value like pStartFrm
    2600             :                 // If pStartFrm is inside a SwCellFrm, consider only frames which are inside the
    2601             :                 // same cell frame (or its follow cell)
    2602          42 :                 const SwTableBox* pTmpCellBox = pCntnt->GetUpper()->IsCellFrm() ?
    2603          42 :                     ((SwCellFrm*)pCntnt->GetUpper())->GetTabBox() : 0;
    2604          84 :                 if ( bBody == pCntnt->IsInDocBody() &&
    2605           0 :                     ( !pCellBox || pCellBox == pTmpCellBox ) )
    2606             :                 {
    2607          42 :                     SwRect aCRect( pCntnt->UnionFrm( sal_True ) );
    2608          42 :                     aCRect.Intersection( pCntnt->PaintArea() );
    2609          42 :                     if( aCRect.IsOver( aRegion.GetOrigin() ))
    2610             :                     {
    2611           8 :                         SwRect aTmp( aPrvRect );
    2612           8 :                         aTmp.Union( aCRect );
    2613          24 :                         if ( (aPrvRect.Height() * aPrvRect.Width() +
    2614           8 :                             aCRect.Height()   * aCRect.Width()) ==
    2615           8 :                             (aTmp.Height() * aTmp.Width()) )
    2616             :                         {
    2617           4 :                             aPrvRect.Union( aCRect );
    2618             :                         }
    2619             :                         else
    2620             :                         {
    2621           4 :                             if ( aPrvRect.HasArea() )
    2622           0 :                                 Sub( aRegion, aPrvRect );
    2623           4 :                             aPrvRect = aCRect;
    2624             :                         }
    2625             :                     }
    2626             :                 }
    2627          42 :                 pCntnt = pCntnt->GetNextCntntFrm();
    2628             :                 OSL_ENSURE( pCntnt,
    2629             :                     "<SwRootFrm::CalcFrmRects(..)> - no content frame. This is a serious defect -> please inform OD" );
    2630             :             }
    2631           9 :             if ( aPrvRect.HasArea() )
    2632           4 :                 Sub( aRegion, aPrvRect );
    2633             : 
    2634             :             //At least the endframe...
    2635           9 :             bVert = pEndFrm->IsVertical();
    2636           9 :             bRev = pEndFrm->IsReverse();
    2637             :             //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
    2638           0 :             fnRect = bVert ? ( bRev ? fnRectVL2R : ( pEndFrm->IsVertLR() ? fnRectVertL2R : fnRectVert ) ) :
    2639           9 :                 ( bRev ? fnRectB2T : fnRectHori );
    2640           9 :             nTmpTwips = (aEndRect.*fnRect->fnGetTop)();
    2641           9 :             if( (aEndFrm.*fnRect->fnGetTop)() != nTmpTwips )
    2642             :             {
    2643           3 :                 aSubRect = aEndFrm;
    2644           3 :                 (aSubRect.*fnRect->fnSetBottom)( nTmpTwips );
    2645           3 :                 Sub( aRegion, aSubRect );
    2646             :             }
    2647           9 :             aSubRect = aEndRect;
    2648           9 :             if( bEndR2L )
    2649           0 :                 (aSubRect.*fnRect->fnSetRight)((aEndFrm.*fnRect->fnGetRight)());
    2650             :             else
    2651           9 :                 (aSubRect.*fnRect->fnSetLeft)( (aEndFrm.*fnRect->fnGetLeft)() );
    2652           9 :             Sub( aRegion, aSubRect );
    2653             :         }
    2654             : 
    2655         233 :         aRegion.Invert();
    2656         233 :         delete pSt2Pos;
    2657         233 :         delete pEnd2Pos;
    2658             :     }
    2659             : 
    2660             :     //Flys mit Durchlauf ausstanzen. Nicht ausgestanzt werden Flys:
    2661             :     //- die Lower des StartFrm/EndFrm sind (FlyInCnt und alle Flys die wiederum
    2662             :     //  darin sitzen)
    2663             :     //- in der Z-Order ueber denjenigen Flys stehen in denen sich der StartFrm
    2664             :     //  befindet.
    2665         233 :     const SwPageFrm *pPage      = pStartFrm->FindPageFrm();
    2666         233 :     const SwPageFrm *pEndPage   = pEndFrm->FindPageFrm();
    2667             : 
    2668         473 :     while ( pPage )
    2669             :     {
    2670         240 :         if ( pPage->GetSortedObjs() )
    2671             :         {
    2672           0 :             const SwSortedObjs &rObjs = *pPage->GetSortedObjs();
    2673           0 :             for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
    2674             :             {
    2675           0 :                 SwAnchoredObject* pAnchoredObj = rObjs[i];
    2676           0 :                 if ( !pAnchoredObj->ISA(SwFlyFrm) )
    2677           0 :                     continue;
    2678           0 :                 const SwFlyFrm* pFly = static_cast<const SwFlyFrm*>(pAnchoredObj);
    2679           0 :                 const SwVirtFlyDrawObj* pObj = pFly->GetVirtDrawObj();
    2680           0 :                 const SwFmtSurround &rSur = pFly->GetFmt()->GetSurround();
    2681           0 :                 if ( !pFly->IsAnLower( pStartFrm ) &&
    2682           0 :                     (rSur.GetSurround() != SURROUND_THROUGHT &&
    2683           0 :                     !rSur.IsContour()) )
    2684             :                 {
    2685           0 :                     if ( aSortObjs.Contains( *pAnchoredObj ) )
    2686           0 :                         continue;
    2687             : 
    2688           0 :                     sal_Bool bSub = sal_True;
    2689           0 :                     const sal_uInt32 nPos = pObj->GetOrdNum();
    2690           0 :                     for ( sal_uInt16 k = 0; bSub && k < aSortObjs.Count(); ++k )
    2691             :                     {
    2692             :                         OSL_ENSURE( aSortObjs[k]->ISA(SwFlyFrm),
    2693             :                             "<SwRootFrm::CalcFrmRects(..)> - object in <aSortObjs> of unexcepted type" );
    2694           0 :                         const SwFlyFrm* pTmp = static_cast<SwFlyFrm*>(aSortObjs[k]);
    2695           0 :                         do
    2696             :                         {
    2697           0 :                             if ( nPos < pTmp->GetVirtDrawObj()->GetOrdNumDirect() )
    2698             :                             {
    2699           0 :                                 bSub = sal_False;
    2700             :                             }
    2701             :                             else
    2702             :                             {
    2703           0 :                                 pTmp = pTmp->GetAnchorFrm()->FindFlyFrm();
    2704             :                             }
    2705           0 :                         } while ( bSub && pTmp );
    2706             :                     }
    2707           0 :                     if ( bSub )
    2708           0 :                         Sub( aRegion, pFly->Frm() );
    2709             :                 }
    2710             :             }
    2711             :         }
    2712         240 :         if ( pPage == pEndPage )
    2713         233 :             break;
    2714             :         else
    2715           7 :             pPage = (SwPageFrm*)pPage->GetNext();
    2716             :     }
    2717             : 
    2718             :     //Weil's besser aussieht noch die DropCaps ausschliessen.
    2719         233 :     SwRect aDropRect;
    2720         233 :     if ( pStartFrm->IsTxtFrm() )
    2721             :     {
    2722         233 :         if ( ((SwTxtFrm*)pStartFrm)->GetDropRect( aDropRect ) )
    2723           0 :             Sub( aRegion, aDropRect );
    2724             :     }
    2725         233 :     if ( pEndFrm != pStartFrm && pEndFrm->IsTxtFrm() )
    2726             :     {
    2727           9 :         if ( ((SwTxtFrm*)pEndFrm)->GetDropRect( aDropRect ) )
    2728           0 :             Sub( aRegion, aDropRect );
    2729             :     }
    2730             : 
    2731         466 :     rCrsr.assign( aRegion.begin(), aRegion.end() );
    2732          99 : }
    2733             : 
    2734             : 
    2735             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10