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