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

Generated by: LCOV version 1.10