1efeef26fSAndrew Rist /**************************************************************
2efeef26fSAndrew Rist *
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 #include "pam.hxx"
27cdf0e10cSrcweir #include "swtable.hxx"
28cdf0e10cSrcweir #include "frame.hxx"
29cdf0e10cSrcweir #include "rootfrm.hxx"
30cdf0e10cSrcweir #include "pagefrm.hxx"
31cdf0e10cSrcweir #include "flyfrm.hxx"
32cdf0e10cSrcweir #include "viewsh.hxx"
33cdf0e10cSrcweir #include "doc.hxx"
34cdf0e10cSrcweir #include "viewimp.hxx"
35cdf0e10cSrcweir #include "viewopt.hxx"
36cdf0e10cSrcweir #include "dflyobj.hxx"
37cdf0e10cSrcweir #include "frmtool.hxx"
38cdf0e10cSrcweir #include "dcontact.hxx"
39cdf0e10cSrcweir #include <editeng/brkitem.hxx>
40cdf0e10cSrcweir #include <editeng/keepitem.hxx>
41cdf0e10cSrcweir #include <fmtsrnd.hxx>
42cdf0e10cSrcweir #include <fmtanchr.hxx>
43cdf0e10cSrcweir #include <fmtpdsc.hxx>
44cdf0e10cSrcweir #include <editeng/ulspitem.hxx>
45cdf0e10cSrcweir #include <tgrditem.hxx>
46cdf0e10cSrcweir #include <txtftn.hxx>
47cdf0e10cSrcweir #include <fmtftn.hxx>
48cdf0e10cSrcweir #include <editeng/pgrditem.hxx>
49cdf0e10cSrcweir #include <paratr.hxx>
50cdf0e10cSrcweir #include "ftnfrm.hxx"
51cdf0e10cSrcweir #include "txtfrm.hxx"
52cdf0e10cSrcweir #include "tabfrm.hxx"
53cdf0e10cSrcweir #include "pagedesc.hxx"
54cdf0e10cSrcweir #include "layact.hxx"
55cdf0e10cSrcweir #include "fmtornt.hxx"
56cdf0e10cSrcweir #include "flyfrms.hxx"
57cdf0e10cSrcweir #include "sectfrm.hxx"
58cdf0e10cSrcweir #include "section.hxx"
59cdf0e10cSrcweir #include "dbg_lay.hxx"
60cdf0e10cSrcweir #include "lineinfo.hxx"
61cdf0e10cSrcweir #include <fmtclbl.hxx>
62cdf0e10cSrcweir #include <sortedobjs.hxx>
63cdf0e10cSrcweir #include <layouter.hxx>
64cdf0e10cSrcweir #include <fmtfollowtextflow.hxx>
65cdf0e10cSrcweir #include <switerator.hxx>
66cdf0e10cSrcweir
67cdf0e10cSrcweir sal_Bool SwFlowFrm::bMoveBwdJump = sal_False;
68cdf0e10cSrcweir
69cdf0e10cSrcweir
70cdf0e10cSrcweir /*************************************************************************
71cdf0e10cSrcweir |*
72cdf0e10cSrcweir |* SwFlowFrm::SwFlowFrm()
73cdf0e10cSrcweir |*
74cdf0e10cSrcweir |* Ersterstellung MA 26. Apr. 95
75cdf0e10cSrcweir |* Letzte Aenderung MA 26. Apr. 95
76cdf0e10cSrcweir |*
77cdf0e10cSrcweir |*************************************************************************/
78cdf0e10cSrcweir
79cdf0e10cSrcweir
SwFlowFrm(SwFrm & rFrm)80cdf0e10cSrcweir SwFlowFrm::SwFlowFrm( SwFrm &rFrm ) :
81cdf0e10cSrcweir rThis( rFrm ),
82cdf0e10cSrcweir pFollow( 0 )
83cdf0e10cSrcweir {
84cdf0e10cSrcweir bLockJoin = bIsFollow = bCntntLock = bOwnFtnNum =
85cdf0e10cSrcweir bFtnLock = bFlyLock = sal_False;
86cdf0e10cSrcweir }
87cdf0e10cSrcweir
88cdf0e10cSrcweir
89cdf0e10cSrcweir /*************************************************************************
90cdf0e10cSrcweir |*
91cdf0e10cSrcweir |* SwFlowFrm::IsFollowLocked()
92cdf0e10cSrcweir |* return sal_True if any follow has the JoinLocked flag
93cdf0e10cSrcweir |*
94cdf0e10cSrcweir |*************************************************************************/
95cdf0e10cSrcweir
HasLockedFollow() const96cdf0e10cSrcweir sal_Bool SwFlowFrm::HasLockedFollow() const
97cdf0e10cSrcweir {
98cdf0e10cSrcweir const SwFlowFrm* pFrm = GetFollow();
99cdf0e10cSrcweir while( pFrm )
100cdf0e10cSrcweir {
101cdf0e10cSrcweir if( pFrm->IsJoinLocked() )
102cdf0e10cSrcweir return sal_True;
103cdf0e10cSrcweir pFrm = pFrm->GetFollow();
104cdf0e10cSrcweir }
105cdf0e10cSrcweir return sal_False;
106cdf0e10cSrcweir }
107cdf0e10cSrcweir
108cdf0e10cSrcweir /*************************************************************************
109cdf0e10cSrcweir |*
110cdf0e10cSrcweir |* SwFlowFrm::IsKeepFwdMoveAllowed()
111cdf0e10cSrcweir |*
112cdf0e10cSrcweir |* Ersterstellung MA 20. Jul. 94
113cdf0e10cSrcweir |* Letzte Aenderung MA 16. May. 95
114cdf0e10cSrcweir |*
115cdf0e10cSrcweir |*************************************************************************/
116cdf0e10cSrcweir
117cdf0e10cSrcweir
IsKeepFwdMoveAllowed()118cdf0e10cSrcweir sal_Bool SwFlowFrm::IsKeepFwdMoveAllowed()
119cdf0e10cSrcweir {
120cdf0e10cSrcweir //Wenn der Vorgaenger das KeepAttribut traegt und auch dessen
121cdf0e10cSrcweir //Vorgaenger usw. bis zum ersten der Kette und fuer diesen das
122cdf0e10cSrcweir //IsFwdMoveAllowed ein sal_False liefert, so ist das Moven eben nicht erlaubt.
123cdf0e10cSrcweir SwFrm *pFrm = &rThis;
124cdf0e10cSrcweir if ( !pFrm->IsInFtn() )
125cdf0e10cSrcweir do
126cdf0e10cSrcweir { if ( pFrm->GetAttrSet()->GetKeep().GetValue() )
127cdf0e10cSrcweir pFrm = pFrm->GetIndPrev();
128cdf0e10cSrcweir else
129cdf0e10cSrcweir return sal_True;
130cdf0e10cSrcweir } while ( pFrm );
131cdf0e10cSrcweir
132cdf0e10cSrcweir //Siehe IsFwdMoveAllowed()
133cdf0e10cSrcweir sal_Bool bRet = sal_False;
134cdf0e10cSrcweir if ( pFrm && pFrm->GetIndPrev() )
135cdf0e10cSrcweir bRet = sal_True;
136cdf0e10cSrcweir return bRet;
137cdf0e10cSrcweir }
138cdf0e10cSrcweir
139cdf0e10cSrcweir /*************************************************************************
140cdf0e10cSrcweir |*
141cdf0e10cSrcweir |* SwFlowFrm::CheckKeep()
142cdf0e10cSrcweir |*
143cdf0e10cSrcweir |* Beschreibung
144cdf0e10cSrcweir |* Ersterstellung MA 20. Jun. 95
145cdf0e10cSrcweir |* Letzte Aenderung MA 09. Apr. 97
146cdf0e10cSrcweir |*
147cdf0e10cSrcweir |*************************************************************************/
148cdf0e10cSrcweir
149cdf0e10cSrcweir
CheckKeep()150cdf0e10cSrcweir void SwFlowFrm::CheckKeep()
151cdf0e10cSrcweir {
152cdf0e10cSrcweir //Den 'letzten' Vorgaenger mit KeepAttribut anstossen, denn
153cdf0e10cSrcweir //die ganze Truppe koennte zuruckrutschen.
154cdf0e10cSrcweir SwFrm *pPre = rThis.GetIndPrev();
155cdf0e10cSrcweir if( pPre->IsSctFrm() )
156cdf0e10cSrcweir {
157cdf0e10cSrcweir SwFrm *pLast = ((SwSectionFrm*)pPre)->FindLastCntnt();
158cdf0e10cSrcweir if( pLast && pLast->FindSctFrm() == pPre )
159cdf0e10cSrcweir pPre = pLast;
160cdf0e10cSrcweir else
161cdf0e10cSrcweir return;
162cdf0e10cSrcweir }
163cdf0e10cSrcweir SwFrm* pTmp;
164cdf0e10cSrcweir sal_Bool bKeep;
165cdf0e10cSrcweir while ( sal_True == (bKeep = pPre->GetAttrSet()->GetKeep().GetValue()) &&
166cdf0e10cSrcweir 0 != ( pTmp = pPre->GetIndPrev() ) )
167cdf0e10cSrcweir {
168cdf0e10cSrcweir if( pTmp->IsSctFrm() )
169cdf0e10cSrcweir {
170cdf0e10cSrcweir SwFrm *pLast = ((SwSectionFrm*)pTmp)->FindLastCntnt();
171cdf0e10cSrcweir if( pLast && pLast->FindSctFrm() == pTmp )
172cdf0e10cSrcweir pTmp = pLast;
173cdf0e10cSrcweir else
174cdf0e10cSrcweir break;
175cdf0e10cSrcweir }
176cdf0e10cSrcweir pPre = pTmp;
177cdf0e10cSrcweir }
178cdf0e10cSrcweir if ( bKeep )
179cdf0e10cSrcweir pPre->InvalidatePos();
180cdf0e10cSrcweir }
181cdf0e10cSrcweir
182cdf0e10cSrcweir /*************************************************************************
183cdf0e10cSrcweir |*
184cdf0e10cSrcweir |* SwFlowFrm::IsKeep()
185cdf0e10cSrcweir |*
186cdf0e10cSrcweir |* Ersterstellung MA 09. Apr. 97
187cdf0e10cSrcweir |* Letzte Aenderung MA 09. Apr. 97
188cdf0e10cSrcweir |*
189cdf0e10cSrcweir |*************************************************************************/
190cdf0e10cSrcweir
IsKeep(const SwAttrSet & rAttrs,bool bCheckIfLastRowShouldKeep) const191cdf0e10cSrcweir sal_Bool SwFlowFrm::IsKeep( const SwAttrSet& rAttrs, bool bCheckIfLastRowShouldKeep ) const
192cdf0e10cSrcweir {
193cdf0e10cSrcweir // 1. The keep attribute is ignored inside footnotes
194cdf0e10cSrcweir // 2. For compatibility reasons, the keep attribute is
195cdf0e10cSrcweir // ignored for frames inside table cells
196cdf0e10cSrcweir // 3. If bBreakCheck is set to true, this function only checks
197cdf0e10cSrcweir // if there are any break after attributes set at rAttrs
198cdf0e10cSrcweir // or break before attributes set for the next content (or next table)
199cdf0e10cSrcweir sal_Bool bKeep = bCheckIfLastRowShouldKeep ||
200cdf0e10cSrcweir ( !rThis.IsInFtn() &&
201cdf0e10cSrcweir ( !rThis.IsInTab() || rThis.IsTabFrm() ) &&
202cdf0e10cSrcweir rAttrs.GetKeep().GetValue() );
203cdf0e10cSrcweir
204cdf0e10cSrcweir ASSERT( !bCheckIfLastRowShouldKeep || rThis.IsTabFrm(),
205cdf0e10cSrcweir "IsKeep with bCheckIfLastRowShouldKeep should only be used for tabfrms" )
206cdf0e10cSrcweir
207cdf0e10cSrcweir // Ignore keep attribute if there are break situations:
208cdf0e10cSrcweir if ( bKeep )
209cdf0e10cSrcweir {
210cdf0e10cSrcweir switch ( rAttrs.GetBreak().GetBreak() )
211cdf0e10cSrcweir {
212cdf0e10cSrcweir case SVX_BREAK_COLUMN_AFTER:
213cdf0e10cSrcweir case SVX_BREAK_COLUMN_BOTH:
214cdf0e10cSrcweir case SVX_BREAK_PAGE_AFTER:
215cdf0e10cSrcweir case SVX_BREAK_PAGE_BOTH:
216cdf0e10cSrcweir {
217cdf0e10cSrcweir bKeep = sal_False;
218cdf0e10cSrcweir }
219cdf0e10cSrcweir default: break;
220cdf0e10cSrcweir }
221cdf0e10cSrcweir if ( bKeep )
222cdf0e10cSrcweir {
223cdf0e10cSrcweir SwFrm *pNxt;
224cdf0e10cSrcweir if( 0 != (pNxt = rThis.FindNextCnt()) &&
225cdf0e10cSrcweir (!pFollow || pNxt != pFollow->GetFrm()))
226cdf0e10cSrcweir {
227cdf0e10cSrcweir // --> FME 2006-05-15 #135914#
228cdf0e10cSrcweir // The last row of a table only keeps with the next content
229cdf0e10cSrcweir // it they are in the same section:
230cdf0e10cSrcweir if ( bCheckIfLastRowShouldKeep )
231cdf0e10cSrcweir {
232cdf0e10cSrcweir const SwSection* pThisSection = 0;
233cdf0e10cSrcweir const SwSection* pNextSection = 0;
234cdf0e10cSrcweir const SwSectionFrm* pThisSectionFrm = rThis.FindSctFrm();
235cdf0e10cSrcweir const SwSectionFrm* pNextSectionFrm = pNxt->FindSctFrm();
236cdf0e10cSrcweir
237cdf0e10cSrcweir if ( pThisSectionFrm )
238cdf0e10cSrcweir pThisSection = pThisSectionFrm->GetSection();
239cdf0e10cSrcweir
240cdf0e10cSrcweir if ( pNextSectionFrm )
241cdf0e10cSrcweir pNextSection = pNextSectionFrm->GetSection();
242cdf0e10cSrcweir
243cdf0e10cSrcweir if ( pThisSection != pNextSection )
244cdf0e10cSrcweir bKeep = sal_False;
245cdf0e10cSrcweir }
246cdf0e10cSrcweir // <--
247cdf0e10cSrcweir
248cdf0e10cSrcweir if ( bKeep )
249cdf0e10cSrcweir {
250cdf0e10cSrcweir const SwAttrSet* pSet = NULL;
251cdf0e10cSrcweir
252cdf0e10cSrcweir if ( pNxt->IsInTab() )
253cdf0e10cSrcweir {
254cdf0e10cSrcweir SwTabFrm* pTab = pNxt->FindTabFrm();
255cdf0e10cSrcweir if ( ! rThis.IsInTab() || rThis.FindTabFrm() != pTab )
256cdf0e10cSrcweir pSet = &pTab->GetFmt()->GetAttrSet();
257cdf0e10cSrcweir }
258cdf0e10cSrcweir
259cdf0e10cSrcweir if ( ! pSet )
260cdf0e10cSrcweir pSet = pNxt->GetAttrSet();
261cdf0e10cSrcweir
262cdf0e10cSrcweir ASSERT( pSet, "No AttrSet to check keep attribute" )
263cdf0e10cSrcweir
264cdf0e10cSrcweir if ( pSet->GetPageDesc().GetPageDesc() )
265cdf0e10cSrcweir bKeep = sal_False;
266cdf0e10cSrcweir else switch ( pSet->GetBreak().GetBreak() )
267cdf0e10cSrcweir {
268cdf0e10cSrcweir case SVX_BREAK_COLUMN_BEFORE:
269cdf0e10cSrcweir case SVX_BREAK_COLUMN_BOTH:
270cdf0e10cSrcweir case SVX_BREAK_PAGE_BEFORE:
271cdf0e10cSrcweir case SVX_BREAK_PAGE_BOTH:
272cdf0e10cSrcweir bKeep = sal_False;
273cdf0e10cSrcweir default: break;
274cdf0e10cSrcweir }
275cdf0e10cSrcweir }
276cdf0e10cSrcweir }
277cdf0e10cSrcweir }
278cdf0e10cSrcweir }
279cdf0e10cSrcweir return bKeep;
280cdf0e10cSrcweir }
281cdf0e10cSrcweir
282cdf0e10cSrcweir /*************************************************************************
283cdf0e10cSrcweir |*
284cdf0e10cSrcweir |* SwFlowFrm::BwdMoveNecessary()
285cdf0e10cSrcweir |*
286cdf0e10cSrcweir |* Ersterstellung MA 20. Jul. 94
287cdf0e10cSrcweir |* Letzte Aenderung MA 02. May. 96
288cdf0e10cSrcweir |*
289cdf0e10cSrcweir |*************************************************************************/
290cdf0e10cSrcweir
291cdf0e10cSrcweir
BwdMoveNecessary(const SwPageFrm * pPage,const SwRect & rRect)292cdf0e10cSrcweir sal_uInt8 SwFlowFrm::BwdMoveNecessary( const SwPageFrm *pPage, const SwRect &rRect )
293cdf0e10cSrcweir {
294cdf0e10cSrcweir // Der return-Wert entscheidet mit,
295cdf0e10cSrcweir // ob auf Zurueckgeflossen werden muss, (3)
296cdf0e10cSrcweir // ob das gute alte WouldFit gerufen werden kann (0, 1)
297cdf0e10cSrcweir // oder ob ein Umhaengen und eine Probeformatierung sinnvoll ist (2)
298cdf0e10cSrcweir // dabei bedeutet Bit 1, dass Objekte an mir selbst verankert sind
299cdf0e10cSrcweir // und Bit 2, dass ich anderen Objekten ausweichen muss.
300cdf0e10cSrcweir
301cdf0e10cSrcweir //Wenn ein SurroundObj, dass einen Umfluss wuenscht mit dem Rect ueberlappt
302cdf0e10cSrcweir //ist der Fluss notwendig (weil die Verhaeltnisse nicht geschaetzt werden
303cdf0e10cSrcweir //koennen), es kann allerdings ggf. eine TestFormatierung stattfinden.
304cdf0e10cSrcweir //Wenn das SurroundObj ein Fly ist und ich selbst ein Lower bin oder der Fly
305cdf0e10cSrcweir //Lower von mir ist, so spielt er keine Rolle.
306cdf0e10cSrcweir //Wenn das SurroundObj in einem zeichengebunden Fly verankert ist, und ich
307cdf0e10cSrcweir //selbst nicht Lower dieses Zeichengebundenen Flys bin, so spielt der Fly
308cdf0e10cSrcweir //keine Rolle.
309cdf0e10cSrcweir //#32639# Wenn das Objekt bei mir verankert ist kann ich es
310cdf0e10cSrcweir //vernachlaessigen, weil es hoechstwahrscheinlich (!?) mitfliesst,
311cdf0e10cSrcweir //eine TestFormatierung ist dann allerdings nicht erlaubt!
312cdf0e10cSrcweir sal_uInt8 nRet = 0;
313cdf0e10cSrcweir SwFlowFrm *pTmp = this;
314cdf0e10cSrcweir do
315cdf0e10cSrcweir { // Wenn an uns oder einem Follow Objekte haengen, so
316cdf0e10cSrcweir // kann keine ProbeFormatierung stattfinden, da absatzgebundene
317cdf0e10cSrcweir // nicht richtig beruecksichtigt wuerden und zeichengebundene sollten
318cdf0e10cSrcweir // gar nicht zur Probe formatiert werden.
319cdf0e10cSrcweir if( pTmp->GetFrm()->GetDrawObjs() )
320cdf0e10cSrcweir nRet = 1;
321cdf0e10cSrcweir pTmp = pTmp->GetFollow();
322cdf0e10cSrcweir } while ( !nRet && pTmp );
323cdf0e10cSrcweir if ( pPage->GetSortedObjs() )
324cdf0e10cSrcweir {
325cdf0e10cSrcweir // --> OD 2004-07-01 #i28701# - new type <SwSortedObjs>
326cdf0e10cSrcweir const SwSortedObjs &rObjs = *pPage->GetSortedObjs();
327cdf0e10cSrcweir sal_uLong nIndex = ULONG_MAX;
328cdf0e10cSrcweir for ( sal_uInt16 i = 0; nRet < 3 && i < rObjs.Count(); ++i )
329cdf0e10cSrcweir {
330cdf0e10cSrcweir // --> OD 2004-07-01 #i28701# - consider changed type of
331cdf0e10cSrcweir // <SwSortedObjs> entries.
332cdf0e10cSrcweir SwAnchoredObject* pObj = rObjs[i];
333cdf0e10cSrcweir const SwFrmFmt& rFmt = pObj->GetFrmFmt();
334cdf0e10cSrcweir const SwRect aRect( pObj->GetObjRect() );
335cdf0e10cSrcweir if ( aRect.IsOver( rRect ) &&
336cdf0e10cSrcweir rFmt.GetSurround().GetSurround() != SURROUND_THROUGHT )
337cdf0e10cSrcweir {
338cdf0e10cSrcweir if( rThis.IsLayoutFrm() && //Fly Lower von This?
339cdf0e10cSrcweir Is_Lower_Of( &rThis, pObj->GetDrawObj() ) )
340cdf0e10cSrcweir continue;
341cdf0e10cSrcweir if( pObj->ISA(SwFlyFrm) )
342cdf0e10cSrcweir {
343cdf0e10cSrcweir const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pObj);
344cdf0e10cSrcweir if ( pFly->IsAnLower( &rThis ) )//This Lower vom Fly?
345cdf0e10cSrcweir continue;
346cdf0e10cSrcweir }
347cdf0e10cSrcweir
348cdf0e10cSrcweir const SwFrm* pAnchor = pObj->GetAnchorFrm();
349cdf0e10cSrcweir if ( pAnchor == &rThis )
350cdf0e10cSrcweir {
351cdf0e10cSrcweir nRet |= 1;
352cdf0e10cSrcweir continue;
353cdf0e10cSrcweir }
354cdf0e10cSrcweir
355cdf0e10cSrcweir //Nicht wenn das Objekt im Textfluss hinter mir verankert ist,
356cdf0e10cSrcweir //denn dann weiche ich ihm nicht aus.
357cdf0e10cSrcweir if ( ::IsFrmInSameKontext( pAnchor, &rThis ) )
358cdf0e10cSrcweir {
359cdf0e10cSrcweir if ( rFmt.GetAnchor().GetAnchorId() == FLY_AT_PARA )
360cdf0e10cSrcweir {
361cdf0e10cSrcweir // Den Index des anderen erhalten wir immer ueber das Ankerattr.
362cdf0e10cSrcweir sal_uLong nTmpIndex = rFmt.GetAnchor().GetCntntAnchor()->nNode.GetIndex();
363cdf0e10cSrcweir // Jetzt wird noch ueberprueft, ob der aktuelle Absatz vor dem
364cdf0e10cSrcweir // Anker des verdraengenden Objekts im Text steht, dann wird
365cdf0e10cSrcweir // nicht ausgewichen.
366cdf0e10cSrcweir // Der Index wird moeglichst ueber einen SwFmtAnchor ermittelt,
367cdf0e10cSrcweir // da sonst recht teuer.
368cdf0e10cSrcweir if( ULONG_MAX == nIndex )
369cdf0e10cSrcweir {
370cdf0e10cSrcweir const SwNode *pNode;
371cdf0e10cSrcweir if ( rThis.IsCntntFrm() )
372cdf0e10cSrcweir pNode = ((SwCntntFrm&)rThis).GetNode();
373cdf0e10cSrcweir else if( rThis.IsSctFrm() )
374cdf0e10cSrcweir pNode = ((SwSectionFmt*)((SwSectionFrm&)rThis).
375cdf0e10cSrcweir GetFmt())->GetSectionNode();
376cdf0e10cSrcweir else
377cdf0e10cSrcweir {
378cdf0e10cSrcweir ASSERT( rThis.IsTabFrm(), "new FowFrm?" );
379cdf0e10cSrcweir pNode = ((SwTabFrm&)rThis).GetTable()->
380cdf0e10cSrcweir GetTabSortBoxes()[0]->GetSttNd()->FindTableNode();
381cdf0e10cSrcweir }
382cdf0e10cSrcweir nIndex = pNode->GetIndex();
383cdf0e10cSrcweir }
384cdf0e10cSrcweir if( nIndex < nTmpIndex )
385cdf0e10cSrcweir continue;
386cdf0e10cSrcweir }
387cdf0e10cSrcweir }
388cdf0e10cSrcweir else
389cdf0e10cSrcweir continue;
390cdf0e10cSrcweir
391cdf0e10cSrcweir nRet |= 2;
392cdf0e10cSrcweir }
393cdf0e10cSrcweir }
394cdf0e10cSrcweir }
395cdf0e10cSrcweir return nRet;
396cdf0e10cSrcweir }
397cdf0e10cSrcweir
398cdf0e10cSrcweir /*************************************************************************
399cdf0e10cSrcweir |*
400cdf0e10cSrcweir |* SwFlowFrm::CutTree(), PasteTree(), MoveSubTree()
401cdf0e10cSrcweir |*
402cdf0e10cSrcweir |* Beschreibung Eine Spezialisierte Form des Cut() und Paste(), die
403cdf0e10cSrcweir |* eine ganze Kette umhaengt (naehmlich this und folgende). Dabei werden
404cdf0e10cSrcweir |* nur minimale Operationen und Benachrichtigungen ausgefuehrt.
405cdf0e10cSrcweir |* Ersterstellung MA 18. Mar. 93
406cdf0e10cSrcweir |* Letzte Aenderung MA 18. May. 95
407cdf0e10cSrcweir |*
408cdf0e10cSrcweir |*************************************************************************/
409cdf0e10cSrcweir
410cdf0e10cSrcweir
CutTree(SwFrm * pStart)411cdf0e10cSrcweir SwLayoutFrm *SwFlowFrm::CutTree( SwFrm *pStart )
412cdf0e10cSrcweir {
413cdf0e10cSrcweir //Der Start und alle Nachbarn werden ausgeschnitten, sie werden aneinander-
414cdf0e10cSrcweir //gereiht und ein Henkel auf den ersten wird zurueckgeliefert.
415cdf0e10cSrcweir //Zurueckbleibende werden geeignet invalidiert.
416cdf0e10cSrcweir
417cdf0e10cSrcweir SwLayoutFrm *pLay = pStart->GetUpper();
418cdf0e10cSrcweir if ( pLay->IsInFtn() )
419cdf0e10cSrcweir pLay = pLay->FindFtnFrm();
420cdf0e10cSrcweir
421cdf0e10cSrcweir // --> OD 2006-05-08 #i58846#
422cdf0e10cSrcweir // <pPrepare( PREP_QUOVADIS )> only for frames in footnotes
423cdf0e10cSrcweir if( pStart->IsInFtn() )
424cdf0e10cSrcweir {
425cdf0e10cSrcweir SwFrm* pTmp = pStart->GetIndPrev();
426cdf0e10cSrcweir if( pTmp )
427cdf0e10cSrcweir pTmp->Prepare( PREP_QUOVADIS );
428cdf0e10cSrcweir }
429cdf0e10cSrcweir // <--
430cdf0e10cSrcweir
431cdf0e10cSrcweir //Nur fix auschneiden und zwar so, dass klare Verhaeltnisse bei den
432cdf0e10cSrcweir //Verlassenen herrschen. Die Pointer der ausgeschnittenen Kette zeigen
433cdf0e10cSrcweir //noch wer weiss wo hin.
434cdf0e10cSrcweir if ( pStart == pStart->GetUpper()->Lower() )
435cdf0e10cSrcweir pStart->GetUpper()->pLower = 0;
436cdf0e10cSrcweir if ( pStart->GetPrev() )
437cdf0e10cSrcweir {
438cdf0e10cSrcweir pStart->GetPrev()->pNext = 0;
439cdf0e10cSrcweir pStart->pPrev = 0;
440cdf0e10cSrcweir }
441cdf0e10cSrcweir
442cdf0e10cSrcweir if ( pLay->IsFtnFrm() )
443cdf0e10cSrcweir {
444cdf0e10cSrcweir if ( !pLay->Lower() && !pLay->IsColLocked() &&
445cdf0e10cSrcweir !((SwFtnFrm*)pLay)->IsBackMoveLocked() )
446cdf0e10cSrcweir {
447cdf0e10cSrcweir pLay->Cut();
448cdf0e10cSrcweir delete pLay;
449cdf0e10cSrcweir }
450cdf0e10cSrcweir else
451cdf0e10cSrcweir {
452cdf0e10cSrcweir sal_Bool bUnlock = !((SwFtnFrm*)pLay)->IsBackMoveLocked();
453cdf0e10cSrcweir ((SwFtnFrm*)pLay)->LockBackMove();
454cdf0e10cSrcweir pLay->InvalidateSize();
455cdf0e10cSrcweir pLay->Calc();
456cdf0e10cSrcweir SwCntntFrm *pCnt = pLay->ContainsCntnt();
457cdf0e10cSrcweir while ( pCnt && pLay->IsAnLower( pCnt ) )
458cdf0e10cSrcweir {
459cdf0e10cSrcweir //Kann sein, dass der CntFrm gelockt ist, wir wollen hier nicht
460cdf0e10cSrcweir //in eine endlose Seitenwanderung hineinlaufen und rufen das
461cdf0e10cSrcweir //Calc garnicht erst!
462cdf0e10cSrcweir ASSERT( pCnt->IsTxtFrm(), "Die Graphic ist gelandet." );
463cdf0e10cSrcweir if ( ((SwTxtFrm*)pCnt)->IsLocked() ||
464cdf0e10cSrcweir ((SwTxtFrm*)pCnt)->GetFollow() == pStart )
465cdf0e10cSrcweir break;
466cdf0e10cSrcweir pCnt->Calc();
467cdf0e10cSrcweir pCnt = pCnt->GetNextCntntFrm();
468cdf0e10cSrcweir }
469cdf0e10cSrcweir if( bUnlock )
470cdf0e10cSrcweir ((SwFtnFrm*)pLay)->UnlockBackMove();
471cdf0e10cSrcweir }
472cdf0e10cSrcweir pLay = 0;
473cdf0e10cSrcweir }
474cdf0e10cSrcweir return pLay;
475cdf0e10cSrcweir }
476cdf0e10cSrcweir
477cdf0e10cSrcweir
478cdf0e10cSrcweir
PasteTree(SwFrm * pStart,SwLayoutFrm * pParent,SwFrm * pSibling,SwFrm * pOldParent)479cdf0e10cSrcweir sal_Bool SwFlowFrm::PasteTree( SwFrm *pStart, SwLayoutFrm *pParent, SwFrm *pSibling,
480cdf0e10cSrcweir SwFrm *pOldParent )
481cdf0e10cSrcweir {
482cdf0e10cSrcweir //returnt sal_True wenn in der Kette ein LayoutFrm steht.
483cdf0e10cSrcweir sal_Bool bRet = sal_False;
484cdf0e10cSrcweir
485cdf0e10cSrcweir //Die mit pStart beginnende Kette wird vor den Sibling unter den Parent
486cdf0e10cSrcweir //gehaengt. Fuer geeignete Invalidierung wird ebenfalls gesorgt.
487cdf0e10cSrcweir
488cdf0e10cSrcweir //Ich bekomme eine fertige Kette. Der Anfang der Kette muss verpointert
489cdf0e10cSrcweir //werden, dann alle Upper fuer die Kette und schliesslich dass Ende.
490cdf0e10cSrcweir //Unterwegs werden alle geeignet invalidiert.
491cdf0e10cSrcweir if ( pSibling )
492cdf0e10cSrcweir {
493cdf0e10cSrcweir if ( 0 != (pStart->pPrev = pSibling->GetPrev()) )
494cdf0e10cSrcweir pStart->GetPrev()->pNext = pStart;
495cdf0e10cSrcweir else
496cdf0e10cSrcweir pParent->pLower = pStart;
497cdf0e10cSrcweir pSibling->_InvalidatePos();
498cdf0e10cSrcweir pSibling->_InvalidatePrt();
499cdf0e10cSrcweir }
500cdf0e10cSrcweir else
501cdf0e10cSrcweir {
502cdf0e10cSrcweir if ( 0 == (pStart->pPrev = pParent->Lower()) )
503cdf0e10cSrcweir pParent->pLower = pStart;
504cdf0e10cSrcweir else
505cdf0e10cSrcweir //Modified for #i100782#,04/03/2009
506cdf0e10cSrcweir //If the pParent has more than 1 child nodes, former design will
507cdf0e10cSrcweir //ignore them directly without any collection work. It will make some
508cdf0e10cSrcweir //dangling pointers. This lead the crash...
509cdf0e10cSrcweir //The new design will find the last child of pParent in loop way, and
510cdf0e10cSrcweir //add the pStart after the last child.
511cdf0e10cSrcweir // pParent->Lower()->pNext = pStart;
512cdf0e10cSrcweir {
513cdf0e10cSrcweir SwFrm* pTemp = pParent->pLower;
514cdf0e10cSrcweir while (pTemp)
515cdf0e10cSrcweir {
516cdf0e10cSrcweir if (pTemp->pNext)
517cdf0e10cSrcweir pTemp = pTemp->pNext;
518cdf0e10cSrcweir else
519cdf0e10cSrcweir {
520cdf0e10cSrcweir pStart->pPrev = pTemp;
521cdf0e10cSrcweir pTemp->pNext = pStart;
522cdf0e10cSrcweir break;
523cdf0e10cSrcweir }
524cdf0e10cSrcweir }
525cdf0e10cSrcweir }
526cdf0e10cSrcweir //End modification for #i100782#,04/03/2009
527cdf0e10cSrcweir
528cdf0e10cSrcweir // #i27145#
529cdf0e10cSrcweir if ( pParent->IsSctFrm() )
530cdf0e10cSrcweir {
531cdf0e10cSrcweir // We have no sibling because pParent is a section frame and
532cdf0e10cSrcweir // has just been created to contain some content. The printing
533cdf0e10cSrcweir // area of the frame behind pParent has to be invalidated, so
534cdf0e10cSrcweir // that the correct distance between pParent and the next frame
535cdf0e10cSrcweir // can be calculated.
536cdf0e10cSrcweir pParent->InvalidateNextPrtArea();
537cdf0e10cSrcweir }
538cdf0e10cSrcweir }
539cdf0e10cSrcweir SwFrm *pFloat = pStart;
540cdf0e10cSrcweir SwFrm *pLst = 0;
541cdf0e10cSrcweir SWRECTFN( pParent )
542cdf0e10cSrcweir SwTwips nGrowVal = 0;
543cdf0e10cSrcweir do
544cdf0e10cSrcweir { pFloat->pUpper = pParent;
545cdf0e10cSrcweir pFloat->_InvalidateAll();
546cdf0e10cSrcweir pFloat->CheckDirChange();
547cdf0e10cSrcweir
548cdf0e10cSrcweir //Ich bin Freund des TxtFrm und darf deshalb so einiges. Das mit
549cdf0e10cSrcweir //dem CacheIdx scheint etwas riskant!
550cdf0e10cSrcweir if ( pFloat->IsTxtFrm() )
551cdf0e10cSrcweir {
552cdf0e10cSrcweir if ( ((SwTxtFrm*)pFloat)->GetCacheIdx() != USHRT_MAX )
553cdf0e10cSrcweir ((SwTxtFrm*)pFloat)->Init(); //Ich bin sein Freund.
554cdf0e10cSrcweir }
555cdf0e10cSrcweir else
556cdf0e10cSrcweir bRet = sal_True;
557cdf0e10cSrcweir
558cdf0e10cSrcweir nGrowVal += (pFloat->Frm().*fnRect->fnGetHeight)();
559cdf0e10cSrcweir if ( pFloat->GetNext() )
560cdf0e10cSrcweir pFloat = pFloat->GetNext();
561cdf0e10cSrcweir else
562cdf0e10cSrcweir {
563cdf0e10cSrcweir pLst = pFloat;
564cdf0e10cSrcweir pFloat = 0;
565cdf0e10cSrcweir }
566cdf0e10cSrcweir } while ( pFloat );
567cdf0e10cSrcweir
568cdf0e10cSrcweir if ( pSibling )
569cdf0e10cSrcweir {
570cdf0e10cSrcweir pLst->pNext = pSibling;
571cdf0e10cSrcweir pSibling->pPrev = pLst;
572cdf0e10cSrcweir if( pSibling->IsInFtn() )
573cdf0e10cSrcweir {
574cdf0e10cSrcweir if( pSibling->IsSctFrm() )
575cdf0e10cSrcweir pSibling = ((SwSectionFrm*)pSibling)->ContainsAny();
576cdf0e10cSrcweir if( pSibling )
577cdf0e10cSrcweir pSibling->Prepare( PREP_ERGOSUM );
578cdf0e10cSrcweir }
579cdf0e10cSrcweir }
580cdf0e10cSrcweir if ( nGrowVal )
581cdf0e10cSrcweir {
582cdf0e10cSrcweir if ( pOldParent && pOldParent->IsBodyFrm() ) //Fuer variable Seitenhoehe beim Browsen
583cdf0e10cSrcweir pOldParent->Shrink( nGrowVal );
584cdf0e10cSrcweir pParent->Grow( nGrowVal );
585cdf0e10cSrcweir }
586cdf0e10cSrcweir
587cdf0e10cSrcweir if ( pParent->IsFtnFrm() )
588cdf0e10cSrcweir ((SwFtnFrm*)pParent)->InvalidateNxtFtnCnts( pParent->FindPageFrm() );
589cdf0e10cSrcweir return bRet;
590cdf0e10cSrcweir }
591cdf0e10cSrcweir
592cdf0e10cSrcweir
593cdf0e10cSrcweir
MoveSubTree(SwLayoutFrm * pParent,SwFrm * pSibling)594cdf0e10cSrcweir void SwFlowFrm::MoveSubTree( SwLayoutFrm* pParent, SwFrm* pSibling )
595cdf0e10cSrcweir {
596cdf0e10cSrcweir ASSERT( pParent, "Kein Parent uebergeben." );
597cdf0e10cSrcweir ASSERT( rThis.GetUpper(), "Wo kommen wir denn her?" );
598cdf0e10cSrcweir
599cdf0e10cSrcweir //Sparsamer benachrichtigen wenn eine Action laeuft.
600cdf0e10cSrcweir ViewShell *pSh = rThis.getRootFrm()->GetCurrShell();
601cdf0e10cSrcweir const SwViewImp *pImp = pSh ? pSh->Imp() : 0;
602cdf0e10cSrcweir const sal_Bool bComplete = pImp && pImp->IsAction() && pImp->GetLayAction().IsComplete();
603cdf0e10cSrcweir
604cdf0e10cSrcweir if ( !bComplete )
605cdf0e10cSrcweir {
606cdf0e10cSrcweir SwFrm *pPre = rThis.GetIndPrev();
607cdf0e10cSrcweir if ( pPre )
608cdf0e10cSrcweir {
609cdf0e10cSrcweir pPre->SetRetouche();
610cdf0e10cSrcweir // --> OD 2004-11-23 #115759# - follow-up of #i26250#
611cdf0e10cSrcweir // invalidate printing area of previous frame, if it's in a table
612cdf0e10cSrcweir if ( pPre->GetUpper()->IsInTab() )
613cdf0e10cSrcweir {
614cdf0e10cSrcweir pPre->_InvalidatePrt();
615cdf0e10cSrcweir }
616cdf0e10cSrcweir // <--
617cdf0e10cSrcweir pPre->InvalidatePage();
618cdf0e10cSrcweir }
619cdf0e10cSrcweir else
620cdf0e10cSrcweir { rThis.GetUpper()->SetCompletePaint();
621cdf0e10cSrcweir rThis.GetUpper()->InvalidatePage();
622cdf0e10cSrcweir }
623cdf0e10cSrcweir }
624cdf0e10cSrcweir
625cdf0e10cSrcweir SwPageFrm *pOldPage = rThis.FindPageFrm();
626cdf0e10cSrcweir
627cdf0e10cSrcweir SwLayoutFrm *pOldParent = CutTree( &rThis );
628cdf0e10cSrcweir const sal_Bool bInvaLay = PasteTree( &rThis, pParent, pSibling, pOldParent );
629cdf0e10cSrcweir
630cdf0e10cSrcweir // Wenn durch das Cut&Paste ein leerer SectionFrm entstanden ist, sollte
631cdf0e10cSrcweir // dieser automatisch verschwinden.
632cdf0e10cSrcweir SwSectionFrm *pSct;
633cdf0e10cSrcweir // --> OD 2006-01-04 #126020# - adjust check for empty section
634cdf0e10cSrcweir // --> OD 2006-02-01 #130797# - correct fix #126020#
635cdf0e10cSrcweir if ( pOldParent && !pOldParent->Lower() &&
636cdf0e10cSrcweir ( pOldParent->IsInSct() &&
637cdf0e10cSrcweir !(pSct = pOldParent->FindSctFrm())->ContainsCntnt() &&
638cdf0e10cSrcweir !pSct->ContainsAny( true ) ) )
639cdf0e10cSrcweir // <--
640cdf0e10cSrcweir {
641cdf0e10cSrcweir pSct->DelEmpty( sal_False );
642cdf0e10cSrcweir }
643cdf0e10cSrcweir
644cdf0e10cSrcweir // In einem spaltigen Bereich rufen wir lieber kein Calc "von unten"
645cdf0e10cSrcweir if( !rThis.IsInSct() &&
646cdf0e10cSrcweir ( !rThis.IsInTab() || ( rThis.IsTabFrm() && !rThis.GetUpper()->IsInTab() ) ) )
647cdf0e10cSrcweir rThis.GetUpper()->Calc();
648cdf0e10cSrcweir else if( rThis.GetUpper()->IsSctFrm() )
649cdf0e10cSrcweir {
650cdf0e10cSrcweir SwSectionFrm* pTmpSct = (SwSectionFrm*)rThis.GetUpper();
651cdf0e10cSrcweir sal_Bool bOld = pTmpSct->IsCntntLocked();
652cdf0e10cSrcweir pTmpSct->SetCntntLock( sal_True );
653cdf0e10cSrcweir pTmpSct->Calc();
654cdf0e10cSrcweir if( !bOld )
655cdf0e10cSrcweir pTmpSct->SetCntntLock( sal_False );
656cdf0e10cSrcweir }
657cdf0e10cSrcweir SwPageFrm *pPage = rThis.FindPageFrm();
658cdf0e10cSrcweir
659cdf0e10cSrcweir if ( pOldPage != pPage )
660cdf0e10cSrcweir {
661cdf0e10cSrcweir rThis.InvalidatePage( pPage );
662cdf0e10cSrcweir if ( rThis.IsLayoutFrm() )
663cdf0e10cSrcweir {
664cdf0e10cSrcweir SwCntntFrm *pCnt = ((SwLayoutFrm*)&rThis)->ContainsCntnt();
665cdf0e10cSrcweir if ( pCnt )
666cdf0e10cSrcweir pCnt->InvalidatePage( pPage );
667cdf0e10cSrcweir }
668cdf0e10cSrcweir else if ( pSh && pSh->GetDoc()->GetLineNumberInfo().IsRestartEachPage()
669cdf0e10cSrcweir && pPage->FindFirstBodyCntnt() == &rThis )
670cdf0e10cSrcweir {
671cdf0e10cSrcweir rThis._InvalidateLineNum();
672cdf0e10cSrcweir }
673cdf0e10cSrcweir }
674cdf0e10cSrcweir if ( bInvaLay || (pSibling && pSibling->IsLayoutFrm()) )
675cdf0e10cSrcweir rThis.GetUpper()->InvalidatePage( pPage );
676cdf0e10cSrcweir }
677cdf0e10cSrcweir
678cdf0e10cSrcweir /*************************************************************************
679cdf0e10cSrcweir |*
680cdf0e10cSrcweir |* SwFlowFrm::IsAnFollow()
681cdf0e10cSrcweir |*
682cdf0e10cSrcweir |* Ersterstellung MA 26. Apr. 95
683cdf0e10cSrcweir |* Letzte Aenderung MA 26. Apr. 95
684cdf0e10cSrcweir |*
685cdf0e10cSrcweir |*************************************************************************/
686cdf0e10cSrcweir
687cdf0e10cSrcweir
IsAnFollow(const SwFlowFrm * pAssumed) const688cdf0e10cSrcweir sal_Bool SwFlowFrm::IsAnFollow( const SwFlowFrm *pAssumed ) const
689cdf0e10cSrcweir {
690cdf0e10cSrcweir const SwFlowFrm *pFoll = this;
691cdf0e10cSrcweir do
692cdf0e10cSrcweir { if ( pAssumed == pFoll )
693cdf0e10cSrcweir return sal_True;
694cdf0e10cSrcweir pFoll = pFoll->GetFollow();
695cdf0e10cSrcweir } while ( pFoll );
696cdf0e10cSrcweir return sal_False;
697cdf0e10cSrcweir }
698cdf0e10cSrcweir
699cdf0e10cSrcweir
700cdf0e10cSrcweir /*************************************************************************
701cdf0e10cSrcweir |*
702cdf0e10cSrcweir |* SwFlowFrm::FindMaster()
703cdf0e10cSrcweir |*
704cdf0e10cSrcweir |* Ersterstellung MA 26. Apr. 95
705cdf0e10cSrcweir |* Letzte Aenderung MA 26. Apr. 95
706cdf0e10cSrcweir |*
707cdf0e10cSrcweir |*************************************************************************/
708cdf0e10cSrcweir
FindMaster() const709cdf0e10cSrcweir SwTxtFrm* SwCntntFrm::FindMaster() const
710cdf0e10cSrcweir {
711cdf0e10cSrcweir ASSERT( IsFollow(), "SwCntntFrm::FindMaster(): !IsFollow" );
712cdf0e10cSrcweir
713cdf0e10cSrcweir const SwCntntFrm* pCnt = GetPrevCntntFrm();
714cdf0e10cSrcweir
715cdf0e10cSrcweir while ( pCnt )
716cdf0e10cSrcweir {
717cdf0e10cSrcweir if ( pCnt->HasFollow() && pCnt->GetFollow() == this )
718cdf0e10cSrcweir {
719cdf0e10cSrcweir ASSERT( pCnt->IsTxtFrm(), "NoTxtFrm with follow found" )
720cdf0e10cSrcweir return (SwTxtFrm*)pCnt;
721cdf0e10cSrcweir }
722cdf0e10cSrcweir pCnt = pCnt->GetPrevCntntFrm();
723cdf0e10cSrcweir }
724cdf0e10cSrcweir
725cdf0e10cSrcweir ASSERT( sal_False, "Follow ist lost in Space." );
726cdf0e10cSrcweir return 0;
727cdf0e10cSrcweir }
728cdf0e10cSrcweir
FindMaster() const729cdf0e10cSrcweir SwSectionFrm* SwSectionFrm::FindMaster() const
730cdf0e10cSrcweir {
731cdf0e10cSrcweir ASSERT( IsFollow(), "SwSectionFrm::FindMaster(): !IsFollow" );
732cdf0e10cSrcweir
733cdf0e10cSrcweir SwIterator<SwSectionFrm,SwFmt> aIter( *pSection->GetFmt() );
734cdf0e10cSrcweir SwSectionFrm* pSect = aIter.First();
735cdf0e10cSrcweir while ( pSect )
736cdf0e10cSrcweir {
737cdf0e10cSrcweir if( pSect->GetFollow() == this )
738cdf0e10cSrcweir return pSect;
739cdf0e10cSrcweir pSect = aIter.Next();
740cdf0e10cSrcweir }
741cdf0e10cSrcweir
742cdf0e10cSrcweir ASSERT( sal_False, "Follow ist lost in Space." );
743cdf0e10cSrcweir return 0;
744cdf0e10cSrcweir }
745cdf0e10cSrcweir
FindMaster(bool bFirstMaster) const746cdf0e10cSrcweir SwTabFrm* SwTabFrm::FindMaster( bool bFirstMaster ) const
747cdf0e10cSrcweir {
748cdf0e10cSrcweir ASSERT( IsFollow(), "SwTabFrm::FindMaster(): !IsFollow" );
749cdf0e10cSrcweir
750cdf0e10cSrcweir SwIterator<SwTabFrm,SwFmt> aIter( *GetTable()->GetFrmFmt() );
751cdf0e10cSrcweir SwTabFrm* pTab = aIter.First();
752cdf0e10cSrcweir while ( pTab )
753cdf0e10cSrcweir {
754cdf0e10cSrcweir if ( bFirstMaster )
755cdf0e10cSrcweir {
756cdf0e10cSrcweir //
757cdf0e10cSrcweir // Optimization. This makes code like this obsolete:
758cdf0e10cSrcweir // while ( pTab->IsFollow() )
759cdf0e10cSrcweir // pTab = pTab->FindMaster();
760cdf0e10cSrcweir //
761cdf0e10cSrcweir if ( !pTab->IsFollow() )
762cdf0e10cSrcweir {
763cdf0e10cSrcweir SwTabFrm* pNxt = pTab;
764cdf0e10cSrcweir while ( pNxt )
765cdf0e10cSrcweir {
766cdf0e10cSrcweir if ( pNxt->GetFollow() == this )
767cdf0e10cSrcweir return pTab;
768cdf0e10cSrcweir pNxt = pNxt->GetFollow();
769cdf0e10cSrcweir }
770cdf0e10cSrcweir }
771cdf0e10cSrcweir }
772cdf0e10cSrcweir else
773cdf0e10cSrcweir {
774cdf0e10cSrcweir if ( pTab->GetFollow() == this )
775cdf0e10cSrcweir return pTab;
776cdf0e10cSrcweir }
777cdf0e10cSrcweir
778cdf0e10cSrcweir pTab = aIter.Next();
779cdf0e10cSrcweir }
780cdf0e10cSrcweir
781cdf0e10cSrcweir ASSERT( sal_False, "Follow ist lost in Space." );
782cdf0e10cSrcweir return 0;
783cdf0e10cSrcweir }
784cdf0e10cSrcweir
785cdf0e10cSrcweir /*************************************************************************
786cdf0e10cSrcweir |*
787cdf0e10cSrcweir |* SwFrm::GetLeaf()
788cdf0e10cSrcweir |*
789cdf0e10cSrcweir |* Beschreibung Liefert das naechste/vorhergehende LayoutBlatt,
790cdf0e10cSrcweir |* das _nicht_ unterhalb von this liegt (oder gar this selbst ist).
791cdf0e10cSrcweir |* Ausserdem muss dieses LayoutBlatt im gleichen Textfluss wie
792cdf0e10cSrcweir |* pAnch Ausgangsfrm liegen (Body, Ftn)
793cdf0e10cSrcweir |* Ersterstellung MA 25. Nov. 92
794cdf0e10cSrcweir |* Letzte Aenderung MA 25. Apr. 95
795cdf0e10cSrcweir |*
796cdf0e10cSrcweir |*************************************************************************/
797cdf0e10cSrcweir
798cdf0e10cSrcweir
GetLeaf(MakePageType eMakePage,sal_Bool bFwd,const SwFrm * pAnch) const799cdf0e10cSrcweir const SwLayoutFrm *SwFrm::GetLeaf( MakePageType eMakePage, sal_Bool bFwd,
800cdf0e10cSrcweir const SwFrm *pAnch ) const
801cdf0e10cSrcweir {
802cdf0e10cSrcweir //Ohne Fluss kein genuss...
803cdf0e10cSrcweir if ( !(IsInDocBody() || IsInFtn() || IsInFly()) )
804cdf0e10cSrcweir return 0;
805cdf0e10cSrcweir
806cdf0e10cSrcweir const SwFrm *pLeaf = this;
807cdf0e10cSrcweir sal_Bool bFound = sal_False;
808cdf0e10cSrcweir
809cdf0e10cSrcweir do
810cdf0e10cSrcweir { pLeaf = ((SwFrm*)pLeaf)->GetLeaf( eMakePage, bFwd );
811cdf0e10cSrcweir
812cdf0e10cSrcweir if ( pLeaf &&
813cdf0e10cSrcweir (!IsLayoutFrm() || !((SwLayoutFrm*)this)->IsAnLower( pLeaf )))
814cdf0e10cSrcweir {
815cdf0e10cSrcweir if ( pAnch->IsInDocBody() == pLeaf->IsInDocBody() &&
816cdf0e10cSrcweir pAnch->IsInFtn() == pLeaf->IsInFtn() )
817cdf0e10cSrcweir {
818cdf0e10cSrcweir bFound = sal_True;
819cdf0e10cSrcweir }
820cdf0e10cSrcweir }
821cdf0e10cSrcweir } while ( !bFound && pLeaf );
822cdf0e10cSrcweir
823cdf0e10cSrcweir return (const SwLayoutFrm*)pLeaf;
824cdf0e10cSrcweir }
825cdf0e10cSrcweir
826cdf0e10cSrcweir /*************************************************************************
827cdf0e10cSrcweir |*
828cdf0e10cSrcweir |* SwFrm::GetLeaf()
829cdf0e10cSrcweir |*
830cdf0e10cSrcweir |* Beschreibung Ruft Get[Next|Prev]Leaf
831cdf0e10cSrcweir |*
832cdf0e10cSrcweir |* Ersterstellung MA 20. Mar. 93
833cdf0e10cSrcweir |* Letzte Aenderung MA 25. Apr. 95
834cdf0e10cSrcweir |*
835cdf0e10cSrcweir |*************************************************************************/
836cdf0e10cSrcweir
837cdf0e10cSrcweir
GetLeaf(MakePageType eMakePage,sal_Bool bFwd)838cdf0e10cSrcweir SwLayoutFrm *SwFrm::GetLeaf( MakePageType eMakePage, sal_Bool bFwd )
839cdf0e10cSrcweir {
840cdf0e10cSrcweir if ( IsInFtn() )
841cdf0e10cSrcweir return bFwd ? GetNextFtnLeaf( eMakePage ) : GetPrevFtnLeaf( eMakePage );
842cdf0e10cSrcweir
843cdf0e10cSrcweir // --> OD 2005-08-16 #i53323#
844cdf0e10cSrcweir // A frame could be inside a table AND inside a section.
845cdf0e10cSrcweir // Thus, it has to be determined, which is the first parent.
846cdf0e10cSrcweir bool bInTab( IsInTab() );
847cdf0e10cSrcweir bool bInSct( IsInSct() );
848cdf0e10cSrcweir if ( bInTab && bInSct )
849cdf0e10cSrcweir {
850cdf0e10cSrcweir const SwFrm* pUpperFrm( GetUpper() );
851cdf0e10cSrcweir while ( pUpperFrm )
852cdf0e10cSrcweir {
853cdf0e10cSrcweir if ( pUpperFrm->IsTabFrm() )
854cdf0e10cSrcweir {
855cdf0e10cSrcweir // the table is the first.
856cdf0e10cSrcweir bInSct = false;
857cdf0e10cSrcweir break;
858cdf0e10cSrcweir }
859cdf0e10cSrcweir else if ( pUpperFrm->IsSctFrm() )
860cdf0e10cSrcweir {
861cdf0e10cSrcweir // the section is the first.
862cdf0e10cSrcweir bInTab = false;
863cdf0e10cSrcweir break;
864cdf0e10cSrcweir }
865cdf0e10cSrcweir
866cdf0e10cSrcweir pUpperFrm = pUpperFrm->GetUpper();
867cdf0e10cSrcweir }
868cdf0e10cSrcweir }
869cdf0e10cSrcweir
870cdf0e10cSrcweir if ( bInTab && ( !IsTabFrm() || GetUpper()->IsCellFrm() ) ) // TABLE IN TABLE
871cdf0e10cSrcweir return bFwd ? GetNextCellLeaf( eMakePage ) : GetPrevCellLeaf( eMakePage );
872cdf0e10cSrcweir
873cdf0e10cSrcweir if ( bInSct )
874cdf0e10cSrcweir return bFwd ? GetNextSctLeaf( eMakePage ) : GetPrevSctLeaf( eMakePage );
875cdf0e10cSrcweir // <--
876cdf0e10cSrcweir
877cdf0e10cSrcweir return bFwd ? GetNextLeaf( eMakePage ) : GetPrevLeaf( eMakePage );
878cdf0e10cSrcweir }
879cdf0e10cSrcweir
880cdf0e10cSrcweir
881cdf0e10cSrcweir
WrongPageDesc(SwPageFrm * pNew)882cdf0e10cSrcweir sal_Bool SwFrm::WrongPageDesc( SwPageFrm* pNew )
883cdf0e10cSrcweir {
884cdf0e10cSrcweir //Jetzt wirds leider etwas kompliziert:
885cdf0e10cSrcweir //Ich bringe ich evtl. selbst
886cdf0e10cSrcweir //einen Pagedesc mit; der der Folgeseite muss dann damit
887cdf0e10cSrcweir //uebereinstimmen.
888cdf0e10cSrcweir //Anderfalls muss ich mir etwas genauer ansehen wo der
889cdf0e10cSrcweir //Folgepagedesc herkam.
890cdf0e10cSrcweir //Wenn die Folgeseite selbst schon sagt, dass ihr
891cdf0e10cSrcweir //Pagedesc nicht stimmt so kann ich das Teil bedenkenlos
892cdf0e10cSrcweir //auswechseln.
893cdf0e10cSrcweir //Wenn die Seite meint, dass ihr Pagedesc stimmt, so heisst
894cdf0e10cSrcweir //das leider noch immer nicht, dass ich damit etwas anfangen
895cdf0e10cSrcweir //kann: Wenn der erste BodyCntnt einen PageDesc oder einen
896cdf0e10cSrcweir //PageBreak wuenscht, so muss ich ebenfalls eine neue
897cdf0e10cSrcweir //Seite einfuegen; es sein denn die gewuenschte Seite ist
898cdf0e10cSrcweir //die richtige.
899cdf0e10cSrcweir //Wenn ich einen neue Seite eingefuegt habe, so fangen die
900cdf0e10cSrcweir //Probleme leider erst an, denn wahrscheinlich wird die dann
901cdf0e10cSrcweir //folgende Seite verkehrt gewesen und ausgewechselt worden
902cdf0e10cSrcweir //sein. Das hat zur Folge, dass ich zwar eine neue (und
903cdf0e10cSrcweir //jetzt richtige) Seite habe, die Bedingungen zum auswechseln
904cdf0e10cSrcweir //aber leider noch immer stimmen.
905cdf0e10cSrcweir //Ausweg: Vorlaeufiger Versuch, nur einmal eine neue Seite
906cdf0e10cSrcweir //einsetzen (Leerseiten werden noetigenfalls bereits von
907cdf0e10cSrcweir //InsertPage() eingefuegt.
908cdf0e10cSrcweir const SwFmtPageDesc &rFmtDesc = GetAttrSet()->GetPageDesc();
909cdf0e10cSrcweir
910cdf0e10cSrcweir //Mein Pagedesc zaehlt nicht, wenn ich ein Follow bin!
911cdf0e10cSrcweir SwPageDesc *pDesc = 0;
912cdf0e10cSrcweir sal_uInt16 nTmp = 0;
913cdf0e10cSrcweir SwFlowFrm *pFlow = SwFlowFrm::CastFlowFrm( this );
914cdf0e10cSrcweir if ( !pFlow || !pFlow->IsFollow() )
915cdf0e10cSrcweir {
916cdf0e10cSrcweir pDesc = (SwPageDesc*)rFmtDesc.GetPageDesc();
917cdf0e10cSrcweir if( pDesc )
918cdf0e10cSrcweir {
919cdf0e10cSrcweir if( !pDesc->GetRightFmt() )
920cdf0e10cSrcweir nTmp = 2;
921cdf0e10cSrcweir else if( !pDesc->GetLeftFmt() )
922cdf0e10cSrcweir nTmp = 1;
923cdf0e10cSrcweir else if( rFmtDesc.GetNumOffset() )
924cdf0e10cSrcweir nTmp = rFmtDesc.GetNumOffset();
925cdf0e10cSrcweir }
926cdf0e10cSrcweir }
927cdf0e10cSrcweir
928cdf0e10cSrcweir //Bringt der Cntnt einen Pagedesc mit oder muss zaehlt die
929cdf0e10cSrcweir //virtuelle Seitennummer des neuen Layoutleafs?
930cdf0e10cSrcweir // Bei Follows zaehlt der PageDesc nicht
931cdf0e10cSrcweir const sal_Bool bOdd = nTmp ? ( nTmp % 2 ? sal_True : sal_False )
932cdf0e10cSrcweir : pNew->OnRightPage();
933cdf0e10cSrcweir if ( !pDesc )
934cdf0e10cSrcweir pDesc = pNew->FindPageDesc();
935cdf0e10cSrcweir const SwFlowFrm *pNewFlow = pNew->FindFirstBodyCntnt();
936cdf0e10cSrcweir // Haben wir uns selbst gefunden?
937cdf0e10cSrcweir if( pNewFlow == pFlow )
938cdf0e10cSrcweir pNewFlow = NULL;
939cdf0e10cSrcweir if ( pNewFlow && pNewFlow->GetFrm()->IsInTab() )
940cdf0e10cSrcweir pNewFlow = pNewFlow->GetFrm()->FindTabFrm();
941cdf0e10cSrcweir const SwPageDesc *pNewDesc= ( pNewFlow && !pNewFlow->IsFollow() )
942cdf0e10cSrcweir ? pNewFlow->GetFrm()->GetAttrSet()->GetPageDesc().GetPageDesc():0;
943cdf0e10cSrcweir
944cdf0e10cSrcweir return ( pNew->GetPageDesc() != pDesc || // own desc ?
945cdf0e10cSrcweir pNew->GetFmt() != (bOdd ? pDesc->GetRightFmt() : pDesc->GetLeftFmt()) ||
946cdf0e10cSrcweir ( pNewDesc && pNewDesc == pDesc ) );
947cdf0e10cSrcweir }
948cdf0e10cSrcweir
949cdf0e10cSrcweir
950cdf0e10cSrcweir /*************************************************************************
951cdf0e10cSrcweir |*
952cdf0e10cSrcweir |* SwFrm::GetNextLeaf()
953cdf0e10cSrcweir |*
954cdf0e10cSrcweir |* Beschreibung Liefert das naechste LayoutBlatt in den das
955cdf0e10cSrcweir |* Frame gemoved werden kann.
956cdf0e10cSrcweir |*
957cdf0e10cSrcweir |* Ersterstellung MA 16. Nov. 92
958cdf0e10cSrcweir |* Letzte Aenderung MA 05. Dec. 96
959cdf0e10cSrcweir |*
960cdf0e10cSrcweir |*************************************************************************/
961cdf0e10cSrcweir
GetNextLeaf(MakePageType eMakePage)962cdf0e10cSrcweir SwLayoutFrm *SwFrm::GetNextLeaf( MakePageType eMakePage )
963cdf0e10cSrcweir {
964cdf0e10cSrcweir ASSERT( !IsInFtn(), "GetNextLeaf(), don't call me for Ftn." );
965cdf0e10cSrcweir ASSERT( !IsInSct(), "GetNextLeaf(), don't call me for Sections." );
966cdf0e10cSrcweir
967cdf0e10cSrcweir const sal_Bool bBody = IsInDocBody(); //Wenn ich aus dem DocBody komme
968cdf0e10cSrcweir //Will ich auch im Body landen.
969cdf0e10cSrcweir
970cdf0e10cSrcweir // Bei Flys macht es keinen Sinn, Seiten einzufuegen, wir wollen lediglich
971cdf0e10cSrcweir // die Verkettung absuchen.
972cdf0e10cSrcweir if( IsInFly() )
973cdf0e10cSrcweir eMakePage = MAKEPAGE_NONE;
974cdf0e10cSrcweir
975cdf0e10cSrcweir //Bei Tabellen gleich den grossen Sprung wagen, ein einfaches GetNext...
976cdf0e10cSrcweir //wuerde die erste Zellen und in der Folge alle weiteren Zellen nacheinander
977cdf0e10cSrcweir //abklappern....
978cdf0e10cSrcweir SwLayoutFrm *pLayLeaf = 0;
979cdf0e10cSrcweir if ( IsTabFrm() )
980cdf0e10cSrcweir {
981cdf0e10cSrcweir SwCntntFrm* pTmp = ((SwTabFrm*)this)->FindLastCntnt();
982cdf0e10cSrcweir if ( pTmp )
983cdf0e10cSrcweir pLayLeaf = pTmp->GetUpper();
984cdf0e10cSrcweir }
985cdf0e10cSrcweir if ( !pLayLeaf )
986cdf0e10cSrcweir pLayLeaf = GetNextLayoutLeaf();
987cdf0e10cSrcweir
988cdf0e10cSrcweir SwLayoutFrm *pOldLayLeaf = 0; //Damit bei neu erzeugten Seiten
989cdf0e10cSrcweir //nicht wieder vom Anfang gesucht
990cdf0e10cSrcweir //wird.
991cdf0e10cSrcweir sal_Bool bNewPg = sal_False; //nur einmal eine neue Seite einfuegen.
992cdf0e10cSrcweir
993cdf0e10cSrcweir while ( sal_True )
994cdf0e10cSrcweir {
995cdf0e10cSrcweir if ( pLayLeaf )
996cdf0e10cSrcweir {
997cdf0e10cSrcweir //Es gibt noch einen weiteren LayoutFrm, mal sehen,
998cdf0e10cSrcweir //ob er bereit ist mich aufzunehmen.
999cdf0e10cSrcweir //Dazu braucht er nur von der gleichen Art wie mein Ausgangspunkt
1000cdf0e10cSrcweir //sein (DocBody bzw. Footnote.)
1001cdf0e10cSrcweir if ( pLayLeaf->FindPageFrm()->IsFtnPage() )
1002cdf0e10cSrcweir { //Wenn ich bei den Endnotenseiten angelangt bin hat sichs.
1003cdf0e10cSrcweir pLayLeaf = 0;
1004cdf0e10cSrcweir continue;
1005cdf0e10cSrcweir }
1006cdf0e10cSrcweir if ( (bBody && !pLayLeaf->IsInDocBody()) || pLayLeaf->IsInTab()
1007cdf0e10cSrcweir || pLayLeaf->IsInSct() )
1008cdf0e10cSrcweir {
1009cdf0e10cSrcweir //Er will mich nicht; neuer Versuch, neues Glueck
1010cdf0e10cSrcweir pOldLayLeaf = pLayLeaf;
1011cdf0e10cSrcweir pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
1012cdf0e10cSrcweir continue;
1013cdf0e10cSrcweir }
1014cdf0e10cSrcweir //Er will mich, also ist er der gesuchte und ich bin fertig.
1015cdf0e10cSrcweir //Bei einem Seitenwechsel kann es allerdings noch sein, dass
1016cdf0e10cSrcweir //Der Seitentyp nicht der gewuenschte ist, in diesem Fall muessen
1017cdf0e10cSrcweir //wir eine Seite des richtigen Typs einfuegen.
1018cdf0e10cSrcweir
1019cdf0e10cSrcweir if( !IsFlowFrm() && ( eMakePage == MAKEPAGE_NONE ||
1020cdf0e10cSrcweir eMakePage==MAKEPAGE_APPEND || eMakePage==MAKEPAGE_NOSECTION ) )
1021cdf0e10cSrcweir return pLayLeaf;
1022cdf0e10cSrcweir
1023cdf0e10cSrcweir SwPageFrm *pNew = pLayLeaf->FindPageFrm();
1024cdf0e10cSrcweir const ViewShell *pSh = getRootFrm()->GetCurrShell();
1025cdf0e10cSrcweir // #111704# The pagedesc check does not make sense for frames in fly frames
1026cdf0e10cSrcweir if ( pNew != FindPageFrm() && !bNewPg && !IsInFly() &&
1027cdf0e10cSrcweir // --> FME 2005-05-10 #i46683#
1028cdf0e10cSrcweir // Do not consider page descriptions in browse mode (since
1029cdf0e10cSrcweir // MoveBwd ignored them)
1030cdf0e10cSrcweir !(pSh && pSh->GetViewOptions()->getBrowseMode() ) )
1031cdf0e10cSrcweir // <--
1032cdf0e10cSrcweir {
1033cdf0e10cSrcweir if( WrongPageDesc( pNew ) )
1034cdf0e10cSrcweir {
1035cdf0e10cSrcweir SwFtnContFrm *pCont = pNew->FindFtnCont();
1036cdf0e10cSrcweir if( pCont )
1037cdf0e10cSrcweir {
1038cdf0e10cSrcweir // Falls die Referenz der ersten Fussnote dieser Seite
1039cdf0e10cSrcweir // vor der Seite liegt, fuegen wir lieber keine neue Seite
1040cdf0e10cSrcweir // ein (Bug #55620#)
1041cdf0e10cSrcweir SwFtnFrm *pFtn = (SwFtnFrm*)pCont->Lower();
1042cdf0e10cSrcweir if( pFtn && pFtn->GetRef() )
1043cdf0e10cSrcweir {
1044cdf0e10cSrcweir const sal_uInt16 nRefNum = pNew->GetPhyPageNum();
1045cdf0e10cSrcweir if( pFtn->GetRef()->GetPhyPageNum() < nRefNum )
1046cdf0e10cSrcweir break;
1047cdf0e10cSrcweir }
1048cdf0e10cSrcweir }
1049cdf0e10cSrcweir //Erwischt, die folgende Seite ist verkehrt, also
1050cdf0e10cSrcweir //muss eine neue eingefuegt werden.
1051cdf0e10cSrcweir if ( eMakePage == MAKEPAGE_INSERT )
1052cdf0e10cSrcweir {
1053cdf0e10cSrcweir bNewPg = sal_True;
1054cdf0e10cSrcweir
1055cdf0e10cSrcweir SwPageFrm *pPg = pOldLayLeaf ?
1056cdf0e10cSrcweir pOldLayLeaf->FindPageFrm() : 0;
1057cdf0e10cSrcweir if ( pPg && pPg->IsEmptyPage() )
1058cdf0e10cSrcweir //Nicht hinter, sondern vor der EmptyPage einfuegen.
1059cdf0e10cSrcweir pPg = (SwPageFrm*)pPg->GetPrev();
1060cdf0e10cSrcweir
1061cdf0e10cSrcweir if ( !pPg || pPg == pNew )
1062cdf0e10cSrcweir pPg = FindPageFrm();
1063cdf0e10cSrcweir
1064cdf0e10cSrcweir InsertPage( pPg, sal_False );
1065cdf0e10cSrcweir pLayLeaf = GetNextLayoutLeaf();
1066cdf0e10cSrcweir pOldLayLeaf = 0;
1067cdf0e10cSrcweir continue;
1068cdf0e10cSrcweir }
1069cdf0e10cSrcweir else
1070cdf0e10cSrcweir pLayLeaf = 0;
1071cdf0e10cSrcweir }
1072cdf0e10cSrcweir }
1073cdf0e10cSrcweir break;
1074cdf0e10cSrcweir }
1075cdf0e10cSrcweir else
1076cdf0e10cSrcweir {
1077cdf0e10cSrcweir //Es gibt keinen passenden weiteren LayoutFrm, also muss eine
1078cdf0e10cSrcweir //neue Seite her.
1079cdf0e10cSrcweir if ( eMakePage == MAKEPAGE_APPEND || eMakePage == MAKEPAGE_INSERT )
1080cdf0e10cSrcweir {
1081cdf0e10cSrcweir InsertPage(
1082cdf0e10cSrcweir pOldLayLeaf ? pOldLayLeaf->FindPageFrm() : FindPageFrm(),
1083cdf0e10cSrcweir sal_False );
1084cdf0e10cSrcweir
1085cdf0e10cSrcweir //und nochmal das ganze
1086cdf0e10cSrcweir pLayLeaf = pOldLayLeaf ? pOldLayLeaf : GetNextLayoutLeaf();
1087cdf0e10cSrcweir }
1088cdf0e10cSrcweir else
1089cdf0e10cSrcweir break;
1090cdf0e10cSrcweir }
1091cdf0e10cSrcweir }
1092cdf0e10cSrcweir return pLayLeaf;
1093cdf0e10cSrcweir }
1094cdf0e10cSrcweir
1095cdf0e10cSrcweir /*************************************************************************
1096cdf0e10cSrcweir |*
1097cdf0e10cSrcweir |* SwFrm::GetPrevLeaf()
1098cdf0e10cSrcweir |*
1099cdf0e10cSrcweir |* Beschreibung Liefert das vorhergehende LayoutBlatt in das der
1100cdf0e10cSrcweir |* Frame gemoved werden kann.
1101cdf0e10cSrcweir |* Ersterstellung MA 16. Nov. 92
1102cdf0e10cSrcweir |* Letzte Aenderung MA 25. Apr. 95
1103cdf0e10cSrcweir |*
1104cdf0e10cSrcweir |*************************************************************************/
1105cdf0e10cSrcweir
1106cdf0e10cSrcweir
GetPrevLeaf(MakePageType)1107cdf0e10cSrcweir SwLayoutFrm *SwFrm::GetPrevLeaf( MakePageType )
1108cdf0e10cSrcweir {
1109cdf0e10cSrcweir ASSERT( !IsInFtn(), "GetPrevLeaf(), don't call me for Ftn." );
1110cdf0e10cSrcweir
1111cdf0e10cSrcweir const sal_Bool bBody = IsInDocBody(); //Wenn ich aus dem DocBody komme
1112cdf0e10cSrcweir //will ich auch im Body landen.
1113cdf0e10cSrcweir const sal_Bool bFly = IsInFly();
1114cdf0e10cSrcweir
1115cdf0e10cSrcweir SwLayoutFrm *pLayLeaf = GetPrevLayoutLeaf();
1116cdf0e10cSrcweir SwLayoutFrm *pPrevLeaf = 0;
1117cdf0e10cSrcweir
1118cdf0e10cSrcweir while ( pLayLeaf )
1119cdf0e10cSrcweir {
1120cdf0e10cSrcweir if ( pLayLeaf->IsInTab() || //In Tabellen geht's niemals hinein.
1121cdf0e10cSrcweir pLayLeaf->IsInSct() ) //In Bereiche natuerlich auch nicht!
1122cdf0e10cSrcweir pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
1123cdf0e10cSrcweir else if ( bBody && pLayLeaf->IsInDocBody() )
1124cdf0e10cSrcweir {
1125cdf0e10cSrcweir if ( pLayLeaf->Lower() )
1126cdf0e10cSrcweir break;
1127cdf0e10cSrcweir pPrevLeaf = pLayLeaf;
1128cdf0e10cSrcweir pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
1129cdf0e10cSrcweir if ( pLayLeaf )
1130cdf0e10cSrcweir SwFlowFrm::SetMoveBwdJump( sal_True );
1131cdf0e10cSrcweir }
1132cdf0e10cSrcweir else if ( bFly )
1133cdf0e10cSrcweir break; //Cntnts in Flys sollte jedes Layout-Blatt recht sein.
1134cdf0e10cSrcweir else
1135cdf0e10cSrcweir pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
1136cdf0e10cSrcweir }
1137cdf0e10cSrcweir return pLayLeaf ? pLayLeaf : pPrevLeaf;
1138cdf0e10cSrcweir }
1139cdf0e10cSrcweir
1140cdf0e10cSrcweir /*************************************************************************
1141cdf0e10cSrcweir |*
1142cdf0e10cSrcweir |* SwFlowFrm::IsPrevObjMove()
1143cdf0e10cSrcweir |*
1144cdf0e10cSrcweir |* Ersterstellung MA 20. Feb. 96
1145cdf0e10cSrcweir |* Letzte Aenderung MA 22. Feb. 96
1146cdf0e10cSrcweir |*
1147cdf0e10cSrcweir |*************************************************************************/
1148cdf0e10cSrcweir
1149cdf0e10cSrcweir
IsPrevObjMove() const1150cdf0e10cSrcweir sal_Bool SwFlowFrm::IsPrevObjMove() const
1151cdf0e10cSrcweir {
1152cdf0e10cSrcweir //sal_True der FlowFrm soll auf einen Rahmen des Vorgaengers Ruecksicht nehmen
1153cdf0e10cSrcweir // und fuer diesen ggf. Umbrechen.
1154cdf0e10cSrcweir
1155cdf0e10cSrcweir //!!!!!!!!!!!Hack!!!!!!!!!!!
1156cdf0e10cSrcweir const ViewShell *pSh = rThis.getRootFrm()->GetCurrShell();
1157cdf0e10cSrcweir if( pSh && pSh->GetViewOptions()->getBrowseMode() )
1158cdf0e10cSrcweir return sal_False;
1159cdf0e10cSrcweir
1160cdf0e10cSrcweir SwFrm *pPre = rThis.FindPrev();
1161cdf0e10cSrcweir
1162cdf0e10cSrcweir if ( pPre && pPre->GetDrawObjs() )
1163cdf0e10cSrcweir {
1164cdf0e10cSrcweir ASSERT( SwFlowFrm::CastFlowFrm( pPre ), "new flowfrm?" );
1165cdf0e10cSrcweir if( SwFlowFrm::CastFlowFrm( pPre )->IsAnFollow( this ) )
1166cdf0e10cSrcweir return sal_False;
1167cdf0e10cSrcweir SwLayoutFrm* pPreUp = pPre->GetUpper();
1168cdf0e10cSrcweir // Wenn der Upper ein SectionFrm oder die Spalte eines SectionFrms ist,
1169cdf0e10cSrcweir // duerfen wir aus diesem durchaus heraushaengen,
1170cdf0e10cSrcweir // es muss stattdessen der Upper des SectionFrms beruecksichtigt werden.
1171cdf0e10cSrcweir if( pPreUp->IsInSct() )
1172cdf0e10cSrcweir {
1173cdf0e10cSrcweir if( pPreUp->IsSctFrm() )
1174cdf0e10cSrcweir pPreUp = pPreUp->GetUpper();
1175cdf0e10cSrcweir else if( pPreUp->IsColBodyFrm() &&
1176cdf0e10cSrcweir pPreUp->GetUpper()->GetUpper()->IsSctFrm() )
1177cdf0e10cSrcweir pPreUp = pPreUp->GetUpper()->GetUpper()->GetUpper();
1178cdf0e10cSrcweir }
1179cdf0e10cSrcweir // --> OD 2004-10-15 #i26945# - re-factoring:
1180cdf0e10cSrcweir // use <GetVertPosOrientFrm()> to determine, if object has followed the
1181cdf0e10cSrcweir // text flow to the next layout frame
1182cdf0e10cSrcweir for ( sal_uInt16 i = 0; i < pPre->GetDrawObjs()->Count(); ++i )
1183cdf0e10cSrcweir {
1184cdf0e10cSrcweir // --> OD 2004-07-01 #i28701# - consider changed type of
1185cdf0e10cSrcweir // <SwSortedObjs> entries.
1186cdf0e10cSrcweir const SwAnchoredObject* pObj = (*pPre->GetDrawObjs())[i];
1187cdf0e10cSrcweir // OD 2004-01-20 #110582# - do not consider hidden objects
1188cdf0e10cSrcweir // --> OD 2004-10-15 #i26945# - do not consider object, which
1189cdf0e10cSrcweir // doesn't follow the text flow.
1190cdf0e10cSrcweir if ( pObj->GetFrmFmt().GetDoc()->IsVisibleLayerId(
1191cdf0e10cSrcweir pObj->GetDrawObj()->GetLayer() ) &&
1192cdf0e10cSrcweir pObj->GetFrmFmt().GetFollowTextFlow().GetValue() )
1193cdf0e10cSrcweir // <--
1194cdf0e10cSrcweir {
1195cdf0e10cSrcweir const SwLayoutFrm* pVertPosOrientFrm = pObj->GetVertPosOrientFrm();
1196cdf0e10cSrcweir if ( pVertPosOrientFrm &&
1197cdf0e10cSrcweir pPreUp != pVertPosOrientFrm &&
1198cdf0e10cSrcweir !pPreUp->IsAnLower( pVertPosOrientFrm ) )
1199cdf0e10cSrcweir {
1200cdf0e10cSrcweir return sal_True;
1201cdf0e10cSrcweir }
1202cdf0e10cSrcweir }
1203cdf0e10cSrcweir }
1204cdf0e10cSrcweir // <--
1205cdf0e10cSrcweir }
1206cdf0e10cSrcweir return sal_False;
1207cdf0e10cSrcweir }
1208cdf0e10cSrcweir
1209cdf0e10cSrcweir /*************************************************************************
1210cdf0e10cSrcweir |*
1211cdf0e10cSrcweir |* sal_Bool SwFlowFrm::IsPageBreak()
1212cdf0e10cSrcweir |*
1213cdf0e10cSrcweir |* Beschreibung Wenn vor dem Frm ein harter Seitenumbruch steht UND
1214cdf0e10cSrcweir |* es einen Vorgaenger auf der gleichen Seite gibt, wird sal_True
1215cdf0e10cSrcweir |* zurueckgeliefert (es muss ein PageBreak erzeugt werden) sal_False sonst.
1216cdf0e10cSrcweir |* Wenn in bAct sal_True uebergeben wird, gibt die Funktion dann sal_True
1217cdf0e10cSrcweir |* zurueck, wenn ein PageBreak besteht.
1218cdf0e10cSrcweir |* Fuer Follows wird der harte Seitenumbruch natuerlich nicht
1219cdf0e10cSrcweir |* ausgewertet.
1220cdf0e10cSrcweir |* Der Seitenumbruch steht im eigenen FrmFmt (BEFORE) oder im FrmFmt
1221cdf0e10cSrcweir |* des Vorgaengers (AFTER). Wenn es keinen Vorgaenger auf der Seite
1222cdf0e10cSrcweir |* gibt ist jede weitere Ueberlegung ueberfluessig.
1223cdf0e10cSrcweir |* Ein Seitenumbruch (oder der Bedarf) liegt auch dann vor, wenn
1224cdf0e10cSrcweir |* im FrmFmt ein PageDesc angegeben wird.
1225cdf0e10cSrcweir |* Die Implementierung arbeitet zuaechst nur auf CntntFrms!
1226cdf0e10cSrcweir |* -->Fuer LayoutFrms ist die Definition des Vorgaengers unklar.
1227cdf0e10cSrcweir |* Ersterstellung MA ??
1228cdf0e10cSrcweir |* Letzte Aenderung MA 21. Mar. 95
1229cdf0e10cSrcweir |*
1230cdf0e10cSrcweir |*************************************************************************/
1231cdf0e10cSrcweir
1232cdf0e10cSrcweir
IsPageBreak(sal_Bool bAct) const1233cdf0e10cSrcweir sal_Bool SwFlowFrm::IsPageBreak( sal_Bool bAct ) const
1234cdf0e10cSrcweir {
1235cdf0e10cSrcweir if ( !IsFollow() && rThis.IsInDocBody() &&
1236cdf0e10cSrcweir ( !rThis.IsInTab() || ( rThis.IsTabFrm() && !rThis.GetUpper()->IsInTab() ) ) ) // i66968
1237cdf0e10cSrcweir {
1238cdf0e10cSrcweir const ViewShell *pSh = rThis.getRootFrm()->GetCurrShell();
1239cdf0e10cSrcweir if( pSh && pSh->GetViewOptions()->getBrowseMode() )
1240cdf0e10cSrcweir return sal_False;
1241cdf0e10cSrcweir const SwAttrSet *pSet = rThis.GetAttrSet();
1242cdf0e10cSrcweir
1243cdf0e10cSrcweir //Vorgaenger ermitteln
1244cdf0e10cSrcweir const SwFrm *pPrev = rThis.FindPrev();
1245cdf0e10cSrcweir while ( pPrev && ( !pPrev->IsInDocBody() ||
1246cdf0e10cSrcweir ( pPrev->IsTxtFrm() && ((SwTxtFrm*)pPrev)->IsHiddenNow() ) ) )
1247cdf0e10cSrcweir pPrev = pPrev->FindPrev();
1248cdf0e10cSrcweir
1249cdf0e10cSrcweir if ( pPrev )
1250cdf0e10cSrcweir {
1251cdf0e10cSrcweir ASSERT( pPrev->IsInDocBody(), "IsPageBreak: Not in DocBody?" );
1252cdf0e10cSrcweir if ( bAct )
1253cdf0e10cSrcweir { if ( rThis.FindPageFrm() == pPrev->FindPageFrm() )
1254cdf0e10cSrcweir return sal_False;
1255cdf0e10cSrcweir }
1256cdf0e10cSrcweir else
1257cdf0e10cSrcweir { if ( rThis.FindPageFrm() != pPrev->FindPageFrm() )
1258cdf0e10cSrcweir return sal_False;
1259cdf0e10cSrcweir }
1260cdf0e10cSrcweir
1261cdf0e10cSrcweir const SvxBreak eBreak = pSet->GetBreak().GetBreak();
1262cdf0e10cSrcweir if ( eBreak == SVX_BREAK_PAGE_BEFORE || eBreak == SVX_BREAK_PAGE_BOTH )
1263cdf0e10cSrcweir return sal_True;
1264cdf0e10cSrcweir else
1265cdf0e10cSrcweir {
1266cdf0e10cSrcweir const SvxBreak &ePrB = pPrev->GetAttrSet()->GetBreak().GetBreak();
1267cdf0e10cSrcweir if ( ePrB == SVX_BREAK_PAGE_AFTER ||
1268cdf0e10cSrcweir ePrB == SVX_BREAK_PAGE_BOTH ||
1269cdf0e10cSrcweir pSet->GetPageDesc().GetPageDesc() )
1270cdf0e10cSrcweir return sal_True;
1271cdf0e10cSrcweir }
1272cdf0e10cSrcweir }
1273cdf0e10cSrcweir }
1274cdf0e10cSrcweir return sal_False;
1275cdf0e10cSrcweir }
1276cdf0e10cSrcweir
1277cdf0e10cSrcweir /*************************************************************************
1278cdf0e10cSrcweir |*
1279cdf0e10cSrcweir |* sal_Bool SwFlowFrm::IsColBreak()
1280cdf0e10cSrcweir |*
1281cdf0e10cSrcweir |* Beschreibung Wenn vor dem Frm ein harter Spaltenumbruch steht UND
1282cdf0e10cSrcweir |* es einen Vorgaenger in der gleichen Spalte gibt, wird sal_True
1283cdf0e10cSrcweir |* zurueckgeliefert (es muss ein PageBreak erzeugt werden) sal_False sonst.
1284cdf0e10cSrcweir |* Wenn in bAct sal_True uebergeben wird, gibt die Funktion dann sal_True
1285cdf0e10cSrcweir |* zurueck, wenn ein ColBreak besteht.
1286cdf0e10cSrcweir |* Fuer Follows wird der harte Spaltenumbruch natuerlich nicht
1287cdf0e10cSrcweir |* ausgewertet.
1288cdf0e10cSrcweir |* Der Spaltenumbruch steht im eigenen FrmFmt (BEFORE) oder im FrmFmt
1289cdf0e10cSrcweir |* des Vorgaengers (AFTER). Wenn es keinen Vorgaenger in der Spalte
1290cdf0e10cSrcweir |* gibt ist jede weitere Ueberlegung ueberfluessig.
1291cdf0e10cSrcweir |* Die Implementierung arbeitet zuaechst nur auf CntntFrms!
1292cdf0e10cSrcweir |* -->Fuer LayoutFrms ist die Definition des Vorgaengers unklar.
1293cdf0e10cSrcweir |* Ersterstellung MA 11. Jun. 93
1294cdf0e10cSrcweir |* Letzte Aenderung MA 21. Mar. 95
1295cdf0e10cSrcweir |*
1296cdf0e10cSrcweir |*************************************************************************/
1297cdf0e10cSrcweir
IsColBreak(sal_Bool bAct) const1298cdf0e10cSrcweir sal_Bool SwFlowFrm::IsColBreak( sal_Bool bAct ) const
1299cdf0e10cSrcweir {
1300cdf0e10cSrcweir if ( !IsFollow() && (rThis.IsMoveable() || bAct) )
1301cdf0e10cSrcweir {
1302cdf0e10cSrcweir const SwFrm *pCol = rThis.FindColFrm();
1303cdf0e10cSrcweir if ( pCol )
1304cdf0e10cSrcweir {
1305cdf0e10cSrcweir //Vorgaenger ermitteln
1306cdf0e10cSrcweir const SwFrm *pPrev = rThis.FindPrev();
1307cdf0e10cSrcweir while( pPrev && ( ( !pPrev->IsInDocBody() && !rThis.IsInFly() ) ||
1308cdf0e10cSrcweir ( pPrev->IsTxtFrm() && ((SwTxtFrm*)pPrev)->IsHiddenNow() ) ) )
1309cdf0e10cSrcweir pPrev = pPrev->FindPrev();
1310cdf0e10cSrcweir
1311cdf0e10cSrcweir if ( pPrev )
1312cdf0e10cSrcweir {
1313cdf0e10cSrcweir if ( bAct )
1314cdf0e10cSrcweir { if ( pCol == pPrev->FindColFrm() )
1315cdf0e10cSrcweir return sal_False;
1316cdf0e10cSrcweir }
1317cdf0e10cSrcweir else
1318cdf0e10cSrcweir { if ( pCol != pPrev->FindColFrm() )
1319cdf0e10cSrcweir return sal_False;
1320cdf0e10cSrcweir }
1321cdf0e10cSrcweir
1322cdf0e10cSrcweir const SvxBreak eBreak = rThis.GetAttrSet()->GetBreak().GetBreak();
1323cdf0e10cSrcweir if ( eBreak == SVX_BREAK_COLUMN_BEFORE ||
1324cdf0e10cSrcweir eBreak == SVX_BREAK_COLUMN_BOTH )
1325cdf0e10cSrcweir return sal_True;
1326cdf0e10cSrcweir else
1327cdf0e10cSrcweir {
1328cdf0e10cSrcweir const SvxBreak &ePrB = pPrev->GetAttrSet()->GetBreak().GetBreak();
1329cdf0e10cSrcweir if ( ePrB == SVX_BREAK_COLUMN_AFTER ||
1330cdf0e10cSrcweir ePrB == SVX_BREAK_COLUMN_BOTH )
1331cdf0e10cSrcweir return sal_True;
1332cdf0e10cSrcweir }
1333cdf0e10cSrcweir }
1334cdf0e10cSrcweir }
1335cdf0e10cSrcweir }
1336cdf0e10cSrcweir return sal_False;
1337cdf0e10cSrcweir }
1338cdf0e10cSrcweir
HasParaSpaceAtPages(sal_Bool bSct) const1339cdf0e10cSrcweir sal_Bool SwFlowFrm::HasParaSpaceAtPages( sal_Bool bSct ) const
1340cdf0e10cSrcweir {
1341cdf0e10cSrcweir if( rThis.IsInSct() )
1342cdf0e10cSrcweir {
1343cdf0e10cSrcweir const SwFrm* pTmp = rThis.GetUpper();
1344cdf0e10cSrcweir while( pTmp )
1345cdf0e10cSrcweir {
1346cdf0e10cSrcweir if( pTmp->IsCellFrm() || pTmp->IsFlyFrm() ||
1347cdf0e10cSrcweir pTmp->IsFooterFrm() || pTmp->IsHeaderFrm() ||
1348cdf0e10cSrcweir ( pTmp->IsFtnFrm() && !((SwFtnFrm*)pTmp)->GetMaster() ) )
1349cdf0e10cSrcweir return sal_True;
1350cdf0e10cSrcweir if( pTmp->IsPageFrm() )
1351cdf0e10cSrcweir return ( pTmp->GetPrev() && !IsPageBreak(sal_True) ) ? sal_False : sal_True;
1352cdf0e10cSrcweir if( pTmp->IsColumnFrm() && pTmp->GetPrev() )
1353cdf0e10cSrcweir return IsColBreak( sal_True );
1354cdf0e10cSrcweir if( pTmp->IsSctFrm() && ( !bSct || pTmp->GetPrev() ) )
1355cdf0e10cSrcweir return sal_False;
1356cdf0e10cSrcweir pTmp = pTmp->GetUpper();
1357cdf0e10cSrcweir }
1358cdf0e10cSrcweir ASSERT( sal_False, "HasParaSpaceAtPages: Where's my page?" );
1359cdf0e10cSrcweir return sal_False;
1360cdf0e10cSrcweir }
1361cdf0e10cSrcweir if( !rThis.IsInDocBody() || ( rThis.IsInTab() && !rThis.IsTabFrm()) ||
1362cdf0e10cSrcweir IsPageBreak( sal_True ) || ( rThis.FindColFrm() && IsColBreak( sal_True ) ) )
1363cdf0e10cSrcweir return sal_True;
1364cdf0e10cSrcweir const SwFrm* pTmp = rThis.FindColFrm();
1365cdf0e10cSrcweir if( pTmp )
1366cdf0e10cSrcweir {
1367cdf0e10cSrcweir if( pTmp->GetPrev() )
1368cdf0e10cSrcweir return sal_False;
1369cdf0e10cSrcweir }
1370cdf0e10cSrcweir else
1371cdf0e10cSrcweir pTmp = &rThis;
1372cdf0e10cSrcweir pTmp = pTmp->FindPageFrm();
1373cdf0e10cSrcweir return pTmp && !pTmp->GetPrev();
1374cdf0e10cSrcweir }
1375cdf0e10cSrcweir
1376cdf0e10cSrcweir /** helper method to determine previous frame for calculation of the
1377cdf0e10cSrcweir upper space
1378cdf0e10cSrcweir
1379cdf0e10cSrcweir OD 2004-03-10 #i11860#
1380cdf0e10cSrcweir
1381cdf0e10cSrcweir @author OD
1382cdf0e10cSrcweir */
_GetPrevFrmForUpperSpaceCalc(const SwFrm * _pProposedPrevFrm) const1383cdf0e10cSrcweir const SwFrm* SwFlowFrm::_GetPrevFrmForUpperSpaceCalc( const SwFrm* _pProposedPrevFrm ) const
1384cdf0e10cSrcweir {
1385cdf0e10cSrcweir const SwFrm* pPrevFrm = _pProposedPrevFrm
1386cdf0e10cSrcweir ? _pProposedPrevFrm
1387cdf0e10cSrcweir : rThis.GetPrev();
1388cdf0e10cSrcweir
1389cdf0e10cSrcweir // Skip hidden paragraphs and empty sections
1390cdf0e10cSrcweir while ( pPrevFrm &&
1391cdf0e10cSrcweir ( ( pPrevFrm->IsTxtFrm() &&
1392cdf0e10cSrcweir static_cast<const SwTxtFrm*>(pPrevFrm)->IsHiddenNow() ) ||
1393cdf0e10cSrcweir ( pPrevFrm->IsSctFrm() &&
1394cdf0e10cSrcweir !static_cast<const SwSectionFrm*>(pPrevFrm)->GetSection() ) ) )
1395cdf0e10cSrcweir {
1396cdf0e10cSrcweir pPrevFrm = pPrevFrm->GetPrev();
1397cdf0e10cSrcweir }
1398cdf0e10cSrcweir
1399cdf0e10cSrcweir // Special case: no direct previous frame is found but frame is in footnote
1400cdf0e10cSrcweir // Search for a previous frame in previous footnote,
1401cdf0e10cSrcweir // if frame isn't in a section, which is also in the footnote
1402cdf0e10cSrcweir if ( !pPrevFrm && rThis.IsInFtn() &&
1403cdf0e10cSrcweir ( rThis.IsSctFrm() ||
1404cdf0e10cSrcweir !rThis.IsInSct() || !rThis.FindSctFrm()->IsInFtn() ) )
1405cdf0e10cSrcweir {
1406cdf0e10cSrcweir const SwFtnFrm* pPrevFtnFrm =
1407cdf0e10cSrcweir static_cast<const SwFtnFrm*>(rThis.FindFtnFrm()->GetPrev());
1408cdf0e10cSrcweir if ( pPrevFtnFrm )
1409cdf0e10cSrcweir {
1410cdf0e10cSrcweir pPrevFrm = pPrevFtnFrm->GetLastLower();
1411cdf0e10cSrcweir
1412cdf0e10cSrcweir // Skip hidden paragraphs and empty sections
1413cdf0e10cSrcweir while ( pPrevFrm &&
1414cdf0e10cSrcweir ( ( pPrevFrm->IsTxtFrm() &&
1415cdf0e10cSrcweir static_cast<const SwTxtFrm*>(pPrevFrm)->IsHiddenNow() ) ||
1416cdf0e10cSrcweir ( pPrevFrm->IsSctFrm() &&
1417cdf0e10cSrcweir !static_cast<const SwSectionFrm*>(pPrevFrm)->GetSection() ) ) )
1418cdf0e10cSrcweir {
1419cdf0e10cSrcweir pPrevFrm = pPrevFrm->GetPrev();
1420cdf0e10cSrcweir }
1421cdf0e10cSrcweir }
1422cdf0e10cSrcweir }
1423cdf0e10cSrcweir // Special case: found previous frame is a section
1424cdf0e10cSrcweir // Search for the last content in the section
1425cdf0e10cSrcweir if( pPrevFrm && pPrevFrm->IsSctFrm() )
1426cdf0e10cSrcweir {
1427cdf0e10cSrcweir const SwSectionFrm* pPrevSectFrm =
1428cdf0e10cSrcweir static_cast<const SwSectionFrm*>(pPrevFrm);
1429cdf0e10cSrcweir pPrevFrm = pPrevSectFrm->FindLastCntnt();
1430cdf0e10cSrcweir // If the last content is in a table _inside_ the section,
1431cdf0e10cSrcweir // take the table herself.
1432cdf0e10cSrcweir // OD 2004-02-18 #106629# - correction:
1433cdf0e10cSrcweir // Check directly, if table is inside table, instead of indirectly
1434cdf0e10cSrcweir // by checking, if section isn't inside a table
1435cdf0e10cSrcweir if ( pPrevFrm && pPrevFrm->IsInTab() )
1436cdf0e10cSrcweir {
1437cdf0e10cSrcweir const SwTabFrm* pTableFrm = pPrevFrm->FindTabFrm();
1438cdf0e10cSrcweir if ( pPrevSectFrm->IsAnLower( pTableFrm ) )
1439cdf0e10cSrcweir {
1440cdf0e10cSrcweir pPrevFrm = pTableFrm;
1441cdf0e10cSrcweir }
1442cdf0e10cSrcweir }
1443cdf0e10cSrcweir // OD 2004-02-18 #106629# correction: skip hidden text frames
1444cdf0e10cSrcweir while ( pPrevFrm &&
1445cdf0e10cSrcweir pPrevFrm->IsTxtFrm() &&
1446cdf0e10cSrcweir static_cast<const SwTxtFrm*>(pPrevFrm)->IsHiddenNow() )
1447cdf0e10cSrcweir {
1448cdf0e10cSrcweir pPrevFrm = pPrevFrm->GetPrev();
1449cdf0e10cSrcweir }
1450cdf0e10cSrcweir }
1451cdf0e10cSrcweir
1452cdf0e10cSrcweir return pPrevFrm;
1453cdf0e10cSrcweir }
1454cdf0e10cSrcweir
1455cdf0e10cSrcweir // OD 2004-03-12 #i11860# - add 3rd parameter <_bConsiderGrid>
CalcUpperSpace(const SwBorderAttrs * pAttrs,const SwFrm * pPr,const bool _bConsiderGrid) const1456cdf0e10cSrcweir SwTwips SwFlowFrm::CalcUpperSpace( const SwBorderAttrs *pAttrs,
1457cdf0e10cSrcweir const SwFrm* pPr,
1458cdf0e10cSrcweir const bool _bConsiderGrid ) const
1459cdf0e10cSrcweir {
1460cdf0e10cSrcweir // OD 2004-03-10 #i11860# - use new method <GetPrevFrmForUpperSpaceCalc(..)>
1461cdf0e10cSrcweir const SwFrm* pPrevFrm = _GetPrevFrmForUpperSpaceCalc( pPr );
1462cdf0e10cSrcweir
1463cdf0e10cSrcweir SwBorderAttrAccess *pAccess;
1464cdf0e10cSrcweir SwFrm* pOwn;
1465cdf0e10cSrcweir if( !pAttrs )
1466cdf0e10cSrcweir {
1467cdf0e10cSrcweir if( rThis.IsSctFrm() )
1468cdf0e10cSrcweir {
1469cdf0e10cSrcweir SwSectionFrm* pFoll = &((SwSectionFrm&)rThis);
1470cdf0e10cSrcweir do
1471cdf0e10cSrcweir pOwn = pFoll->ContainsAny();
1472cdf0e10cSrcweir while( !pOwn && 0 != ( pFoll = pFoll->GetFollow() ) );
1473cdf0e10cSrcweir if( !pOwn )
1474cdf0e10cSrcweir return 0;
1475cdf0e10cSrcweir }
1476cdf0e10cSrcweir else
1477cdf0e10cSrcweir pOwn = &rThis;
1478cdf0e10cSrcweir pAccess= new SwBorderAttrAccess( SwFrm::GetCache(), pOwn );
1479cdf0e10cSrcweir pAttrs = pAccess->Get();
1480cdf0e10cSrcweir }
1481cdf0e10cSrcweir else
1482cdf0e10cSrcweir {
1483cdf0e10cSrcweir pAccess = NULL;
1484cdf0e10cSrcweir pOwn = &rThis;
1485cdf0e10cSrcweir }
1486cdf0e10cSrcweir SwTwips nUpper = 0;
1487cdf0e10cSrcweir // OD 06.01.2004 #i11859#
1488cdf0e10cSrcweir {
1489cdf0e10cSrcweir const IDocumentSettingAccess* pIDSA = rThis.GetUpper()->GetFmt()->getIDocumentSettingAccess();
1490cdf0e10cSrcweir const bool bUseFormerLineSpacing = pIDSA->get(IDocumentSettingAccess::OLD_LINE_SPACING);
1491cdf0e10cSrcweir if( pPrevFrm )
1492cdf0e10cSrcweir {
1493cdf0e10cSrcweir // OD 2004-03-10 #i11860# - use new method to determine needed spacing
1494cdf0e10cSrcweir // values of found previous frame and use these values.
1495cdf0e10cSrcweir SwTwips nPrevLowerSpace = 0;
1496cdf0e10cSrcweir SwTwips nPrevLineSpacing = 0;
1497cdf0e10cSrcweir // --> OD 2009-08-28 #i102458#
1498cdf0e10cSrcweir bool bPrevLineSpacingPorportional = false;
1499cdf0e10cSrcweir GetSpacingValuesOfFrm( (*pPrevFrm),
1500cdf0e10cSrcweir nPrevLowerSpace, nPrevLineSpacing,
1501cdf0e10cSrcweir bPrevLineSpacingPorportional );
1502cdf0e10cSrcweir // <--
1503cdf0e10cSrcweir if( pIDSA->get(IDocumentSettingAccess::PARA_SPACE_MAX) )
1504cdf0e10cSrcweir {
1505cdf0e10cSrcweir nUpper = nPrevLowerSpace + pAttrs->GetULSpace().GetUpper();
1506cdf0e10cSrcweir SwTwips nAdd = nPrevLineSpacing;
1507cdf0e10cSrcweir // OD 07.01.2004 #i11859# - consideration of the line spacing
1508cdf0e10cSrcweir // for the upper spacing of a text frame
1509cdf0e10cSrcweir if ( bUseFormerLineSpacing )
1510cdf0e10cSrcweir {
1511cdf0e10cSrcweir // former consideration
1512cdf0e10cSrcweir if ( pOwn->IsTxtFrm() )
1513cdf0e10cSrcweir {
1514cdf0e10cSrcweir nAdd = Max( nAdd, static_cast<SwTxtFrm&>(rThis).GetLineSpace() );
1515cdf0e10cSrcweir }
1516cdf0e10cSrcweir nUpper += nAdd;
1517cdf0e10cSrcweir }
1518cdf0e10cSrcweir else
1519cdf0e10cSrcweir {
1520cdf0e10cSrcweir // new consideration:
1521cdf0e10cSrcweir // Only the proportional line spacing of the previous
1522cdf0e10cSrcweir // text frame is considered for the upper spacing and
1523cdf0e10cSrcweir // the line spacing values are add up instead of
1524cdf0e10cSrcweir // building its maximum.
1525cdf0e10cSrcweir if ( pOwn->IsTxtFrm() )
1526cdf0e10cSrcweir {
1527cdf0e10cSrcweir // --> OD 2009-08-28 #i102458#
1528cdf0e10cSrcweir // Correction:
1529cdf0e10cSrcweir // A proportional line spacing of the previous text frame
1530cdf0e10cSrcweir // is added up to a own leading line spacing.
1531cdf0e10cSrcweir // Otherwise, the maximum of the leading line spacing
1532cdf0e10cSrcweir // of the previous text frame and the own leading line
1533cdf0e10cSrcweir // spacing is built.
1534cdf0e10cSrcweir if ( bPrevLineSpacingPorportional )
1535cdf0e10cSrcweir {
1536cdf0e10cSrcweir nAdd += static_cast<SwTxtFrm&>(rThis).GetLineSpace( true );
1537cdf0e10cSrcweir }
1538cdf0e10cSrcweir else
1539cdf0e10cSrcweir {
1540cdf0e10cSrcweir nAdd = Max( nAdd, static_cast<SwTxtFrm&>(rThis).GetLineSpace( true ) );
1541cdf0e10cSrcweir }
1542cdf0e10cSrcweir // <--
1543cdf0e10cSrcweir }
1544cdf0e10cSrcweir nUpper += nAdd;
1545cdf0e10cSrcweir }
1546cdf0e10cSrcweir }
1547cdf0e10cSrcweir else
1548cdf0e10cSrcweir {
1549cdf0e10cSrcweir nUpper = Max( static_cast<long>(nPrevLowerSpace),
1550cdf0e10cSrcweir static_cast<long>(pAttrs->GetULSpace().GetUpper()) );
1551cdf0e10cSrcweir // OD 07.01.2004 #i11859# - consideration of the line spacing
1552cdf0e10cSrcweir // for the upper spacing of a text frame
1553cdf0e10cSrcweir if ( bUseFormerLineSpacing )
1554cdf0e10cSrcweir {
1555cdf0e10cSrcweir // former consideration
1556cdf0e10cSrcweir if ( pOwn->IsTxtFrm() )
1557cdf0e10cSrcweir nUpper = Max( nUpper, ((SwTxtFrm*)pOwn)->GetLineSpace() );
1558cdf0e10cSrcweir if ( nPrevLineSpacing != 0 )
1559cdf0e10cSrcweir {
1560cdf0e10cSrcweir nUpper = Max( nUpper, nPrevLineSpacing );
1561cdf0e10cSrcweir }
1562cdf0e10cSrcweir }
1563cdf0e10cSrcweir else
1564cdf0e10cSrcweir {
1565cdf0e10cSrcweir // new consideration:
1566cdf0e10cSrcweir // Only the proportional line spacing of the previous
1567cdf0e10cSrcweir // text frame is considered for the upper spacing and
1568cdf0e10cSrcweir // the line spacing values are add up and added to
1569cdf0e10cSrcweir // the paragraph spacing instead of building the
1570cdf0e10cSrcweir // maximum of the line spacings and the paragraph spacing.
1571cdf0e10cSrcweir SwTwips nAdd = nPrevLineSpacing;
1572cdf0e10cSrcweir if ( pOwn->IsTxtFrm() )
1573cdf0e10cSrcweir {
1574cdf0e10cSrcweir // --> OD 2009-08-28 #i102458#
1575cdf0e10cSrcweir // Correction:
1576cdf0e10cSrcweir // A proportional line spacing of the previous text frame
1577cdf0e10cSrcweir // is added up to a own leading line spacing.
1578cdf0e10cSrcweir // Otherwise, the maximum of the leading line spacing
1579cdf0e10cSrcweir // of the previous text frame and the own leading line
1580cdf0e10cSrcweir // spacing is built.
1581cdf0e10cSrcweir if ( bPrevLineSpacingPorportional )
1582cdf0e10cSrcweir {
1583cdf0e10cSrcweir nAdd += static_cast<SwTxtFrm&>(rThis).GetLineSpace( true );
1584cdf0e10cSrcweir }
1585cdf0e10cSrcweir else
1586cdf0e10cSrcweir {
1587cdf0e10cSrcweir nAdd = Max( nAdd, static_cast<SwTxtFrm&>(rThis).GetLineSpace( true ) );
1588cdf0e10cSrcweir }
1589cdf0e10cSrcweir // <--
1590cdf0e10cSrcweir }
1591cdf0e10cSrcweir nUpper += nAdd;
1592cdf0e10cSrcweir }
1593cdf0e10cSrcweir }
1594cdf0e10cSrcweir }
1595cdf0e10cSrcweir else if ( pIDSA->get(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES) &&
1596cdf0e10cSrcweir CastFlowFrm( pOwn )->HasParaSpaceAtPages( rThis.IsSctFrm() ) )
1597cdf0e10cSrcweir {
1598cdf0e10cSrcweir nUpper = pAttrs->GetULSpace().GetUpper();
1599cdf0e10cSrcweir }
1600cdf0e10cSrcweir }
1601cdf0e10cSrcweir
1602cdf0e10cSrcweir // OD 2004-02-26 #i25029# - pass previous frame <pPrevFrm>
1603cdf0e10cSrcweir // to method <GetTopLine(..)>, if parameter <pPr> is set.
1604cdf0e10cSrcweir // Note: parameter <pPr> is set, if method is called from <SwTxtFrm::WouldFit(..)>
1605cdf0e10cSrcweir nUpper += pAttrs->GetTopLine( rThis, (pPr ? pPrevFrm : 0L) );
1606cdf0e10cSrcweir
1607cdf0e10cSrcweir // OD 2004-03-12 #i11860# - consider value of new parameter <_bConsiderGrid>
1608cdf0e10cSrcweir // and use new method <GetUpperSpaceAmountConsideredForPageGrid(..)>
1609cdf0e10cSrcweir
1610cdf0e10cSrcweir //consider grid in square page mode
1611cdf0e10cSrcweir if ( _bConsiderGrid && rThis.GetUpper()->GetFmt()->GetDoc()->IsSquaredPageMode() )
1612cdf0e10cSrcweir {
1613cdf0e10cSrcweir nUpper += _GetUpperSpaceAmountConsideredForPageGrid( nUpper );
1614cdf0e10cSrcweir }
1615cdf0e10cSrcweir
1616cdf0e10cSrcweir delete pAccess;
1617cdf0e10cSrcweir return nUpper;
1618cdf0e10cSrcweir }
1619cdf0e10cSrcweir
1620cdf0e10cSrcweir /** method to detemine the upper space amount, which is considered for
1621cdf0e10cSrcweir the page grid
1622cdf0e10cSrcweir
1623cdf0e10cSrcweir OD 2004-03-12 #i11860#
1624cdf0e10cSrcweir Precondition: Position of frame is valid.
1625cdf0e10cSrcweir
1626cdf0e10cSrcweir @author OD
1627cdf0e10cSrcweir */
_GetUpperSpaceAmountConsideredForPageGrid(const SwTwips _nUpperSpaceWithoutGrid) const1628cdf0e10cSrcweir SwTwips SwFlowFrm::_GetUpperSpaceAmountConsideredForPageGrid(
1629cdf0e10cSrcweir const SwTwips _nUpperSpaceWithoutGrid ) const
1630cdf0e10cSrcweir {
1631cdf0e10cSrcweir SwTwips nUpperSpaceAmountConsideredForPageGrid = 0;
1632cdf0e10cSrcweir
1633cdf0e10cSrcweir if ( rThis.IsInDocBody() && rThis.GetAttrSet()->GetParaGrid().GetValue() )
1634cdf0e10cSrcweir {
1635cdf0e10cSrcweir const SwPageFrm* pPageFrm = rThis.FindPageFrm();
1636cdf0e10cSrcweir GETGRID( pPageFrm )
1637cdf0e10cSrcweir if( pGrid )
1638cdf0e10cSrcweir {
1639cdf0e10cSrcweir const SwFrm* pBodyFrm = pPageFrm->FindBodyCont();
1640cdf0e10cSrcweir if ( pBodyFrm )
1641cdf0e10cSrcweir {
1642cdf0e10cSrcweir const long nGridLineHeight =
1643cdf0e10cSrcweir pGrid->GetBaseHeight() + pGrid->GetRubyHeight();
1644cdf0e10cSrcweir
1645cdf0e10cSrcweir SWRECTFN( (&rThis) )
1646cdf0e10cSrcweir const SwTwips nBodyPrtTop = (pBodyFrm->*fnRect->fnGetPrtTop)();
1647cdf0e10cSrcweir const SwTwips nProposedPrtTop =
1648cdf0e10cSrcweir (*fnRect->fnYInc)( (rThis.Frm().*fnRect->fnGetTop)(),
1649cdf0e10cSrcweir _nUpperSpaceWithoutGrid );
1650cdf0e10cSrcweir
1651cdf0e10cSrcweir const SwTwips nSpaceAbovePrtTop =
1652cdf0e10cSrcweir (*fnRect->fnYDiff)( nProposedPrtTop, nBodyPrtTop );
1653cdf0e10cSrcweir const SwTwips nSpaceOfCompleteLinesAbove =
1654cdf0e10cSrcweir nGridLineHeight * ( nSpaceAbovePrtTop / nGridLineHeight );
1655cdf0e10cSrcweir SwTwips nNewPrtTop =
1656cdf0e10cSrcweir (*fnRect->fnYInc)( nBodyPrtTop, nSpaceOfCompleteLinesAbove );
1657cdf0e10cSrcweir if ( (*fnRect->fnYDiff)( nProposedPrtTop, nNewPrtTop ) > 0 )
1658cdf0e10cSrcweir {
1659cdf0e10cSrcweir nNewPrtTop = (*fnRect->fnYInc)( nNewPrtTop, nGridLineHeight );
1660cdf0e10cSrcweir }
1661cdf0e10cSrcweir
1662cdf0e10cSrcweir const SwTwips nNewUpperSpace =
1663cdf0e10cSrcweir (*fnRect->fnYDiff)( nNewPrtTop,
1664cdf0e10cSrcweir (rThis.Frm().*fnRect->fnGetTop)() );
1665cdf0e10cSrcweir
1666cdf0e10cSrcweir nUpperSpaceAmountConsideredForPageGrid =
1667cdf0e10cSrcweir nNewUpperSpace - _nUpperSpaceWithoutGrid;
1668cdf0e10cSrcweir
1669cdf0e10cSrcweir ASSERT( nUpperSpaceAmountConsideredForPageGrid >= 0,
1670cdf0e10cSrcweir "<SwFlowFrm::GetUpperSpaceAmountConsideredForPageGrid(..)> - negative space considered for page grid!" );
1671cdf0e10cSrcweir }
1672cdf0e10cSrcweir }
1673cdf0e10cSrcweir }
1674cdf0e10cSrcweir return nUpperSpaceAmountConsideredForPageGrid;
1675cdf0e10cSrcweir }
1676cdf0e10cSrcweir
1677cdf0e10cSrcweir /** method to determent the upper space amount, which is considered for
1678cdf0e10cSrcweir the previous frame
1679cdf0e10cSrcweir
1680cdf0e10cSrcweir OD 2004-03-11 #i11860#
1681cdf0e10cSrcweir
1682cdf0e10cSrcweir @author OD
1683cdf0e10cSrcweir */
_GetUpperSpaceAmountConsideredForPrevFrm() const1684cdf0e10cSrcweir SwTwips SwFlowFrm::_GetUpperSpaceAmountConsideredForPrevFrm() const
1685cdf0e10cSrcweir {
1686cdf0e10cSrcweir SwTwips nUpperSpaceAmountOfPrevFrm = 0;
1687cdf0e10cSrcweir
1688cdf0e10cSrcweir const SwFrm* pPrevFrm = _GetPrevFrmForUpperSpaceCalc();
1689cdf0e10cSrcweir if ( pPrevFrm )
1690cdf0e10cSrcweir {
1691cdf0e10cSrcweir SwTwips nPrevLowerSpace = 0;
1692cdf0e10cSrcweir SwTwips nPrevLineSpacing = 0;
1693cdf0e10cSrcweir // --> OD 2009-08-28 #i102458#
1694cdf0e10cSrcweir bool bDummy = false;
1695cdf0e10cSrcweir GetSpacingValuesOfFrm( (*pPrevFrm), nPrevLowerSpace, nPrevLineSpacing, bDummy );
1696cdf0e10cSrcweir // <--
1697cdf0e10cSrcweir if ( nPrevLowerSpace > 0 || nPrevLineSpacing > 0 )
1698cdf0e10cSrcweir {
1699cdf0e10cSrcweir const IDocumentSettingAccess* pIDSA = rThis.GetUpper()->GetFmt()->getIDocumentSettingAccess();
1700cdf0e10cSrcweir if ( pIDSA->get(IDocumentSettingAccess::PARA_SPACE_MAX) ||
1701cdf0e10cSrcweir !pIDSA->get(IDocumentSettingAccess::OLD_LINE_SPACING) )
1702cdf0e10cSrcweir {
1703cdf0e10cSrcweir nUpperSpaceAmountOfPrevFrm = nPrevLowerSpace + nPrevLineSpacing;
1704cdf0e10cSrcweir }
1705cdf0e10cSrcweir else
1706cdf0e10cSrcweir {
1707cdf0e10cSrcweir nUpperSpaceAmountOfPrevFrm = Max( nPrevLowerSpace, nPrevLineSpacing );
1708cdf0e10cSrcweir }
1709cdf0e10cSrcweir }
1710cdf0e10cSrcweir }
1711cdf0e10cSrcweir
1712cdf0e10cSrcweir return nUpperSpaceAmountOfPrevFrm;
1713cdf0e10cSrcweir }
1714cdf0e10cSrcweir
1715cdf0e10cSrcweir /** method to determine the upper space amount, which is considered for
1716cdf0e10cSrcweir the previous frame and the page grid, if option 'Use former object
1717cdf0e10cSrcweir positioning' is OFF
1718cdf0e10cSrcweir
1719cdf0e10cSrcweir OD 2004-03-18 #i11860#
1720cdf0e10cSrcweir
1721cdf0e10cSrcweir @author OD
1722cdf0e10cSrcweir */
GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() const1723cdf0e10cSrcweir SwTwips SwFlowFrm::GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() const
1724cdf0e10cSrcweir {
1725cdf0e10cSrcweir SwTwips nUpperSpaceAmountConsideredForPrevFrmAndPageGrid = 0;
1726cdf0e10cSrcweir
1727cdf0e10cSrcweir if ( !rThis.GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::USE_FORMER_OBJECT_POS) )
1728cdf0e10cSrcweir {
1729cdf0e10cSrcweir nUpperSpaceAmountConsideredForPrevFrmAndPageGrid =
1730cdf0e10cSrcweir _GetUpperSpaceAmountConsideredForPrevFrm() +
1731*7a3ba306SOliver-Rainer Wittmann ( rThis.GetUpper()->GetFmt()->GetDoc()->IsSquaredPageMode()
1732*7a3ba306SOliver-Rainer Wittmann ? _GetUpperSpaceAmountConsideredForPageGrid( CalcUpperSpace( 0, 0, false ) )
1733*7a3ba306SOliver-Rainer Wittmann : 0 );
1734cdf0e10cSrcweir }
1735cdf0e10cSrcweir
1736cdf0e10cSrcweir return nUpperSpaceAmountConsideredForPrevFrmAndPageGrid;
1737cdf0e10cSrcweir }
1738cdf0e10cSrcweir
1739cdf0e10cSrcweir /** calculation of lower space
1740cdf0e10cSrcweir
1741cdf0e10cSrcweir OD 2004-03-02 #106629#
1742cdf0e10cSrcweir
1743cdf0e10cSrcweir @author OD
1744cdf0e10cSrcweir */
CalcLowerSpace(const SwBorderAttrs * _pAttrs) const1745cdf0e10cSrcweir SwTwips SwFlowFrm::CalcLowerSpace( const SwBorderAttrs* _pAttrs ) const
1746cdf0e10cSrcweir {
1747cdf0e10cSrcweir SwTwips nLowerSpace = 0;
1748cdf0e10cSrcweir
1749cdf0e10cSrcweir SwBorderAttrAccess* pAttrAccess = 0L;
1750cdf0e10cSrcweir if ( !_pAttrs )
1751cdf0e10cSrcweir {
1752cdf0e10cSrcweir pAttrAccess = new SwBorderAttrAccess( SwFrm::GetCache(), &rThis );
1753cdf0e10cSrcweir _pAttrs = pAttrAccess->Get();
1754cdf0e10cSrcweir }
1755cdf0e10cSrcweir
1756cdf0e10cSrcweir sal_Bool bCommonBorder = sal_True;
1757cdf0e10cSrcweir if ( rThis.IsInSct() && rThis.GetUpper()->IsColBodyFrm() )
1758cdf0e10cSrcweir {
1759cdf0e10cSrcweir const SwSectionFrm* pSectFrm = rThis.FindSctFrm();
1760cdf0e10cSrcweir bCommonBorder = pSectFrm->GetFmt()->GetBalancedColumns().GetValue();
1761cdf0e10cSrcweir }
1762cdf0e10cSrcweir nLowerSpace = bCommonBorder ?
1763cdf0e10cSrcweir _pAttrs->GetBottomLine( rThis ) :
1764cdf0e10cSrcweir _pAttrs->CalcBottomLine();
1765cdf0e10cSrcweir
1766cdf0e10cSrcweir // --> OD 2004-07-16 #i26250#
1767cdf0e10cSrcweir // - correct consideration of table frames
1768cdf0e10cSrcweir // - use new method <CalcAddLowerSpaceAsLastInTableCell(..)>
1769cdf0e10cSrcweir if ( ( ( rThis.IsTabFrm() && rThis.GetUpper()->IsInTab() ) ||
1770cdf0e10cSrcweir // --> OD 2004-11-16 #115759# - no lower spacing, if frame has a follow
1771cdf0e10cSrcweir ( rThis.IsInTab() && !GetFollow() ) ) &&
1772cdf0e10cSrcweir // <--
1773cdf0e10cSrcweir !rThis.GetIndNext() )
1774cdf0e10cSrcweir {
1775cdf0e10cSrcweir nLowerSpace += CalcAddLowerSpaceAsLastInTableCell( _pAttrs );
1776cdf0e10cSrcweir }
1777cdf0e10cSrcweir // <--
1778cdf0e10cSrcweir
1779cdf0e10cSrcweir delete pAttrAccess;
1780cdf0e10cSrcweir
1781cdf0e10cSrcweir return nLowerSpace;
1782cdf0e10cSrcweir }
1783cdf0e10cSrcweir
1784cdf0e10cSrcweir /** calculation of the additional space to be considered, if flow frame
1785cdf0e10cSrcweir is the last inside a table cell
1786cdf0e10cSrcweir
1787cdf0e10cSrcweir OD 2004-07-16 #i26250#
1788cdf0e10cSrcweir
1789cdf0e10cSrcweir @author OD
1790cdf0e10cSrcweir */
CalcAddLowerSpaceAsLastInTableCell(const SwBorderAttrs * _pAttrs) const1791cdf0e10cSrcweir SwTwips SwFlowFrm::CalcAddLowerSpaceAsLastInTableCell(
1792cdf0e10cSrcweir const SwBorderAttrs* _pAttrs ) const
1793cdf0e10cSrcweir {
1794cdf0e10cSrcweir SwTwips nAdditionalLowerSpace = 0;
1795cdf0e10cSrcweir
1796cdf0e10cSrcweir if ( rThis.GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS) )
1797cdf0e10cSrcweir {
1798cdf0e10cSrcweir const SwFrm* pFrm = &rThis;
1799cdf0e10cSrcweir if ( pFrm->IsSctFrm() )
1800cdf0e10cSrcweir {
1801cdf0e10cSrcweir const SwSectionFrm* pSectFrm = static_cast<const SwSectionFrm*>(pFrm);
1802cdf0e10cSrcweir pFrm = pSectFrm->FindLastCntnt();
1803cdf0e10cSrcweir if ( pFrm && pFrm->IsInTab() )
1804cdf0e10cSrcweir {
1805cdf0e10cSrcweir const SwTabFrm* pTableFrm = pFrm->FindTabFrm();
1806cdf0e10cSrcweir if ( pSectFrm->IsAnLower( pTableFrm ) )
1807cdf0e10cSrcweir {
1808cdf0e10cSrcweir pFrm = pTableFrm;
1809cdf0e10cSrcweir }
1810cdf0e10cSrcweir }
1811cdf0e10cSrcweir }
1812cdf0e10cSrcweir
1813cdf0e10cSrcweir SwBorderAttrAccess* pAttrAccess = 0L;
1814cdf0e10cSrcweir if ( !_pAttrs || pFrm != &rThis )
1815cdf0e10cSrcweir {
1816cdf0e10cSrcweir pAttrAccess = new SwBorderAttrAccess( SwFrm::GetCache(), pFrm );
1817cdf0e10cSrcweir _pAttrs = pAttrAccess->Get();
1818cdf0e10cSrcweir }
1819cdf0e10cSrcweir
1820cdf0e10cSrcweir nAdditionalLowerSpace += _pAttrs->GetULSpace().GetLower();
1821cdf0e10cSrcweir
1822cdf0e10cSrcweir delete pAttrAccess;
1823cdf0e10cSrcweir }
1824cdf0e10cSrcweir
1825cdf0e10cSrcweir return nAdditionalLowerSpace;
1826cdf0e10cSrcweir }
1827cdf0e10cSrcweir
1828cdf0e10cSrcweir /*************************************************************************
1829cdf0e10cSrcweir |*
1830cdf0e10cSrcweir |* sal_Bool SwFlowFrm::CheckMoveFwd()
1831cdf0e10cSrcweir |*
1832cdf0e10cSrcweir |* Beschreibung Moved den Frm vorwaerts wenn es durch die aktuellen
1833cdf0e10cSrcweir |* Bedingungen und Attribute notwendig erscheint.
1834cdf0e10cSrcweir |* Ersterstellung MA 05. Dec. 96
1835cdf0e10cSrcweir |* Letzte Aenderung MA 09. Mar. 98
1836cdf0e10cSrcweir |*
1837cdf0e10cSrcweir |*************************************************************************/
1838cdf0e10cSrcweir
1839cdf0e10cSrcweir
CheckMoveFwd(sal_Bool & rbMakePage,sal_Bool bKeep,sal_Bool)1840cdf0e10cSrcweir sal_Bool SwFlowFrm::CheckMoveFwd( sal_Bool &rbMakePage, sal_Bool bKeep, sal_Bool )
1841cdf0e10cSrcweir {
1842cdf0e10cSrcweir const SwFrm* pNxt = rThis.GetIndNext();
1843cdf0e10cSrcweir
1844cdf0e10cSrcweir if ( bKeep && //!bMovedBwd &&
1845cdf0e10cSrcweir ( !pNxt || ( pNxt->IsTxtFrm() && ((SwTxtFrm*)pNxt)->IsEmptyMaster() ) ) &&
1846cdf0e10cSrcweir ( 0 != (pNxt = rThis.FindNext()) ) && IsKeepFwdMoveAllowed() )
1847cdf0e10cSrcweir {
1848cdf0e10cSrcweir if( pNxt->IsSctFrm() )
1849cdf0e10cSrcweir { // Nicht auf leere SectionFrms hereinfallen
1850cdf0e10cSrcweir const SwFrm* pTmp = NULL;
1851cdf0e10cSrcweir while( pNxt && pNxt->IsSctFrm() &&
1852cdf0e10cSrcweir ( !((SwSectionFrm*)pNxt)->GetSection() ||
1853cdf0e10cSrcweir 0 == ( pTmp = ((SwSectionFrm*)pNxt)->ContainsAny() ) ) )
1854cdf0e10cSrcweir {
1855cdf0e10cSrcweir pNxt = pNxt->FindNext();
1856cdf0e10cSrcweir pTmp = NULL;
1857cdf0e10cSrcweir }
1858cdf0e10cSrcweir if( pTmp )
1859cdf0e10cSrcweir pNxt = pTmp; // the content of the next notempty sectionfrm
1860cdf0e10cSrcweir }
1861cdf0e10cSrcweir if( pNxt && pNxt->GetValidPosFlag() )
1862cdf0e10cSrcweir {
1863cdf0e10cSrcweir sal_Bool bMove = sal_False;
1864cdf0e10cSrcweir const SwSectionFrm *pSct = rThis.FindSctFrm();
1865cdf0e10cSrcweir if( pSct && !pSct->GetValidSizeFlag() )
1866cdf0e10cSrcweir {
1867cdf0e10cSrcweir const SwSectionFrm* pNxtSct = pNxt->FindSctFrm();
1868cdf0e10cSrcweir if( pNxtSct && pSct->IsAnFollow( pNxtSct ) )
1869cdf0e10cSrcweir bMove = sal_True;
1870cdf0e10cSrcweir }
1871cdf0e10cSrcweir else
1872cdf0e10cSrcweir bMove = sal_True;
1873cdf0e10cSrcweir if( bMove )
1874cdf0e10cSrcweir {
1875cdf0e10cSrcweir //Keep together with the following frame
1876cdf0e10cSrcweir MoveFwd( rbMakePage, sal_False );
1877cdf0e10cSrcweir return sal_True;
1878cdf0e10cSrcweir }
1879cdf0e10cSrcweir }
1880cdf0e10cSrcweir }
1881cdf0e10cSrcweir
1882cdf0e10cSrcweir sal_Bool bMovedFwd = sal_False;
1883cdf0e10cSrcweir
1884cdf0e10cSrcweir if ( rThis.GetIndPrev() )
1885cdf0e10cSrcweir {
1886cdf0e10cSrcweir if ( IsPrevObjMove() ) //Auf Objekte des Prev Ruecksicht nehmen?
1887cdf0e10cSrcweir {
1888cdf0e10cSrcweir bMovedFwd = sal_True;
1889cdf0e10cSrcweir if ( !MoveFwd( rbMakePage, sal_False ) )
1890cdf0e10cSrcweir rbMakePage = sal_False;
1891cdf0e10cSrcweir }
1892cdf0e10cSrcweir else
1893cdf0e10cSrcweir {
1894cdf0e10cSrcweir if ( IsPageBreak( sal_False ) )
1895cdf0e10cSrcweir {
1896cdf0e10cSrcweir while ( MoveFwd( rbMakePage, sal_True ) )
1897cdf0e10cSrcweir /* do nothing */;
1898cdf0e10cSrcweir rbMakePage = sal_False;
1899cdf0e10cSrcweir bMovedFwd = sal_True;
1900cdf0e10cSrcweir }
1901cdf0e10cSrcweir else if ( IsColBreak ( sal_False ) )
1902cdf0e10cSrcweir {
1903cdf0e10cSrcweir const SwPageFrm *pPage = rThis.FindPageFrm();
1904cdf0e10cSrcweir SwFrm *pCol = rThis.FindColFrm();
1905cdf0e10cSrcweir do
1906cdf0e10cSrcweir { MoveFwd( rbMakePage, sal_False );
1907cdf0e10cSrcweir SwFrm *pTmp = rThis.FindColFrm();
1908cdf0e10cSrcweir if( pTmp != pCol )
1909cdf0e10cSrcweir {
1910cdf0e10cSrcweir bMovedFwd = sal_True;
1911cdf0e10cSrcweir pCol = pTmp;
1912cdf0e10cSrcweir }
1913cdf0e10cSrcweir else
1914cdf0e10cSrcweir break;
1915cdf0e10cSrcweir } while ( IsColBreak( sal_False ) );
1916cdf0e10cSrcweir if ( pPage != rThis.FindPageFrm() )
1917cdf0e10cSrcweir rbMakePage = sal_False;
1918cdf0e10cSrcweir }
1919cdf0e10cSrcweir }
1920cdf0e10cSrcweir }
1921cdf0e10cSrcweir return bMovedFwd;
1922cdf0e10cSrcweir }
1923cdf0e10cSrcweir
1924cdf0e10cSrcweir /*************************************************************************
1925cdf0e10cSrcweir |*
1926cdf0e10cSrcweir |* sal_Bool SwFlowFrm::MoveFwd()
1927cdf0e10cSrcweir |*
1928cdf0e10cSrcweir |* Beschreibung Returnwert sagt, ob der Frm die Seite gewechselt hat.
1929cdf0e10cSrcweir |* Ersterstellung MA 05. Dec. 96
1930cdf0e10cSrcweir |* Letzte Aenderung MA 05. Dec. 96
1931cdf0e10cSrcweir |*
1932cdf0e10cSrcweir |*************************************************************************/
1933cdf0e10cSrcweir
1934cdf0e10cSrcweir
MoveFwd(sal_Bool bMakePage,sal_Bool bPageBreak,sal_Bool bMoveAlways)1935cdf0e10cSrcweir sal_Bool SwFlowFrm::MoveFwd( sal_Bool bMakePage, sal_Bool bPageBreak, sal_Bool bMoveAlways )
1936cdf0e10cSrcweir {
1937cdf0e10cSrcweir //!!!!MoveFtnCntFwd muss ggf. mitgepflegt werden.
1938cdf0e10cSrcweir SwFtnBossFrm *pOldBoss = rThis.FindFtnBossFrm();
1939cdf0e10cSrcweir if ( rThis.IsInFtn() )
1940cdf0e10cSrcweir return ((SwCntntFrm&)rThis).MoveFtnCntFwd( bMakePage, pOldBoss );
1941cdf0e10cSrcweir
1942cdf0e10cSrcweir if( !IsFwdMoveAllowed() && !bMoveAlways )
1943cdf0e10cSrcweir {
1944cdf0e10cSrcweir sal_Bool bNoFwd = sal_True;
1945cdf0e10cSrcweir if( rThis.IsInSct() )
1946cdf0e10cSrcweir {
1947cdf0e10cSrcweir SwFtnBossFrm* pBoss = rThis.FindFtnBossFrm();
1948cdf0e10cSrcweir bNoFwd = !pBoss->IsInSct() || ( !pBoss->Lower()->GetNext() &&
1949cdf0e10cSrcweir !pBoss->GetPrev() );
1950cdf0e10cSrcweir }
1951cdf0e10cSrcweir
1952cdf0e10cSrcweir // Allow the MoveFwd even if we do not have an IndPrev in these cases:
1953cdf0e10cSrcweir if ( rThis.IsInTab() &&
1954cdf0e10cSrcweir ( !rThis.IsTabFrm() ||
1955cdf0e10cSrcweir ( rThis.GetUpper()->IsInTab() &&
1956cdf0e10cSrcweir rThis.GetUpper()->FindTabFrm()->IsFwdMoveAllowed() ) ) &&
1957cdf0e10cSrcweir 0 != const_cast<SwFrm&>(rThis).GetNextCellLeaf( MAKEPAGE_NONE ) )
1958cdf0e10cSrcweir /*
1959cdf0e10cSrcweir &&
1960cdf0e10cSrcweir // NEW TABLES
1961cdf0e10cSrcweir // Have a look at our main competitor: We don't move inside row span cells:
1962cdf0e10cSrcweir ( !rThis.GetUpper()->IsCellFrm() || !rThis.GetUpper()->IsLeaveUpperAllowed() ) )*/
1963cdf0e10cSrcweir {
1964cdf0e10cSrcweir bNoFwd = sal_False;
1965cdf0e10cSrcweir }
1966cdf0e10cSrcweir
1967cdf0e10cSrcweir if( bNoFwd )
1968cdf0e10cSrcweir {
1969cdf0e10cSrcweir //Fuer PageBreak ist das Moven erlaubt, wenn der Frm nicht
1970cdf0e10cSrcweir //bereits der erste der Seite ist.
1971cdf0e10cSrcweir if ( !bPageBreak )
1972cdf0e10cSrcweir return sal_False;
1973cdf0e10cSrcweir
1974cdf0e10cSrcweir const SwFrm *pCol = rThis.FindColFrm();
1975cdf0e10cSrcweir if ( !pCol || !pCol->GetPrev() )
1976cdf0e10cSrcweir return sal_False;
1977cdf0e10cSrcweir }
1978cdf0e10cSrcweir }
1979cdf0e10cSrcweir
1980cdf0e10cSrcweir sal_Bool bSamePage = sal_True;
1981cdf0e10cSrcweir SwLayoutFrm *pNewUpper =
1982cdf0e10cSrcweir rThis.GetLeaf( bMakePage ? MAKEPAGE_INSERT : MAKEPAGE_NONE, sal_True );
1983cdf0e10cSrcweir
1984cdf0e10cSrcweir if ( pNewUpper )
1985cdf0e10cSrcweir {
1986cdf0e10cSrcweir PROTOCOL_ENTER( &rThis, PROT_MOVE_FWD, 0, 0 );
1987cdf0e10cSrcweir SwPageFrm *pOldPage = pOldBoss->FindPageFrm();
1988cdf0e10cSrcweir //Wir moven uns und alle direkten Nachfolger vor den ersten
1989cdf0e10cSrcweir //CntntFrm unterhalb des neuen Uppers.
1990cdf0e10cSrcweir
1991cdf0e10cSrcweir // Wenn unser NewUpper in einem SectionFrm liegt, muessen wir
1992cdf0e10cSrcweir // verhindern, dass sich dieser im Calc selbst zerstoert
1993cdf0e10cSrcweir SwSectionFrm* pSect = pNewUpper->FindSctFrm();
1994cdf0e10cSrcweir sal_Bool bUnlock = sal_False;
1995cdf0e10cSrcweir if( pSect )
1996cdf0e10cSrcweir {
1997cdf0e10cSrcweir // Wenn wir nur innerhalb unseres SectionFrms die Spalte wechseln,
1998cdf0e10cSrcweir // rufen wir lieber kein Calc, sonst wird noch der SectionFrm
1999cdf0e10cSrcweir // formatiert, der wiederum uns ruft etc.
2000cdf0e10cSrcweir if( pSect != rThis.FindSctFrm() )
2001cdf0e10cSrcweir {
2002cdf0e10cSrcweir bUnlock = !pSect->IsColLocked();
2003cdf0e10cSrcweir pSect->ColLock();
2004cdf0e10cSrcweir pNewUpper->Calc();
2005cdf0e10cSrcweir if( bUnlock )
2006cdf0e10cSrcweir pSect->ColUnlock();
2007cdf0e10cSrcweir }
2008cdf0e10cSrcweir }
2009cdf0e10cSrcweir // Do not calculate split cell frames.
2010cdf0e10cSrcweir else if ( !pNewUpper->IsCellFrm() || ((SwLayoutFrm*)pNewUpper)->Lower() )
2011cdf0e10cSrcweir pNewUpper->Calc();
2012cdf0e10cSrcweir
2013cdf0e10cSrcweir SwFtnBossFrm *pNewBoss = pNewUpper->FindFtnBossFrm();
2014cdf0e10cSrcweir sal_Bool bBossChg = pNewBoss != pOldBoss;
2015cdf0e10cSrcweir pNewBoss = pNewBoss->FindFtnBossFrm( sal_True );
2016cdf0e10cSrcweir pOldBoss = pOldBoss->FindFtnBossFrm( sal_True );
2017cdf0e10cSrcweir SwPageFrm* pNewPage = pOldPage;
2018cdf0e10cSrcweir
2019cdf0e10cSrcweir // First, we move the footnotes.
2020cdf0e10cSrcweir sal_Bool bFtnMoved = sal_False;
2021cdf0e10cSrcweir
2022cdf0e10cSrcweir // --> FME 2004-07-15 #i26831#
2023cdf0e10cSrcweir // If pSect has just been created, the printing area of pSect has
2024cdf0e10cSrcweir // been calculated based on the first content of its follow.
2025cdf0e10cSrcweir // In this case we prefer to call a SimpleFormat for this new
2026cdf0e10cSrcweir // section after we inserted the contents. Otherwise the section
2027cdf0e10cSrcweir // frame will invalidate its lowers, if its printing area changes
2028cdf0e10cSrcweir // in SwSectionFrm::Format, which can cause loops.
2029cdf0e10cSrcweir const bool bForceSimpleFormat = pSect && pSect->HasFollow() &&
2030cdf0e10cSrcweir !pSect->ContainsAny();
2031cdf0e10cSrcweir // <--
2032cdf0e10cSrcweir
2033cdf0e10cSrcweir if ( pNewBoss != pOldBoss )
2034cdf0e10cSrcweir {
2035cdf0e10cSrcweir pNewPage = pNewBoss->FindPageFrm();
2036cdf0e10cSrcweir bSamePage = pNewPage == pOldPage;
2037cdf0e10cSrcweir //Damit die Fussnoten nicht auf dumme Gedanken kommen
2038cdf0e10cSrcweir //setzen wir hier die Deadline.
2039cdf0e10cSrcweir SWRECTFN( pOldBoss )
2040cdf0e10cSrcweir SwSaveFtnHeight aHeight( pOldBoss,
2041cdf0e10cSrcweir (pOldBoss->Frm().*fnRect->fnGetBottom)() );
2042cdf0e10cSrcweir SwCntntFrm* pStart = rThis.IsCntntFrm() ?
2043cdf0e10cSrcweir (SwCntntFrm*)&rThis : ((SwLayoutFrm&)rThis).ContainsCntnt();
2044cdf0e10cSrcweir ASSERT( pStart || ( rThis.IsTabFrm() && !((SwTabFrm&)rThis).Lower() ),
2045cdf0e10cSrcweir "MoveFwd: Missing Content" );
2046cdf0e10cSrcweir SwLayoutFrm* pBody = pStart ? ( pStart->IsTxtFrm() ?
2047cdf0e10cSrcweir (SwLayoutFrm*)((SwTxtFrm*)pStart)->FindBodyFrm() : 0 ) : 0;
2048cdf0e10cSrcweir if( pBody )
2049cdf0e10cSrcweir bFtnMoved = pBody->MoveLowerFtns( pStart, pOldBoss, pNewBoss,
2050cdf0e10cSrcweir sal_False);
2051cdf0e10cSrcweir }
2052cdf0e10cSrcweir // Bei SectionFrms ist es moeglich, dass wir selbst durch pNewUpper->Calc()
2053cdf0e10cSrcweir // bewegt wurden, z. B. in den pNewUpper.
2054cdf0e10cSrcweir // MoveSubTree bzw. PasteTree ist auf so etwas nicht vorbereitet.
2055cdf0e10cSrcweir if( pNewUpper != rThis.GetUpper() )
2056cdf0e10cSrcweir {
2057cdf0e10cSrcweir // --> FME 2004-04-19 #i27145#
2058cdf0e10cSrcweir SwSectionFrm* pOldSct = 0;
2059cdf0e10cSrcweir if ( rThis.GetUpper()->IsSctFrm() )
2060cdf0e10cSrcweir {
2061cdf0e10cSrcweir pOldSct = static_cast<SwSectionFrm*>(rThis.GetUpper());
2062cdf0e10cSrcweir }
2063cdf0e10cSrcweir // <--
2064cdf0e10cSrcweir
2065cdf0e10cSrcweir MoveSubTree( pNewUpper, pNewUpper->Lower() );
2066cdf0e10cSrcweir
2067cdf0e10cSrcweir // --> FME 2004-04-19 #i27145#
2068cdf0e10cSrcweir if ( pOldSct && pOldSct->GetSection() )
2069cdf0e10cSrcweir {
2070cdf0e10cSrcweir // Prevent loops by setting the new height at
2071cdf0e10cSrcweir // the section frame if footnotes have been moved.
2072cdf0e10cSrcweir // Otherwise the call of SwLayNotify::~SwLayNotify() for
2073cdf0e10cSrcweir // the (invalid) section frame will invalidate the first
2074cdf0e10cSrcweir // lower of its follow, because it grows due to the removed
2075cdf0e10cSrcweir // footnotes.
2076cdf0e10cSrcweir // Note: If pOldSct has become empty during MoveSubTree, it
2077cdf0e10cSrcweir // has already been scheduled for removal. No SimpleFormat
2078cdf0e10cSrcweir // for these.
2079cdf0e10cSrcweir pOldSct->SimpleFormat();
2080cdf0e10cSrcweir }
2081cdf0e10cSrcweir // <--
2082cdf0e10cSrcweir
2083cdf0e10cSrcweir // --> FME 2004-07-15 #i26831#
2084cdf0e10cSrcweir if ( bForceSimpleFormat )
2085cdf0e10cSrcweir {
2086cdf0e10cSrcweir pSect->SimpleFormat();
2087cdf0e10cSrcweir }
2088cdf0e10cSrcweir // <--
2089cdf0e10cSrcweir
2090cdf0e10cSrcweir if ( bFtnMoved && !bSamePage )
2091cdf0e10cSrcweir {
2092cdf0e10cSrcweir pOldPage->UpdateFtnNum();
2093cdf0e10cSrcweir pNewPage->UpdateFtnNum();
2094cdf0e10cSrcweir }
2095cdf0e10cSrcweir
2096cdf0e10cSrcweir if( bBossChg )
2097cdf0e10cSrcweir {
2098cdf0e10cSrcweir rThis.Prepare( PREP_BOSS_CHGD, 0, sal_False );
2099cdf0e10cSrcweir if( !bSamePage )
2100cdf0e10cSrcweir {
2101cdf0e10cSrcweir ViewShell *pSh = rThis.getRootFrm()->GetCurrShell();
2102cdf0e10cSrcweir if ( pSh && !pSh->Imp()->IsUpdateExpFlds() )
2103cdf0e10cSrcweir pSh->GetDoc()->SetNewFldLst(true); //Wird von CalcLayout() hinterher erledigt!
2104cdf0e10cSrcweir
2105cdf0e10cSrcweir pNewPage->InvalidateSpelling();
2106cdf0e10cSrcweir pNewPage->InvalidateSmartTags(); // SMARTTAGS
2107cdf0e10cSrcweir pNewPage->InvalidateAutoCompleteWords();
2108cdf0e10cSrcweir pNewPage->InvalidateWordCount();
2109cdf0e10cSrcweir }
2110cdf0e10cSrcweir }
2111cdf0e10cSrcweir }
2112cdf0e10cSrcweir // OD 30.10.2002 #97265# - no <CheckPageDesc(..)> in online layout
2113cdf0e10cSrcweir const ViewShell *pSh = rThis.getRootFrm()->GetCurrShell();
2114cdf0e10cSrcweir
2115cdf0e10cSrcweir if ( !( pSh && pSh->GetViewOptions()->getBrowseMode() ) )
2116cdf0e10cSrcweir {
2117cdf0e10cSrcweir // --> OD 2009-12-31 #i106452#
2118cdf0e10cSrcweir // check page description not only in situation with sections.
2119cdf0e10cSrcweir if ( !bSamePage &&
2120cdf0e10cSrcweir ( rThis.GetAttrSet()->GetPageDesc().GetPageDesc() ||
2121cdf0e10cSrcweir pOldPage->GetPageDesc()->GetFollow() != pNewPage->GetPageDesc() ) )
2122cdf0e10cSrcweir {
2123cdf0e10cSrcweir SwFrm::CheckPageDescs( pNewPage, sal_False );
2124cdf0e10cSrcweir }
2125cdf0e10cSrcweir // <--
2126cdf0e10cSrcweir }
2127cdf0e10cSrcweir }
2128cdf0e10cSrcweir return bSamePage;
2129cdf0e10cSrcweir }
2130cdf0e10cSrcweir
2131cdf0e10cSrcweir
2132cdf0e10cSrcweir /*************************************************************************
2133cdf0e10cSrcweir |*
2134cdf0e10cSrcweir |* sal_Bool SwFlowFrm::MoveBwd()
2135cdf0e10cSrcweir |*
2136cdf0e10cSrcweir |* Beschreibung Returnwert sagt, ob der Frm die Seite wechseln soll.
2137cdf0e10cSrcweir |* Sollte von abgeleiteten Klassen gerufen werden.
2138cdf0e10cSrcweir |* Das moven selbst muessen die abgeleiteten uebernehmen.
2139cdf0e10cSrcweir |* Ersterstellung MA 05. Dec. 96
2140cdf0e10cSrcweir |* Letzte Aenderung MA 05. Dec. 96
2141cdf0e10cSrcweir |*
2142cdf0e10cSrcweir |*************************************************************************/
2143cdf0e10cSrcweir
MoveBwd(sal_Bool & rbReformat)2144cdf0e10cSrcweir sal_Bool SwFlowFrm::MoveBwd( sal_Bool &rbReformat )
2145cdf0e10cSrcweir {
2146cdf0e10cSrcweir SwFlowFrm::SetMoveBwdJump( sal_False );
2147cdf0e10cSrcweir
2148cdf0e10cSrcweir SwFtnFrm* pFtn = rThis.FindFtnFrm();
2149cdf0e10cSrcweir if ( pFtn && pFtn->IsBackMoveLocked() )
2150cdf0e10cSrcweir return sal_False;
2151cdf0e10cSrcweir
2152cdf0e10cSrcweir // --> OD 2004-11-29 #115759# - text frames, which are directly inside
2153cdf0e10cSrcweir // tables aren't allowed to move backward.
2154cdf0e10cSrcweir if ( rThis.IsTxtFrm() && rThis.IsInTab() )
2155cdf0e10cSrcweir {
2156cdf0e10cSrcweir const SwLayoutFrm* pUpperFrm = rThis.GetUpper();
2157cdf0e10cSrcweir while ( pUpperFrm )
2158cdf0e10cSrcweir {
2159cdf0e10cSrcweir if ( pUpperFrm->IsTabFrm() )
2160cdf0e10cSrcweir {
2161cdf0e10cSrcweir return sal_False;
2162cdf0e10cSrcweir }
2163cdf0e10cSrcweir else if ( pUpperFrm->IsColumnFrm() && pUpperFrm->IsInSct() )
2164cdf0e10cSrcweir {
2165cdf0e10cSrcweir break;
2166cdf0e10cSrcweir }
2167cdf0e10cSrcweir pUpperFrm = pUpperFrm->GetUpper();
2168cdf0e10cSrcweir }
2169cdf0e10cSrcweir }
2170cdf0e10cSrcweir // <--
2171cdf0e10cSrcweir
2172cdf0e10cSrcweir SwFtnBossFrm * pOldBoss = rThis.FindFtnBossFrm();
2173cdf0e10cSrcweir SwPageFrm * const pOldPage = pOldBoss->FindPageFrm();
2174cdf0e10cSrcweir SwLayoutFrm *pNewUpper = 0;
2175cdf0e10cSrcweir sal_Bool bCheckPageDescs = sal_False;
2176cdf0e10cSrcweir bool bCheckPageDescOfNextPage = false;
2177cdf0e10cSrcweir
2178cdf0e10cSrcweir if ( pFtn )
2179cdf0e10cSrcweir {
2180cdf0e10cSrcweir //Wenn die Fussnote bereits auf der gleichen Seite/Spalte wie die Referenz
2181cdf0e10cSrcweir //steht, ist nix mit zurueckfliessen. Die breaks brauche fuer die
2182cdf0e10cSrcweir //Fussnoten nicht geprueft zu werden.
2183cdf0e10cSrcweir
2184cdf0e10cSrcweir // --> FME 2004-11-15 #i37084# FindLastCntnt does not necessarily
2185cdf0e10cSrcweir // have to have a result != 0
2186cdf0e10cSrcweir SwFrm* pRef = 0;
2187cdf0e10cSrcweir const bool bEndnote = pFtn->GetAttr()->GetFtn().IsEndNote();
2188cdf0e10cSrcweir if( bEndnote && pFtn->IsInSct() )
2189cdf0e10cSrcweir {
2190cdf0e10cSrcweir SwSectionFrm* pSect = pFtn->FindSctFrm();
2191cdf0e10cSrcweir if( pSect->IsEndnAtEnd() )
2192cdf0e10cSrcweir pRef = pSect->FindLastCntnt( FINDMODE_LASTCNT );
2193cdf0e10cSrcweir }
2194cdf0e10cSrcweir if( !pRef )
2195cdf0e10cSrcweir pRef = pFtn->GetRef();
2196cdf0e10cSrcweir // <--
2197cdf0e10cSrcweir
2198cdf0e10cSrcweir ASSERT( pRef, "MoveBwd: Endnote for an empty section?" );
2199cdf0e10cSrcweir
2200cdf0e10cSrcweir if( !bEndnote )
2201cdf0e10cSrcweir pOldBoss = pOldBoss->FindFtnBossFrm( sal_True );
2202cdf0e10cSrcweir SwFtnBossFrm *pRefBoss = pRef->FindFtnBossFrm( !bEndnote );
2203cdf0e10cSrcweir if ( pOldBoss != pRefBoss &&
2204cdf0e10cSrcweir // OD 08.11.2002 #104840# - use <SwLayoutFrm::IsBefore(..)>
2205cdf0e10cSrcweir ( !bEndnote ||
2206cdf0e10cSrcweir pRefBoss->IsBefore( pOldBoss ) )
2207cdf0e10cSrcweir )
2208cdf0e10cSrcweir pNewUpper = rThis.GetLeaf( MAKEPAGE_FTN, sal_False );
2209cdf0e10cSrcweir }
2210cdf0e10cSrcweir else if ( IsPageBreak( sal_True ) ) //PageBreak zu beachten?
2211cdf0e10cSrcweir {
2212cdf0e10cSrcweir //Wenn auf der vorhergehenden Seite kein Frm im Body steht,
2213cdf0e10cSrcweir //so ist das Zurueckfliessen trotz Pagebreak sinnvoll
2214cdf0e10cSrcweir //(sonst: leere Seite).
2215cdf0e10cSrcweir //Natuerlich muessen Leereseiten geflissentlich uebersehen werden!
2216cdf0e10cSrcweir const SwFrm *pFlow = &rThis;
2217cdf0e10cSrcweir do
2218cdf0e10cSrcweir {
2219cdf0e10cSrcweir pFlow = pFlow->FindPrev();
2220cdf0e10cSrcweir } while ( pFlow &&
2221cdf0e10cSrcweir ( pFlow->FindPageFrm() == pOldPage ||
2222cdf0e10cSrcweir !pFlow->IsInDocBody() ) );
2223cdf0e10cSrcweir if ( pFlow )
2224cdf0e10cSrcweir {
2225cdf0e10cSrcweir long nDiff = pOldPage->GetPhyPageNum() - pFlow->GetPhyPageNum();
2226cdf0e10cSrcweir if ( nDiff > 1 )
2227cdf0e10cSrcweir {
2228cdf0e10cSrcweir if ( ((SwPageFrm*)pOldPage->GetPrev())->IsEmptyPage() )
2229cdf0e10cSrcweir nDiff -= 1;
2230cdf0e10cSrcweir if ( nDiff > 1 )
2231cdf0e10cSrcweir {
2232cdf0e10cSrcweir pNewUpper = rThis.GetLeaf( MAKEPAGE_NONE, sal_False );
2233cdf0e10cSrcweir // --> OD 2006-05-08 #i53139#
2234cdf0e10cSrcweir // Now <pNewUpper> is a previous layout frame, which contains
2235cdf0e10cSrcweir // content. But the new upper layout frame has to be the next one.
2236cdf0e10cSrcweir // Thus, hack for issue i14206 no longer needed, but fix for issue 114442
2237cdf0e10cSrcweir // --> OD 2006-05-17 #136024# - correct fix for i53139:
2238cdf0e10cSrcweir // Check for wrong page description before using next new upper.
2239cdf0e10cSrcweir // --> OD 2006-06-06 #i66051# - further correction of fix for i53139
2240cdf0e10cSrcweir // Check for correct type of new next upper layout frame
2241cdf0e10cSrcweir // --> OD 2006-06-08 #136538# - another correction of fix for i53139
2242cdf0e10cSrcweir // Assumption, that in all cases <pNewUpper> is a previous
2243cdf0e10cSrcweir // layout frame, which contains content, is wrong.
2244cdf0e10cSrcweir // --> OD 2006-07-05 #136538# - another correction of fix for i53139
2245cdf0e10cSrcweir // Beside type check, check also, if proposed new next upper
2246cdf0e10cSrcweir // frame is inside the same frame types.
2247cdf0e10cSrcweir // --> OD 2007-01-10 #i73194# - and yet another correction
2248cdf0e10cSrcweir // of fix for i53139:
2249cdf0e10cSrcweir // Assure that the new next upper layout frame doesn't
2250cdf0e10cSrcweir // equal the current one.
2251cdf0e10cSrcweir // E.g.: content is on page 3, on page 2 is only a 'ghost'
2252cdf0e10cSrcweir // section and on page 1 is normal content. Method <FindPrev(..)>
2253cdf0e10cSrcweir // will find the last content of page 1, but <GetLeaf(..)>
2254cdf0e10cSrcweir // returns new upper on page 2.
2255cdf0e10cSrcweir if ( pNewUpper->Lower() )
2256cdf0e10cSrcweir {
2257cdf0e10cSrcweir SwLayoutFrm* pNewNextUpper = pNewUpper->GetLeaf( MAKEPAGE_NONE, sal_True );
2258cdf0e10cSrcweir if ( pNewNextUpper &&
2259cdf0e10cSrcweir pNewNextUpper != rThis.GetUpper() &&
2260cdf0e10cSrcweir pNewNextUpper->GetType() == pNewUpper->GetType() &&
2261cdf0e10cSrcweir pNewNextUpper->IsInDocBody() == pNewUpper->IsInDocBody() &&
2262cdf0e10cSrcweir pNewNextUpper->IsInFtn() == pNewUpper->IsInFtn() &&
2263cdf0e10cSrcweir pNewNextUpper->IsInTab() == pNewUpper->IsInTab() &&
2264cdf0e10cSrcweir pNewNextUpper->IsInSct() == pNewUpper->IsInSct() &&
2265cdf0e10cSrcweir !rThis.WrongPageDesc( pNewNextUpper->FindPageFrm() ) )
2266cdf0e10cSrcweir {
2267cdf0e10cSrcweir pNewUpper = pNewNextUpper;
2268cdf0e10cSrcweir bCheckPageDescOfNextPage = true;
2269cdf0e10cSrcweir }
2270cdf0e10cSrcweir }
2271cdf0e10cSrcweir // <--
2272cdf0e10cSrcweir
2273cdf0e10cSrcweir bCheckPageDescs = sal_True;
2274cdf0e10cSrcweir }
2275cdf0e10cSrcweir }
2276cdf0e10cSrcweir }
2277cdf0e10cSrcweir }
2278cdf0e10cSrcweir else if ( IsColBreak( sal_True ) )
2279cdf0e10cSrcweir {
2280cdf0e10cSrcweir //Wenn in der vorhergehenden Spalte kein CntntFrm steht, so ist
2281cdf0e10cSrcweir //das Zurueckfliessen trotz ColumnBreak sinnvoll
2282cdf0e10cSrcweir //(sonst: leere Spalte).
2283cdf0e10cSrcweir if( rThis.IsInSct() )
2284cdf0e10cSrcweir {
2285cdf0e10cSrcweir pNewUpper = rThis.GetLeaf( MAKEPAGE_NONE, sal_False );
2286cdf0e10cSrcweir if( pNewUpper && !SwFlowFrm::IsMoveBwdJump() &&
2287cdf0e10cSrcweir ( pNewUpper->ContainsCntnt() ||
2288cdf0e10cSrcweir ( ( !pNewUpper->IsColBodyFrm() ||
2289cdf0e10cSrcweir !pNewUpper->GetUpper()->GetPrev() ) &&
2290cdf0e10cSrcweir !pNewUpper->FindSctFrm()->GetPrev() ) ) )
2291cdf0e10cSrcweir {
2292cdf0e10cSrcweir pNewUpper = 0;
2293cdf0e10cSrcweir }
2294cdf0e10cSrcweir // --> OD 2006-05-08 #i53139#
2295cdf0e10cSrcweir // --> OD 2006-09-11 #i69409# - check <pNewUpper>
2296cdf0e10cSrcweir // --> OD 2006-11-02 #i71065# - check <SwFlowFrm::IsMoveBwdJump()>
2297cdf0e10cSrcweir else if ( pNewUpper && !SwFlowFrm::IsMoveBwdJump() )
2298cdf0e10cSrcweir // <--
2299cdf0e10cSrcweir {
2300cdf0e10cSrcweir // Now <pNewUpper> is a previous layout frame, which
2301cdf0e10cSrcweir // contains content. But the new upper layout frame
2302cdf0e10cSrcweir // has to be the next one.
2303cdf0e10cSrcweir // --> OD 2006-05-17 #136024# - correct fix for i53139
2304cdf0e10cSrcweir // Check for wrong page description before using next new upper.
2305cdf0e10cSrcweir // --> OD 2006-06-06 #i66051# - further correction of fix for i53139
2306cdf0e10cSrcweir // Check for correct type of new next upper layout frame
2307cdf0e10cSrcweir // --> OD 2006-07-05 #136538# - another correction of fix for i53139
2308cdf0e10cSrcweir // Beside type check, check also, if proposed new next upper
2309cdf0e10cSrcweir // frame is inside the same frame types.
2310cdf0e10cSrcweir SwLayoutFrm* pNewNextUpper = pNewUpper->GetLeaf( MAKEPAGE_NOSECTION, sal_True );
2311cdf0e10cSrcweir if ( pNewNextUpper &&
2312cdf0e10cSrcweir pNewNextUpper->GetType() == pNewUpper->GetType() &&
2313cdf0e10cSrcweir pNewNextUpper->IsInDocBody() == pNewUpper->IsInDocBody() &&
2314cdf0e10cSrcweir pNewNextUpper->IsInFtn() == pNewUpper->IsInFtn() &&
2315cdf0e10cSrcweir pNewNextUpper->IsInTab() == pNewUpper->IsInTab() &&
2316cdf0e10cSrcweir pNewNextUpper->IsInSct() == pNewUpper->IsInSct() &&
2317cdf0e10cSrcweir !rThis.WrongPageDesc( pNewNextUpper->FindPageFrm() ) )
2318cdf0e10cSrcweir {
2319cdf0e10cSrcweir pNewUpper = pNewNextUpper;
2320cdf0e10cSrcweir }
2321cdf0e10cSrcweir }
2322cdf0e10cSrcweir // <--
2323cdf0e10cSrcweir }
2324cdf0e10cSrcweir else
2325cdf0e10cSrcweir {
2326cdf0e10cSrcweir const SwFrm *pCol = rThis.FindColFrm();
2327cdf0e10cSrcweir sal_Bool bGoOn = sal_True;
2328cdf0e10cSrcweir sal_Bool bJump = sal_False;
2329cdf0e10cSrcweir do
2330cdf0e10cSrcweir {
2331cdf0e10cSrcweir if ( pCol->GetPrev() )
2332cdf0e10cSrcweir pCol = pCol->GetPrev();
2333cdf0e10cSrcweir else
2334cdf0e10cSrcweir {
2335cdf0e10cSrcweir bGoOn = sal_False;
2336cdf0e10cSrcweir pCol = rThis.GetLeaf( MAKEPAGE_NONE, sal_False );
2337cdf0e10cSrcweir }
2338cdf0e10cSrcweir if ( pCol )
2339cdf0e10cSrcweir {
2340cdf0e10cSrcweir // ColumnFrms jetzt mit BodyFrm
2341cdf0e10cSrcweir SwLayoutFrm* pColBody = pCol->IsColumnFrm() ?
2342cdf0e10cSrcweir (SwLayoutFrm*)((SwLayoutFrm*)pCol)->Lower() :
2343cdf0e10cSrcweir (SwLayoutFrm*)pCol;
2344cdf0e10cSrcweir if ( pColBody->ContainsCntnt() )
2345cdf0e10cSrcweir {
2346cdf0e10cSrcweir bGoOn = sal_False; // Hier gibt's Inhalt, wir akzeptieren diese
2347cdf0e10cSrcweir // nur, wenn GetLeaf() das MoveBwdJump-Flag gesetzt hat.
2348cdf0e10cSrcweir if( SwFlowFrm::IsMoveBwdJump() )
2349cdf0e10cSrcweir {
2350cdf0e10cSrcweir pNewUpper = pColBody;
2351cdf0e10cSrcweir // --> OD 2006-05-08 #i53139#
2352cdf0e10cSrcweir // Now <pNewUpper> is a previous layout frame, which
2353cdf0e10cSrcweir // contains content. But the new upper layout frame
2354cdf0e10cSrcweir // has to be the next one.
2355cdf0e10cSrcweir // --> OD 2006-05-17 #136024# - correct fix for i53139
2356cdf0e10cSrcweir // Check for wrong page description before using next new upper.
2357cdf0e10cSrcweir // --> OD 2006-06-06 #i66051# - further correction of fix for i53139
2358cdf0e10cSrcweir // Check for correct type of new next upper layout frame
2359cdf0e10cSrcweir // --> OD 2006-07-05 #136538# - another correction of fix for i53139
2360cdf0e10cSrcweir // Beside type check, check also, if proposed new next upper
2361cdf0e10cSrcweir // frame is inside the same frame types.
2362cdf0e10cSrcweir // --> OD 2006-11-02 #i71065#
2363cdf0e10cSrcweir // Check that the proposed new next upper layout
2364cdf0e10cSrcweir // frame isn't the current one.
2365cdf0e10cSrcweir SwLayoutFrm* pNewNextUpper = pNewUpper->GetLeaf( MAKEPAGE_NONE, sal_True );
2366cdf0e10cSrcweir if ( pNewNextUpper &&
2367cdf0e10cSrcweir pNewNextUpper != rThis.GetUpper() &&
2368cdf0e10cSrcweir pNewNextUpper->GetType() == pNewUpper->GetType() &&
2369cdf0e10cSrcweir pNewNextUpper->IsInDocBody() == pNewUpper->IsInDocBody() &&
2370cdf0e10cSrcweir pNewNextUpper->IsInFtn() == pNewUpper->IsInFtn() &&
2371cdf0e10cSrcweir pNewNextUpper->IsInTab() == pNewUpper->IsInTab() &&
2372cdf0e10cSrcweir pNewNextUpper->IsInSct() == pNewUpper->IsInSct() &&
2373cdf0e10cSrcweir !rThis.WrongPageDesc( pNewNextUpper->FindPageFrm() ) )
2374cdf0e10cSrcweir {
2375cdf0e10cSrcweir pNewUpper = pNewNextUpper;
2376cdf0e10cSrcweir }
2377cdf0e10cSrcweir // <--
2378cdf0e10cSrcweir }
2379cdf0e10cSrcweir }
2380cdf0e10cSrcweir else
2381cdf0e10cSrcweir {
2382cdf0e10cSrcweir if( pNewUpper ) // Wir hatten schon eine leere Spalte, haben
2383cdf0e10cSrcweir bJump = sal_True; // also eine uebersprungen
2384cdf0e10cSrcweir pNewUpper = pColBody; // Diese leere Spalte kommt in Frage,
2385cdf0e10cSrcweir // trotzdem weitersuchen
2386cdf0e10cSrcweir }
2387cdf0e10cSrcweir }
2388cdf0e10cSrcweir } while( bGoOn );
2389cdf0e10cSrcweir if( bJump )
2390cdf0e10cSrcweir SwFlowFrm::SetMoveBwdJump( sal_True );
2391cdf0e10cSrcweir }
2392cdf0e10cSrcweir }
2393cdf0e10cSrcweir else //Keine Breaks also kann ich zurueckfliessen
2394cdf0e10cSrcweir pNewUpper = rThis.GetLeaf( MAKEPAGE_NONE, sal_False );
2395cdf0e10cSrcweir
2396cdf0e10cSrcweir // --> OD 2004-06-23 #i27801# - no move backward of 'master' text frame,
2397cdf0e10cSrcweir // if - due to its object positioning - it isn't allowed to be on the new page frame
2398cdf0e10cSrcweir // --> OD 2005-03-07 #i44049# - add another condition for not moving backward:
2399cdf0e10cSrcweir // If one of its objects has restarted the layout process, moving backward
2400cdf0e10cSrcweir // isn't sensible either.
2401cdf0e10cSrcweir // --> OD 2005-04-19 #i47697# - refine condition made for issue i44049:
2402cdf0e10cSrcweir // - allow move backward as long as the anchored object is only temporarily
2403cdf0e10cSrcweir // positions considering its wrapping style.
2404cdf0e10cSrcweir if ( pNewUpper &&
2405cdf0e10cSrcweir rThis.IsTxtFrm() && !IsFollow() )
2406cdf0e10cSrcweir {
2407cdf0e10cSrcweir sal_uInt32 nToPageNum( 0L );
2408cdf0e10cSrcweir const bool bMoveFwdByObjPos = SwLayouter::FrmMovedFwdByObjPos(
2409cdf0e10cSrcweir *(pOldPage->GetFmt()->GetDoc()),
2410cdf0e10cSrcweir static_cast<SwTxtFrm&>(rThis),
2411cdf0e10cSrcweir nToPageNum );
2412cdf0e10cSrcweir if ( bMoveFwdByObjPos &&
2413cdf0e10cSrcweir pNewUpper->FindPageFrm()->GetPhyPageNum() < nToPageNum )
2414cdf0e10cSrcweir {
2415cdf0e10cSrcweir pNewUpper = 0;
2416cdf0e10cSrcweir }
2417cdf0e10cSrcweir // --> OD 2005-03-07 #i44049# - check, if one of its anchored objects
2418cdf0e10cSrcweir // has restarted the layout process.
2419cdf0e10cSrcweir else if ( rThis.GetDrawObjs() )
2420cdf0e10cSrcweir {
2421cdf0e10cSrcweir sal_uInt32 i = 0;
2422cdf0e10cSrcweir for ( ; i < rThis.GetDrawObjs()->Count(); ++i )
2423cdf0e10cSrcweir {
2424cdf0e10cSrcweir SwAnchoredObject* pAnchoredObj = (*rThis.GetDrawObjs())[i];
2425cdf0e10cSrcweir // --> OD 2005-04-19 #i47697# - refine condition - see above
2426cdf0e10cSrcweir if ( pAnchoredObj->RestartLayoutProcess() &&
2427cdf0e10cSrcweir !pAnchoredObj->IsTmpConsiderWrapInfluence() )
2428cdf0e10cSrcweir // <--
2429cdf0e10cSrcweir {
2430cdf0e10cSrcweir pNewUpper = 0;
2431cdf0e10cSrcweir break;
2432cdf0e10cSrcweir }
2433cdf0e10cSrcweir }
2434cdf0e10cSrcweir }
2435cdf0e10cSrcweir // <--
2436cdf0e10cSrcweir }
2437cdf0e10cSrcweir // <--
2438cdf0e10cSrcweir
2439cdf0e10cSrcweir //Fuer Follows ist das zurueckfliessen nur dann erlaubt wenn in der
2440cdf0e10cSrcweir //neuen Umgebung kein Nachbar existiert (denn dieses waere der Master).
2441cdf0e10cSrcweir //(6677)Wenn allerdings leere Blaetter uebersprungen wurden wird doch gemoved.
2442cdf0e10cSrcweir if ( pNewUpper && IsFollow() && pNewUpper->Lower() )
2443cdf0e10cSrcweir {
2444cdf0e10cSrcweir // --> OD 2007-09-05 #i79774#, #b6596954#
2445cdf0e10cSrcweir // neglect empty sections in proposed new upper frame
2446cdf0e10cSrcweir bool bProposedNewUpperContainsOnlyEmptySections( true );
2447cdf0e10cSrcweir {
2448cdf0e10cSrcweir const SwFrm* pLower( pNewUpper->Lower() );
2449cdf0e10cSrcweir while ( pLower )
2450cdf0e10cSrcweir {
2451cdf0e10cSrcweir if ( pLower->IsSctFrm() &&
2452cdf0e10cSrcweir !dynamic_cast<const SwSectionFrm*>(pLower)->GetSection() )
2453cdf0e10cSrcweir {
2454cdf0e10cSrcweir pLower = pLower->GetNext();
2455cdf0e10cSrcweir continue;
2456cdf0e10cSrcweir }
2457cdf0e10cSrcweir else
2458cdf0e10cSrcweir {
2459cdf0e10cSrcweir bProposedNewUpperContainsOnlyEmptySections = false;
2460cdf0e10cSrcweir break;
2461cdf0e10cSrcweir }
2462cdf0e10cSrcweir }
2463cdf0e10cSrcweir }
2464cdf0e10cSrcweir if ( !bProposedNewUpperContainsOnlyEmptySections )
2465cdf0e10cSrcweir {
2466cdf0e10cSrcweir if ( SwFlowFrm::IsMoveBwdJump() )
2467cdf0e10cSrcweir {
2468cdf0e10cSrcweir //Nicht hinter den Master sondern in das naechstfolgende leere
2469cdf0e10cSrcweir //Blatt moven.
2470cdf0e10cSrcweir SwFrm *pFrm = pNewUpper->Lower();
2471cdf0e10cSrcweir while ( pFrm->GetNext() )
2472cdf0e10cSrcweir pFrm = pFrm->GetNext();
2473cdf0e10cSrcweir pNewUpper = pFrm->GetLeaf( MAKEPAGE_INSERT, sal_True );
2474cdf0e10cSrcweir if( pNewUpper == rThis.GetUpper() ) //Landen wir wieder an der gleichen Stelle?
2475cdf0e10cSrcweir pNewUpper = NULL; //dann eruebrigt sich das Moven
2476cdf0e10cSrcweir }
2477cdf0e10cSrcweir else
2478cdf0e10cSrcweir pNewUpper = 0;
2479cdf0e10cSrcweir }
2480cdf0e10cSrcweir // <--
2481cdf0e10cSrcweir }
2482cdf0e10cSrcweir if ( pNewUpper && !ShouldBwdMoved( pNewUpper, sal_True, rbReformat ) )
2483cdf0e10cSrcweir {
2484cdf0e10cSrcweir if( !pNewUpper->Lower() )
2485cdf0e10cSrcweir {
2486cdf0e10cSrcweir if( pNewUpper->IsFtnContFrm() )
2487cdf0e10cSrcweir {
2488cdf0e10cSrcweir pNewUpper->Cut();
2489cdf0e10cSrcweir delete pNewUpper;
2490cdf0e10cSrcweir }
2491cdf0e10cSrcweir else
2492cdf0e10cSrcweir {
2493cdf0e10cSrcweir SwSectionFrm* pSectFrm = pNewUpper->FindSctFrm();
2494cdf0e10cSrcweir // --> OD 2006-01-04 #126020# - adjust check for empty section
2495cdf0e10cSrcweir // --> OD 2006-02-01 #130797# - correct fix #126020#
2496cdf0e10cSrcweir if ( pSectFrm && !pSectFrm->IsColLocked() &&
2497cdf0e10cSrcweir !pSectFrm->ContainsCntnt() && !pSectFrm->ContainsAny( true ) )
2498cdf0e10cSrcweir // <--
2499cdf0e10cSrcweir {
2500cdf0e10cSrcweir pSectFrm->DelEmpty( sal_True );
2501cdf0e10cSrcweir delete pSectFrm;
2502cdf0e10cSrcweir rThis.bValidPos = sal_True;
2503cdf0e10cSrcweir }
2504cdf0e10cSrcweir }
2505cdf0e10cSrcweir }
2506cdf0e10cSrcweir pNewUpper = 0;
2507cdf0e10cSrcweir }
2508cdf0e10cSrcweir
2509cdf0e10cSrcweir // OD 2004-05-26 #i21478# - don't move backward, if flow frame wants to
2510cdf0e10cSrcweir // keep with next frame and next frame is locked.
2511cdf0e10cSrcweir // --> OD 2004-12-08 #i38232# - If next frame is a table, do *not* check,
2512cdf0e10cSrcweir // if it's locked.
2513cdf0e10cSrcweir if ( pNewUpper && !IsFollow() &&
2514cdf0e10cSrcweir rThis.GetAttrSet()->GetKeep().GetValue() && rThis.GetIndNext() )
2515cdf0e10cSrcweir {
2516cdf0e10cSrcweir SwFrm* pIndNext = rThis.GetIndNext();
2517cdf0e10cSrcweir // --> OD 2004-12-08 #i38232#
2518cdf0e10cSrcweir if ( !pIndNext->IsTabFrm() )
2519cdf0e10cSrcweir {
2520cdf0e10cSrcweir // get first content of section, while empty sections are skipped
2521cdf0e10cSrcweir while ( pIndNext && pIndNext->IsSctFrm() )
2522cdf0e10cSrcweir {
2523cdf0e10cSrcweir if( static_cast<SwSectionFrm*>(pIndNext)->GetSection() )
2524cdf0e10cSrcweir {
2525cdf0e10cSrcweir SwFrm* pTmp = static_cast<SwSectionFrm*>(pIndNext)->ContainsAny();
2526cdf0e10cSrcweir if ( pTmp )
2527cdf0e10cSrcweir {
2528cdf0e10cSrcweir pIndNext = pTmp;
2529cdf0e10cSrcweir break;
2530cdf0e10cSrcweir }
2531cdf0e10cSrcweir }
2532cdf0e10cSrcweir pIndNext = pIndNext->GetIndNext();
2533cdf0e10cSrcweir }
2534cdf0e10cSrcweir ASSERT( !pIndNext || pIndNext->ISA(SwTxtFrm),
2535cdf0e10cSrcweir "<SwFlowFrm::MovedBwd(..)> - incorrect next found." );
2536cdf0e10cSrcweir if ( pIndNext && pIndNext->IsFlowFrm() &&
2537cdf0e10cSrcweir SwFlowFrm::CastFlowFrm(pIndNext)->IsJoinLocked() )
2538cdf0e10cSrcweir {
2539cdf0e10cSrcweir pNewUpper = 0L;
2540cdf0e10cSrcweir }
2541cdf0e10cSrcweir }
2542cdf0e10cSrcweir // <--
2543cdf0e10cSrcweir }
2544cdf0e10cSrcweir
2545cdf0e10cSrcweir // --> OD 2006-05-10 #i65250#
2546cdf0e10cSrcweir // layout loop control for flowing content again and again moving
2547cdf0e10cSrcweir // backward under the same layout condition.
2548cdf0e10cSrcweir if ( pNewUpper && !IsFollow() &&
2549cdf0e10cSrcweir pNewUpper != rThis.GetUpper() &&
2550cdf0e10cSrcweir SwLayouter::MoveBwdSuppressed( *(pOldPage->GetFmt()->GetDoc()),
2551cdf0e10cSrcweir *this, *pNewUpper ) )
2552cdf0e10cSrcweir {
2553cdf0e10cSrcweir SwLayoutFrm* pNextNewUpper = pNewUpper->GetLeaf(
2554cdf0e10cSrcweir ( !rThis.IsSctFrm() && rThis.IsInSct() )
2555cdf0e10cSrcweir ? MAKEPAGE_NOSECTION
2556cdf0e10cSrcweir : MAKEPAGE_NONE,
2557cdf0e10cSrcweir sal_True );
2558cdf0e10cSrcweir // --> OD 2007-01-10 #i73194# - make code robust
2559cdf0e10cSrcweir ASSERT( pNextNewUpper, "<SwFlowFrm::MoveBwd(..)> - missing next new upper" );
2560cdf0e10cSrcweir if ( pNextNewUpper &&
2561cdf0e10cSrcweir ( pNextNewUpper == rThis.GetUpper() ||
2562cdf0e10cSrcweir pNextNewUpper->GetType() != rThis.GetUpper()->GetType() ) )
2563cdf0e10cSrcweir // <--
2564cdf0e10cSrcweir {
2565cdf0e10cSrcweir pNewUpper = 0L;
2566cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
2567cdf0e10cSrcweir ASSERT( false,
2568cdf0e10cSrcweir "<SwFlowFrm::MoveBwd(..)> - layout loop control for layout action <Move Backward> applied!" );
2569cdf0e10cSrcweir #endif
2570cdf0e10cSrcweir }
2571cdf0e10cSrcweir }
2572cdf0e10cSrcweir // <--
2573cdf0e10cSrcweir
2574cdf0e10cSrcweir ASSERT( pNewUpper != rThis.GetUpper(),
2575cdf0e10cSrcweir "<SwFlowFrm::MoveBwd(..)> - moving backward to the current upper frame!? -> Please inform OD." );
2576cdf0e10cSrcweir if ( pNewUpper )
2577cdf0e10cSrcweir {
2578cdf0e10cSrcweir PROTOCOL_ENTER( &rThis, PROT_MOVE_BWD, 0, 0 );
2579cdf0e10cSrcweir if ( pNewUpper->IsFtnContFrm() )
2580cdf0e10cSrcweir {
2581cdf0e10cSrcweir //Kann sein, dass ich einen Container bekam.
2582cdf0e10cSrcweir SwFtnFrm *pOld = rThis.FindFtnFrm();
2583cdf0e10cSrcweir SwFtnFrm *pNew = new SwFtnFrm( pOld->GetFmt(), pOld,
2584cdf0e10cSrcweir pOld->GetRef(), pOld->GetAttr() );
2585cdf0e10cSrcweir if ( pOld->GetMaster() )
2586cdf0e10cSrcweir {
2587cdf0e10cSrcweir pNew->SetMaster( pOld->GetMaster() );
2588cdf0e10cSrcweir pOld->GetMaster()->SetFollow( pNew );
2589cdf0e10cSrcweir }
2590cdf0e10cSrcweir pNew->SetFollow( pOld );
2591cdf0e10cSrcweir pOld->SetMaster( pNew );
2592cdf0e10cSrcweir pNew->Paste( pNewUpper );
2593cdf0e10cSrcweir pNewUpper = pNew;
2594cdf0e10cSrcweir }
2595cdf0e10cSrcweir if( pNewUpper->IsFtnFrm() && rThis.IsInSct() )
2596cdf0e10cSrcweir {
2597cdf0e10cSrcweir SwSectionFrm* pSct = rThis.FindSctFrm();
2598cdf0e10cSrcweir //Wenn wir in einem Bereich in einer Fussnote stecken, muss im
2599cdf0e10cSrcweir //neuen Upper ggf. ein SwSectionFrm angelegt werden
2600cdf0e10cSrcweir if( pSct->IsInFtn() )
2601cdf0e10cSrcweir {
2602cdf0e10cSrcweir SwFrm* pTmp = pNewUpper->Lower();
2603cdf0e10cSrcweir if( pTmp )
2604cdf0e10cSrcweir {
2605cdf0e10cSrcweir while( pTmp->GetNext() )
2606cdf0e10cSrcweir pTmp = pTmp->GetNext();
2607cdf0e10cSrcweir if( !pTmp->IsSctFrm() ||
2608cdf0e10cSrcweir ((SwSectionFrm*)pTmp)->GetFollow() != pSct )
2609cdf0e10cSrcweir pTmp = NULL;
2610cdf0e10cSrcweir }
2611cdf0e10cSrcweir if( pTmp )
2612cdf0e10cSrcweir pNewUpper = (SwSectionFrm*)pTmp;
2613cdf0e10cSrcweir else
2614cdf0e10cSrcweir {
2615cdf0e10cSrcweir pSct = new SwSectionFrm( *pSct, sal_True );
2616cdf0e10cSrcweir pSct->Paste( pNewUpper );
2617cdf0e10cSrcweir pSct->Init();
2618cdf0e10cSrcweir pNewUpper = pSct;
2619cdf0e10cSrcweir pSct->SimpleFormat();
2620cdf0e10cSrcweir }
2621cdf0e10cSrcweir }
2622cdf0e10cSrcweir }
2623cdf0e10cSrcweir sal_Bool bUnlock = sal_False;
2624cdf0e10cSrcweir sal_Bool bFollow = sal_False;
2625cdf0e10cSrcweir //Section locken, sonst kann sie bei Fluss des einzigen Cntnt etwa
2626cdf0e10cSrcweir //von zweiter in die erste Spalte zerstoert werden.
2627cdf0e10cSrcweir SwSectionFrm* pSect = pNewUpper->FindSctFrm();
2628cdf0e10cSrcweir if( pSect )
2629cdf0e10cSrcweir {
2630cdf0e10cSrcweir bUnlock = !pSect->IsColLocked();
2631cdf0e10cSrcweir pSect->ColLock();
2632cdf0e10cSrcweir bFollow = pSect->HasFollow();
2633cdf0e10cSrcweir }
2634cdf0e10cSrcweir pNewUpper->Calc();
2635cdf0e10cSrcweir rThis.Cut();
2636cdf0e10cSrcweir // --> OD 2005-02-23 #b6229852#
2637cdf0e10cSrcweir // optimization: format section, if its size is invalidated and if it's
2638cdf0e10cSrcweir // the new parent of moved backward frame.
2639cdf0e10cSrcweir bool bFormatSect( false );
2640cdf0e10cSrcweir // <--
2641cdf0e10cSrcweir if( bUnlock )
2642cdf0e10cSrcweir {
2643cdf0e10cSrcweir pSect->ColUnlock();
2644cdf0e10cSrcweir if( pSect->HasFollow() != bFollow )
2645cdf0e10cSrcweir {
2646cdf0e10cSrcweir pSect->InvalidateSize();
2647cdf0e10cSrcweir // --> OD 2005-02-23 #b6229852# - optimization
2648cdf0e10cSrcweir if ( pSect == pNewUpper )
2649cdf0e10cSrcweir bFormatSect = true;
2650cdf0e10cSrcweir // <--
2651cdf0e10cSrcweir }
2652cdf0e10cSrcweir }
2653cdf0e10cSrcweir
2654cdf0e10cSrcweir rThis.Paste( pNewUpper );
2655cdf0e10cSrcweir // --> OD 2005-02-23 #b6229852# - optimization
2656cdf0e10cSrcweir if ( bFormatSect )
2657cdf0e10cSrcweir pSect->Calc();
2658cdf0e10cSrcweir // <--
2659cdf0e10cSrcweir
2660cdf0e10cSrcweir SwPageFrm *pNewPage = rThis.FindPageFrm();
2661cdf0e10cSrcweir if( pNewPage != pOldPage )
2662cdf0e10cSrcweir {
2663cdf0e10cSrcweir rThis.Prepare( PREP_BOSS_CHGD, (const void*)pOldPage, sal_False );
2664cdf0e10cSrcweir ViewShell *pSh = rThis.getRootFrm()->GetCurrShell();
2665cdf0e10cSrcweir if ( pSh && !pSh->Imp()->IsUpdateExpFlds() )
2666cdf0e10cSrcweir pSh->GetDoc()->SetNewFldLst(true); //Wird von CalcLayout() hinterher eledigt!
2667cdf0e10cSrcweir
2668cdf0e10cSrcweir pNewPage->InvalidateSpelling();
2669cdf0e10cSrcweir pNewPage->InvalidateSmartTags(); // SMARTTAGS
2670cdf0e10cSrcweir pNewPage->InvalidateAutoCompleteWords();
2671cdf0e10cSrcweir pNewPage->InvalidateWordCount();
2672cdf0e10cSrcweir
2673cdf0e10cSrcweir // OD 30.10.2002 #97265# - no <CheckPageDesc(..)> in online layout
2674cdf0e10cSrcweir if ( !( pSh && pSh->GetViewOptions()->getBrowseMode() ) )
2675cdf0e10cSrcweir {
2676cdf0e10cSrcweir if ( bCheckPageDescs && pNewPage->GetNext() )
2677cdf0e10cSrcweir {
2678cdf0e10cSrcweir SwPageFrm* pStartPage = bCheckPageDescOfNextPage ?
2679cdf0e10cSrcweir pNewPage :
2680cdf0e10cSrcweir (SwPageFrm*)pNewPage->GetNext();
2681cdf0e10cSrcweir SwFrm::CheckPageDescs( pStartPage, sal_False);
2682cdf0e10cSrcweir }
2683cdf0e10cSrcweir else if ( rThis.GetAttrSet()->GetPageDesc().GetPageDesc() )
2684cdf0e10cSrcweir {
2685cdf0e10cSrcweir //Erste Seite wird etwa durch Ausblenden eines Bereiches leer
2686cdf0e10cSrcweir SwFrm::CheckPageDescs( (SwPageFrm*)pNewPage, sal_False);
2687cdf0e10cSrcweir }
2688cdf0e10cSrcweir }
2689cdf0e10cSrcweir }
2690cdf0e10cSrcweir }
2691cdf0e10cSrcweir return pNewUpper != 0;
2692cdf0e10cSrcweir }
2693cdf0e10cSrcweir
2694cdf0e10cSrcweir /*************************************************************************
2695cdf0e10cSrcweir |*
2696cdf0e10cSrcweir |* SwFlowFrm::CastFlowFrm
2697cdf0e10cSrcweir |*
2698cdf0e10cSrcweir |* Ersterstellung MA 03. May. 95
2699cdf0e10cSrcweir |* Letzte Aenderung AMA 02. Dec. 97
2700cdf0e10cSrcweir |*
2701cdf0e10cSrcweir |*************************************************************************/
2702cdf0e10cSrcweir
CastFlowFrm(SwFrm * pFrm)2703cdf0e10cSrcweir SwFlowFrm *SwFlowFrm::CastFlowFrm( SwFrm *pFrm )
2704cdf0e10cSrcweir {
2705cdf0e10cSrcweir if ( pFrm->IsCntntFrm() )
2706cdf0e10cSrcweir return (SwCntntFrm*)pFrm;
2707cdf0e10cSrcweir if ( pFrm->IsTabFrm() )
2708cdf0e10cSrcweir return (SwTabFrm*)pFrm;
2709cdf0e10cSrcweir if ( pFrm->IsSctFrm() )
2710cdf0e10cSrcweir return (SwSectionFrm*)pFrm;
2711cdf0e10cSrcweir return 0;
2712cdf0e10cSrcweir }
2713cdf0e10cSrcweir
CastFlowFrm(const SwFrm * pFrm)2714cdf0e10cSrcweir const SwFlowFrm *SwFlowFrm::CastFlowFrm( const SwFrm *pFrm )
2715cdf0e10cSrcweir {
2716cdf0e10cSrcweir if ( pFrm->IsCntntFrm() )
2717cdf0e10cSrcweir return (SwCntntFrm*)pFrm;
2718cdf0e10cSrcweir if ( pFrm->IsTabFrm() )
2719cdf0e10cSrcweir return (SwTabFrm*)pFrm;
2720cdf0e10cSrcweir if ( pFrm->IsSctFrm() )
2721cdf0e10cSrcweir return (SwSectionFrm*)pFrm;
2722cdf0e10cSrcweir return 0;
2723cdf0e10cSrcweir }
2724