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