LCOV - code coverage report
Current view: top level - sw/source/core/layout - trvlfrm.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 597 1270 47.0 %
Date: 2012-08-25 Functions: 29 48 60.4 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 710 2599 27.3 %

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

Generated by: LCOV version 1.10