File: | home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx |
Warning: | line 2290, column 47 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | ||||
2 | /* | ||||
3 | * This file is part of the LibreOffice project. | ||||
4 | * | ||||
5 | * This Source Code Form is subject to the terms of the Mozilla Public | ||||
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
8 | * | ||||
9 | * This file incorporates work covered by the following license notice: | ||||
10 | * | ||||
11 | * Licensed to the Apache Software Foundation (ASF) under one or more | ||||
12 | * contributor license agreements. See the NOTICE file distributed | ||||
13 | * with this work for additional information regarding copyright | ||||
14 | * ownership. The ASF licenses this file to you under the Apache | ||||
15 | * License, Version 2.0 (the "License"); you may not use this file | ||||
16 | * except in compliance with the License. You may obtain a copy of | ||||
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . | ||||
18 | */ | ||||
19 | |||||
20 | #include <txtftn.hxx> | ||||
21 | #include <fmtftn.hxx> | ||||
22 | #include <ftnidx.hxx> | ||||
23 | #include <pagefrm.hxx> | ||||
24 | #include <colfrm.hxx> | ||||
25 | #include <rootfrm.hxx> | ||||
26 | #include <frmtool.hxx> | ||||
27 | #include <ftnfrm.hxx> | ||||
28 | #include <txtfrm.hxx> | ||||
29 | #include <tabfrm.hxx> | ||||
30 | #include <pagedesc.hxx> | ||||
31 | #include <ftninfo.hxx> | ||||
32 | #include <sectfrm.hxx> | ||||
33 | #include <objectformatter.hxx> | ||||
34 | #include <viewopt.hxx> | ||||
35 | #include <calbck.hxx> | ||||
36 | #include <ndindex.hxx> | ||||
37 | #include <pam.hxx> | ||||
38 | #include <ndtxt.hxx> | ||||
39 | #include <sal/log.hxx> | ||||
40 | #include <IDocumentSettingAccess.hxx> | ||||
41 | |||||
42 | #define ENDNOTE0x80000000 0x80000000 | ||||
43 | |||||
44 | /// Search the position of an attribute in the FootnoteArray at the document, | ||||
45 | /// because all footnotes are located there, ordered by their index. | ||||
46 | static sal_uLong lcl_FindFootnotePos( const SwDoc *pDoc, const SwTextFootnote *pAttr ) | ||||
47 | { | ||||
48 | const SwFootnoteIdxs &rFootnoteIdxs = pDoc->GetFootnoteIdxs(); | ||||
49 | |||||
50 | SwTextFootnote* pBla = const_cast<SwTextFootnote*>(pAttr); | ||||
51 | SwFootnoteIdxs::const_iterator it = rFootnoteIdxs.find( pBla ); | ||||
52 | if ( it != rFootnoteIdxs.end() ) | ||||
53 | { | ||||
54 | sal_uLong nRet = it - rFootnoteIdxs.begin(); | ||||
55 | if( pAttr->GetFootnote().IsEndNote() ) | ||||
56 | return nRet + ENDNOTE0x80000000; | ||||
57 | return nRet; | ||||
58 | } | ||||
59 | OSL_ENSURE( !pDoc, "FootnotePos not found." )do { if (true && (!(!pDoc))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "59" ": "), "%s", "FootnotePos not found."); } } while ( false); | ||||
60 | return 0; | ||||
61 | } | ||||
62 | |||||
63 | bool SwFootnoteFrame::operator<( const SwTextFootnote* pTextFootnote ) const | ||||
64 | { | ||||
65 | const SwDoc* pDoc = GetFormat()->GetDoc(); | ||||
66 | OSL_ENSURE( pDoc, "SwFootnoteFrame: Missing doc!" )do { if (true && (!(pDoc))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "66" ": "), "%s", "SwFootnoteFrame: Missing doc!"); } } while (false); | ||||
67 | return lcl_FindFootnotePos( pDoc, GetAttr() ) < | ||||
68 | lcl_FindFootnotePos( pDoc, pTextFootnote ); | ||||
69 | } | ||||
70 | |||||
71 | /* | ||||
72 | |* | ||||
73 | |* bool lcl_NextFootnoteBoss( SwFootnoteBossFrame* pBoss, SwPageFrame* pPage) | ||||
74 | |* sets pBoss on the next SwFootnoteBossFrame, which can either be a column | ||||
75 | |* or a page (without columns). If the page changes meanwhile, | ||||
76 | |* pPage contains the new page and this function returns true. | ||||
77 | |* | ||||
78 | |*/ | ||||
79 | |||||
80 | static bool lcl_NextFootnoteBoss( SwFootnoteBossFrame* &rpBoss, SwPageFrame* &rpPage, | ||||
81 | bool bDontLeave ) | ||||
82 | { | ||||
83 | if( rpBoss->IsColumnFrame() ) | ||||
84 | { | ||||
85 | if( rpBoss->GetNext() ) | ||||
86 | { | ||||
87 | rpBoss = static_cast<SwFootnoteBossFrame*>(rpBoss->GetNext()); //next column | ||||
88 | return false; | ||||
89 | } | ||||
90 | if( rpBoss->IsInSct() ) | ||||
91 | { | ||||
92 | SwSectionFrame* pSct = rpBoss->FindSctFrame()->GetFollow(); | ||||
93 | if( pSct ) | ||||
94 | { | ||||
95 | OSL_ENSURE( pSct->Lower() && pSct->Lower()->IsColumnFrame(),do { if (true && (!(pSct->Lower() && pSct-> Lower()->IsColumnFrame()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "96" ": "), "%s", "Where's the column?"); } } while (false ) | ||||
96 | "Where's the column?" )do { if (true && (!(pSct->Lower() && pSct-> Lower()->IsColumnFrame()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "96" ": "), "%s", "Where's the column?"); } } while (false ); | ||||
97 | rpBoss = static_cast<SwColumnFrame*>(pSct->Lower()); | ||||
98 | SwPageFrame* pOld = rpPage; | ||||
99 | rpPage = pSct->FindPageFrame(); | ||||
100 | return pOld != rpPage; | ||||
101 | } | ||||
102 | else if( bDontLeave ) | ||||
103 | { | ||||
104 | rpPage = nullptr; | ||||
105 | rpBoss = nullptr; | ||||
106 | return false; | ||||
107 | } | ||||
108 | } | ||||
109 | } | ||||
110 | rpPage = static_cast<SwPageFrame*>(rpPage->GetNext()); // next page | ||||
111 | rpBoss = rpPage; | ||||
112 | if( rpPage ) | ||||
113 | { | ||||
114 | SwLayoutFrame* pBody = rpPage->FindBodyCont(); | ||||
115 | if( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrame() ) | ||||
116 | rpBoss = static_cast<SwFootnoteBossFrame*>(pBody->Lower()); // first column | ||||
117 | } | ||||
118 | return true; | ||||
119 | } | ||||
120 | |||||
121 | /// @returns column number if pBoss is a column, otherwise 0. | ||||
122 | static sal_uInt16 lcl_ColumnNum( const SwFrame* pBoss ) | ||||
123 | { | ||||
124 | sal_uInt16 nRet = 0; | ||||
125 | if( !pBoss->IsColumnFrame() ) | ||||
126 | return 0; | ||||
127 | const SwFrame* pCol; | ||||
128 | if( pBoss->IsInSct() ) | ||||
129 | { | ||||
130 | pCol = pBoss->GetUpper()->FindColFrame(); | ||||
131 | if( pBoss->GetNext() || pBoss->GetPrev() ) | ||||
132 | { | ||||
133 | while( pBoss ) | ||||
134 | { | ||||
135 | ++nRet; // Section columns | ||||
136 | pBoss = pBoss->GetPrev(); | ||||
137 | } | ||||
138 | } | ||||
139 | } | ||||
140 | else | ||||
141 | pCol = pBoss; | ||||
142 | while( pCol ) | ||||
143 | { | ||||
144 | nRet += 256; // Page columns | ||||
145 | pCol = pCol->GetPrev(); | ||||
146 | } | ||||
147 | return nRet; | ||||
148 | } | ||||
149 | |||||
150 | SwFootnoteContFrame::SwFootnoteContFrame( SwFrameFormat *pFormat, SwFrame* pSib ): | ||||
151 | SwLayoutFrame( pFormat, pSib ) | ||||
152 | { | ||||
153 | mnFrameType = SwFrameType::FtnCont; | ||||
154 | } | ||||
155 | |||||
156 | SwFootnoteFrame* SwFootnoteContFrame::AddChained(bool bAppend, SwFrame* pThis, bool bDefaultFormat) | ||||
157 | { | ||||
158 | SwFootnoteFrame *pOld = pThis->FindFootnoteFrame(); | ||||
159 | SwFrameFormat *pFormat = pOld->GetFormat(); | ||||
160 | if (bDefaultFormat) | ||||
161 | pFormat = pFormat->GetDoc()->GetDfltFrameFormat(); | ||||
162 | |||||
163 | SwFootnoteFrame *pNew = new SwFootnoteFrame(pFormat, pOld, pOld->GetRef(), pOld->GetAttr()); | ||||
164 | |||||
165 | if (bAppend) | ||||
166 | { | ||||
167 | if (pOld->GetFollow()) | ||||
168 | { | ||||
169 | pNew->SetFollow(pOld->GetFollow()); | ||||
170 | pOld->GetFollow()->SetMaster(pNew); | ||||
171 | } | ||||
172 | pOld->SetFollow(pNew); | ||||
173 | pNew->SetMaster(pOld); | ||||
174 | } | ||||
175 | else | ||||
176 | { | ||||
177 | if (pOld->GetMaster()) | ||||
178 | { | ||||
179 | pNew->SetMaster(pOld->GetMaster()); | ||||
180 | pOld->GetMaster()->SetFollow(pNew); | ||||
181 | } | ||||
182 | pNew->SetFollow(pOld); | ||||
183 | pOld->SetMaster(pNew); | ||||
184 | } | ||||
185 | |||||
186 | return pNew; | ||||
187 | } | ||||
188 | |||||
189 | // lcl_Undersize(..) walks over a SwFrame and its contents | ||||
190 | // and returns the sum of all requested TextFrame magnifications. | ||||
191 | |||||
192 | static long lcl_Undersize( const SwFrame* pFrame ) | ||||
193 | { | ||||
194 | long nRet = 0; | ||||
195 | SwRectFnSet aRectFnSet(pFrame); | ||||
196 | if( pFrame->IsTextFrame() ) | ||||
197 | { | ||||
198 | if( static_cast<const SwTextFrame*>(pFrame)->IsUndersized() ) | ||||
199 | { | ||||
200 | // Does this TextFrame would like to be a little bit bigger? | ||||
201 | nRet = static_cast<const SwTextFrame*>(pFrame)->GetParHeight() - | ||||
202 | aRectFnSet.GetHeight(pFrame->getFramePrintArea()); | ||||
203 | if( nRet < 0 ) | ||||
204 | nRet = 0; | ||||
205 | } | ||||
206 | } | ||||
207 | else if( pFrame->IsLayoutFrame() ) | ||||
208 | { | ||||
209 | const SwFrame* pNxt = static_cast<const SwLayoutFrame*>(pFrame)->Lower(); | ||||
210 | while( pNxt ) | ||||
211 | { | ||||
212 | nRet += lcl_Undersize( pNxt ); | ||||
213 | pNxt = pNxt->GetNext(); | ||||
214 | } | ||||
215 | } | ||||
216 | return nRet; | ||||
217 | } | ||||
218 | |||||
219 | namespace sw { | ||||
220 | |||||
221 | SwTwips FootnoteSeparatorHeight(SwPageFootnoteInfo const& rInf) | ||||
222 | { | ||||
223 | return rInf.GetTopDist() + rInf.GetBottomDist() + rInf.GetLineWidth(); | ||||
224 | } | ||||
225 | |||||
226 | } // namespace sw | ||||
227 | |||||
228 | /// "format" the frame (Fixsize is not set here). | ||||
229 | void SwFootnoteContFrame::Format( vcl::RenderContext* /*pRenderContext*/, const SwBorderAttrs * ) | ||||
230 | { | ||||
231 | // calculate total border, only one distance to the top | ||||
232 | const SwPageFrame* pPage = FindPageFrame(); | ||||
233 | const SwPageFootnoteInfo &rInf = pPage->GetPageDesc()->GetFootnoteInfo(); | ||||
234 | const SwTwips nBorder = sw::FootnoteSeparatorHeight(rInf); | ||||
235 | SwRectFnSet aRectFnSet(this); | ||||
236 | |||||
237 | if ( !isFramePrintAreaValid() ) | ||||
238 | { | ||||
239 | setFramePrintAreaValid(true); | ||||
240 | SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this); | ||||
241 | |||||
242 | aRectFnSet.SetTop( aPrt, nBorder ); | ||||
243 | aRectFnSet.SetWidth( aPrt, aRectFnSet.GetWidth(getFrameArea()) ); | ||||
244 | aRectFnSet.SetHeight(aPrt, aRectFnSet.GetHeight(getFrameArea()) - nBorder ); | ||||
245 | |||||
246 | if( aRectFnSet.GetHeight(aPrt) < 0 && !pPage->IsFootnotePage() ) | ||||
247 | { | ||||
248 | setFrameAreaSizeValid(false); | ||||
249 | } | ||||
250 | } | ||||
251 | |||||
252 | if ( isFrameAreaSizeValid() ) | ||||
253 | return; | ||||
254 | |||||
255 | bool bGrow = pPage->IsFootnotePage(); | ||||
256 | if( bGrow ) | ||||
257 | { | ||||
258 | const SwViewShell *pSh = getRootFrame() ? getRootFrame()->GetCurrShell() : nullptr; | ||||
259 | if( pSh && pSh->GetViewOptions()->getBrowseMode() ) | ||||
260 | bGrow = false; | ||||
261 | } | ||||
262 | if( bGrow ) | ||||
263 | Grow( LONG_MAX9223372036854775807L ); | ||||
264 | else | ||||
265 | { | ||||
266 | // VarSize is determined based on the content plus the borders | ||||
267 | SwTwips nRemaining = 0; | ||||
268 | SwFrame *pFrame = m_pLower; | ||||
269 | while ( pFrame ) | ||||
270 | { // lcl_Undersize(..) respects (recursively) TextFrames, which | ||||
271 | // would like to be bigger. They are created especially in | ||||
272 | // columnized borders, if these do not have their maximum | ||||
273 | // size yet. | ||||
274 | nRemaining += aRectFnSet.GetHeight(pFrame->getFrameArea()) + lcl_Undersize( pFrame ); | ||||
275 | pFrame = pFrame->GetNext(); | ||||
276 | } | ||||
277 | // add the own border | ||||
278 | nRemaining += nBorder; | ||||
279 | |||||
280 | SwTwips nDiff; | ||||
281 | if( IsInSct() ) | ||||
282 | { | ||||
283 | nDiff = -aRectFnSet.BottomDist( getFrameArea(), aRectFnSet.GetPrtBottom(*GetUpper()) ); | ||||
284 | if( nDiff > 0 ) | ||||
285 | { | ||||
286 | if( nDiff > aRectFnSet.GetHeight(getFrameArea()) ) | ||||
287 | { | ||||
288 | nDiff = aRectFnSet.GetHeight(getFrameArea()); | ||||
289 | } | ||||
290 | |||||
291 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | ||||
292 | aRectFnSet.AddBottom( aFrm, -nDiff ); | ||||
293 | aRectFnSet.AddHeight( aFrm, -nDiff ); | ||||
294 | } | ||||
295 | } | ||||
296 | nDiff = aRectFnSet.GetHeight(getFrameArea()) - nRemaining; | ||||
297 | if ( nDiff > 0 ) | ||||
298 | Shrink( nDiff ); | ||||
299 | else if ( nDiff < 0 ) | ||||
300 | { | ||||
301 | Grow( -nDiff ); | ||||
302 | // It may happen that there is less space available, | ||||
303 | // than what the border needs - the size of the PrtArea | ||||
304 | // will then be negative. | ||||
305 | SwTwips nPrtHeight = aRectFnSet.GetHeight(getFramePrintArea()); | ||||
306 | if( nPrtHeight < 0 ) | ||||
307 | { | ||||
308 | const SwTwips nTmpDiff = std::max( aRectFnSet.GetTop(getFramePrintArea()), -nPrtHeight ); | ||||
309 | SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this); | ||||
310 | aRectFnSet.SubTop( aPrt, nTmpDiff ); | ||||
311 | } | ||||
312 | } | ||||
313 | } | ||||
314 | |||||
315 | setFrameAreaSizeValid(true); | ||||
316 | } | ||||
317 | |||||
318 | SwTwips SwFootnoteContFrame::GrowFrame( SwTwips nDist, bool bTst, bool ) | ||||
319 | { | ||||
320 | // No check if FixSize since FootnoteContainer are variable up to their max. height. | ||||
321 | // If the max. height is LONG_MAX, take as much space as needed. | ||||
322 | // If the page is a special footnote page, take also as much as possible. | ||||
323 | assert(GetUpper() && GetUpper()->IsFootnoteBossFrame())(static_cast <bool> (GetUpper() && GetUpper()-> IsFootnoteBossFrame()) ? void (0) : __assert_fail ("GetUpper() && GetUpper()->IsFootnoteBossFrame()" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" , 323, __extension__ __PRETTY_FUNCTION__)); | ||||
324 | |||||
325 | SwRectFnSet aRectFnSet(this); | ||||
326 | if( aRectFnSet.GetHeight(getFrameArea()) > 0 && | ||||
327 | nDist > ( LONG_MAX9223372036854775807L - aRectFnSet.GetHeight(getFrameArea()) ) ) | ||||
328 | nDist = LONG_MAX9223372036854775807L - aRectFnSet.GetHeight(getFrameArea()); | ||||
329 | |||||
330 | SwFootnoteBossFrame *pBoss = static_cast<SwFootnoteBossFrame*>(GetUpper()); | ||||
331 | if( IsInSct() ) | ||||
332 | { | ||||
333 | SwSectionFrame* pSect = FindSctFrame(); | ||||
334 | OSL_ENSURE( pSect, "GrowFrame: Missing SectFrame" )do { if (true && (!(pSect))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "334" ": "), "%s", "GrowFrame: Missing SectFrame"); } } while (false); | ||||
335 | // In a section, which has to maximize, a footnotecontainer is allowed | ||||
336 | // to grow, when the section can't grow anymore. | ||||
337 | if( !bTst && !pSect->IsColLocked() && | ||||
338 | pSect->ToMaximize( false ) && pSect->Growable() ) | ||||
339 | { | ||||
340 | pSect->InvalidateSize(); | ||||
341 | return 0; | ||||
342 | } | ||||
343 | } | ||||
344 | const SwViewShell *pSh = getRootFrame() ? getRootFrame()->GetCurrShell() : nullptr; | ||||
345 | const bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode(); | ||||
346 | SwPageFrame *pPage = pBoss->FindPageFrame(); | ||||
347 | if ( bBrowseMode || !pPage->IsFootnotePage() ) | ||||
348 | { | ||||
349 | if ( pBoss->GetMaxFootnoteHeight() != LONG_MAX9223372036854775807L ) | ||||
350 | { | ||||
351 | nDist = std::min( nDist, pBoss->GetMaxFootnoteHeight() | ||||
352 | - aRectFnSet.GetHeight(getFrameArea()) ); | ||||
353 | if ( nDist <= 0 ) | ||||
354 | return 0; | ||||
355 | } | ||||
356 | // FootnoteBoss also influences the max value | ||||
357 | if( !IsInSct() ) | ||||
358 | { | ||||
359 | const SwTwips nMax = pBoss->GetVarSpace(); | ||||
360 | if ( nDist > nMax ) | ||||
361 | nDist = nMax; | ||||
362 | if ( nDist <= 0 ) | ||||
363 | return 0; | ||||
364 | } | ||||
365 | } | ||||
366 | else if( nDist > aRectFnSet.GetHeight(GetPrev()->getFrameArea()) ) | ||||
367 | // do not use more space than the body has | ||||
368 | nDist = aRectFnSet.GetHeight(GetPrev()->getFrameArea()); | ||||
369 | |||||
370 | long nAvail = 0; | ||||
371 | if ( bBrowseMode ) | ||||
372 | { | ||||
373 | nAvail = GetUpper()->getFramePrintArea().Height(); | ||||
374 | const SwFrame *pAvail = GetUpper()->Lower(); | ||||
375 | do | ||||
376 | { nAvail -= pAvail->getFrameArea().Height(); | ||||
377 | pAvail = pAvail->GetNext(); | ||||
378 | } while ( pAvail ); | ||||
379 | if ( nAvail > nDist ) | ||||
380 | nAvail = nDist; | ||||
381 | } | ||||
382 | |||||
383 | if ( !bTst ) | ||||
384 | { | ||||
385 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | ||||
386 | aRectFnSet.SetHeight( aFrm, aRectFnSet.GetHeight(aFrm) + nDist ); | ||||
387 | |||||
388 | if( IsVertical() && !IsVertLR() ) | ||||
389 | { | ||||
390 | aFrm.Pos().AdjustX( -nDist ); | ||||
391 | } | ||||
392 | } | ||||
393 | long nGrow = nDist - nAvail, | ||||
394 | nReal = 0; | ||||
395 | if ( nGrow > 0 ) | ||||
396 | { | ||||
397 | SwNeighbourAdjust nAdjust = pBoss->NeighbourhoodAdjustment(); | ||||
398 | if( SwNeighbourAdjust::OnlyAdjust == nAdjust ) | ||||
399 | nReal = AdjustNeighbourhood( nGrow, bTst ); | ||||
400 | else | ||||
401 | { | ||||
402 | if( SwNeighbourAdjust::GrowAdjust == nAdjust ) | ||||
403 | { | ||||
404 | SwFrame* pFootnote = Lower(); | ||||
405 | if( pFootnote ) | ||||
406 | { | ||||
407 | while( pFootnote->GetNext() ) | ||||
408 | pFootnote = pFootnote->GetNext(); | ||||
409 | if( static_cast<SwFootnoteFrame*>(pFootnote)->GetAttr()->GetFootnote().IsEndNote() ) | ||||
410 | { | ||||
411 | nReal = AdjustNeighbourhood( nGrow, bTst ); | ||||
412 | nAdjust = SwNeighbourAdjust::GrowShrink; // no more AdjustNeighbourhood | ||||
413 | } | ||||
414 | } | ||||
415 | } | ||||
416 | nReal += pBoss->Grow( nGrow - nReal, bTst ); | ||||
417 | if( ( SwNeighbourAdjust::GrowAdjust == nAdjust || SwNeighbourAdjust::AdjustGrow == nAdjust ) | ||||
418 | && nReal < nGrow ) | ||||
419 | nReal += AdjustNeighbourhood( nGrow - nReal, bTst ); | ||||
420 | } | ||||
421 | } | ||||
422 | |||||
423 | nReal += nAvail; | ||||
424 | |||||
425 | if ( !bTst ) | ||||
426 | { | ||||
427 | if ( nReal != nDist ) | ||||
428 | { | ||||
429 | nDist -= nReal; | ||||
430 | |||||
431 | // We can only respect the boundless wish so much | ||||
432 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | ||||
433 | aFrm.AddHeight( -nDist ); | ||||
434 | |||||
435 | if( IsVertical() && !IsVertLR() ) | ||||
436 | { | ||||
437 | aFrm.Pos().AdjustX(nDist ); | ||||
438 | } | ||||
439 | } | ||||
440 | |||||
441 | // growing happens upwards, so successors to not need to be invalidated | ||||
442 | if( nReal ) | ||||
443 | { | ||||
444 | InvalidateSize_(); | ||||
445 | InvalidatePos_(); | ||||
446 | InvalidatePage( pPage ); | ||||
447 | } | ||||
448 | } | ||||
449 | return nReal; | ||||
450 | } | ||||
451 | |||||
452 | SwTwips SwFootnoteContFrame::ShrinkFrame( SwTwips nDiff, bool bTst, bool bInfo ) | ||||
453 | { | ||||
454 | SwPageFrame *pPage = FindPageFrame(); | ||||
455 | bool bShrink = false; | ||||
456 | if ( pPage ) | ||||
457 | { | ||||
458 | if( !pPage->IsFootnotePage() ) | ||||
459 | bShrink = true; | ||||
460 | else | ||||
461 | { | ||||
462 | const SwViewShell *pSh = getRootFrame()->GetCurrShell(); | ||||
463 | if( pSh && pSh->GetViewOptions()->getBrowseMode() ) | ||||
464 | bShrink = true; | ||||
465 | } | ||||
466 | } | ||||
467 | if( bShrink ) | ||||
468 | { | ||||
469 | SwTwips nRet = SwLayoutFrame::ShrinkFrame( nDiff, bTst, bInfo ); | ||||
470 | if( IsInSct() && !bTst ) | ||||
471 | FindSctFrame()->InvalidateNextPos(); | ||||
472 | if ( !bTst && nRet ) | ||||
473 | { | ||||
474 | InvalidatePos_(); | ||||
475 | InvalidatePage( pPage ); | ||||
476 | } | ||||
477 | return nRet; | ||||
478 | } | ||||
479 | return 0; | ||||
480 | } | ||||
481 | |||||
482 | SwFootnoteFrame::SwFootnoteFrame( SwFrameFormat *pFormat, SwFrame* pSib, SwContentFrame *pCnt, SwTextFootnote *pAt ): | ||||
483 | SwLayoutFrame( pFormat, pSib ), | ||||
484 | mpFollow( nullptr ), | ||||
485 | mpMaster( nullptr ), | ||||
486 | mpReference( pCnt ), | ||||
487 | mpAttribute( pAt ), | ||||
488 | mbBackMoveLocked( false ), | ||||
489 | // #i49383# | ||||
490 | mbUnlockPosOfLowerObjs( true ) | ||||
491 | { | ||||
492 | mnFrameType = SwFrameType::Ftn; | ||||
493 | } | ||||
494 | |||||
495 | void SwFootnoteFrame::InvalidateNxtFootnoteCnts( SwPageFrame const *pPage ) | ||||
496 | { | ||||
497 | if ( !GetNext() ) | ||||
498 | return; | ||||
499 | |||||
500 | SwFrame *pCnt = static_cast<SwLayoutFrame*>(GetNext())->ContainsAny(); | ||||
501 | if( !pCnt ) | ||||
502 | return; | ||||
503 | |||||
504 | pCnt->InvalidatePage( pPage ); | ||||
505 | pCnt->InvalidatePrt_(); | ||||
506 | do | ||||
507 | { pCnt->InvalidatePos_(); | ||||
508 | if( pCnt->IsSctFrame() ) | ||||
509 | { | ||||
510 | SwFrame* pTmp = static_cast<SwSectionFrame*>(pCnt)->ContainsAny(); | ||||
511 | if( pTmp ) | ||||
512 | pTmp->InvalidatePos_(); | ||||
513 | } | ||||
514 | pCnt->GetUpper()->InvalidateSize_(); | ||||
515 | pCnt = pCnt->FindNext(); | ||||
516 | } while ( pCnt && GetUpper()->IsAnLower( pCnt ) ); | ||||
517 | } | ||||
518 | |||||
519 | bool SwFootnoteFrame::IsDeleteForbidden() const | ||||
520 | { | ||||
521 | if (SwLayoutFrame::IsDeleteForbidden()) | ||||
522 | return true; | ||||
523 | // needs to be in sync with the ::Cut logic | ||||
524 | const SwLayoutFrame *pUp = GetUpper(); | ||||
525 | if (pUp) | ||||
526 | { | ||||
527 | if (GetPrev()) | ||||
528 | return false; | ||||
529 | |||||
530 | // The last footnote takes its container along if it | ||||
531 | // is deleted. Cut would put pUp->Lower() to the value | ||||
532 | // of GetNext(), so if there is no GetNext then | ||||
533 | // Cut would delete pUp. If that condition is true | ||||
534 | // here then check if the container is delete-forbidden | ||||
535 | return !GetNext() && pUp->IsDeleteForbidden(); | ||||
536 | } | ||||
537 | return false; | ||||
538 | } | ||||
539 | |||||
540 | void SwFootnoteFrame::Cut() | ||||
541 | { | ||||
542 | if ( GetNext() ) | ||||
543 | GetNext()->InvalidatePos(); | ||||
544 | else if ( GetPrev() ) | ||||
545 | GetPrev()->SetRetouche(); | ||||
546 | |||||
547 | // first move then shrink Upper | ||||
548 | SwLayoutFrame *pUp = GetUpper(); | ||||
549 | |||||
550 | // correct chaining | ||||
551 | SwFootnoteFrame *pFootnote = this; | ||||
552 | if ( pFootnote->GetFollow() ) | ||||
553 | pFootnote->GetFollow()->SetMaster( pFootnote->GetMaster() ); | ||||
554 | if ( pFootnote->GetMaster() ) | ||||
555 | pFootnote->GetMaster()->SetFollow( pFootnote->GetFollow() ); | ||||
556 | pFootnote->SetFollow( nullptr ); | ||||
557 | pFootnote->SetMaster( nullptr ); | ||||
558 | |||||
559 | // cut all connections | ||||
560 | RemoveFromLayout(); | ||||
561 | |||||
562 | if ( !pUp ) | ||||
563 | return; | ||||
564 | |||||
565 | // The last footnote takes its container along | ||||
566 | if (!pUp->Lower()) | ||||
567 | { | ||||
568 | SwPageFrame *pPage = pUp->FindPageFrame(); | ||||
569 | if ( pPage ) | ||||
570 | { | ||||
571 | SwLayoutFrame *pBody = pPage->FindBodyCont(); | ||||
572 | if( pBody && !pBody->ContainsContent() ) | ||||
573 | pPage->getRootFrame()->SetSuperfluous(); | ||||
574 | } | ||||
575 | SwSectionFrame* pSect = pUp->FindSctFrame(); | ||||
576 | pUp->Cut(); | ||||
577 | SwFrame::DestroyFrame(pUp); | ||||
578 | // If the last footnote container was removed from a column | ||||
579 | // section without a Follow, then this section can be shrunk. | ||||
580 | if( pSect && !pSect->ToMaximize( false ) && !pSect->IsColLocked() ) | ||||
581 | pSect->InvalidateSize_(); | ||||
582 | } | ||||
583 | else | ||||
584 | { if ( getFrameArea().Height() ) | ||||
585 | pUp->Shrink( getFrameArea().Height() ); | ||||
586 | pUp->SetCompletePaint(); | ||||
587 | pUp->InvalidatePage(); | ||||
588 | } | ||||
589 | } | ||||
590 | |||||
591 | void SwFootnoteFrame::Paste( SwFrame* pParent, SwFrame* pSibling ) | ||||
592 | { | ||||
593 | OSL_ENSURE( pParent, "no parent in Paste." )do { if (true && (!(pParent))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "593" ": "), "%s", "no parent in Paste."); } } while (false ); | ||||
594 | OSL_ENSURE( pParent->IsLayoutFrame(), "Parent is ContentFrame." )do { if (true && (!(pParent->IsLayoutFrame()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "594" ": "), "%s", "Parent is ContentFrame."); } } while (false); | ||||
595 | OSL_ENSURE( pParent != this, "I am my own parent." )do { if (true && (!(pParent != this))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "595" ": "), "%s", "I am my own parent."); } } while (false ); | ||||
596 | OSL_ENSURE( pSibling != this, "I am my own sibling." )do { if (true && (!(pSibling != this))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "596" ": "), "%s", "I am my own sibling."); } } while (false ); | ||||
597 | OSL_ENSURE( !GetPrev() && !GetNext() && !GetUpper(),do { if (true && (!(!GetPrev() && !GetNext() && !GetUpper()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "598" ": "), "%s", "I am still somewhere registered."); } } while (false) | ||||
598 | "I am still somewhere registered." )do { if (true && (!(!GetPrev() && !GetNext() && !GetUpper()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "598" ": "), "%s", "I am still somewhere registered."); } } while (false); | ||||
599 | |||||
600 | // insert into tree structure | ||||
601 | InsertBefore( static_cast<SwLayoutFrame*>(pParent), pSibling ); | ||||
602 | |||||
603 | SwRectFnSet aRectFnSet(this); | ||||
604 | if( aRectFnSet.GetWidth(getFrameArea())!=aRectFnSet.GetWidth(pParent->getFramePrintArea()) ) | ||||
605 | InvalidateSize_(); | ||||
606 | InvalidatePos_(); | ||||
607 | SwPageFrame *pPage = FindPageFrame(); | ||||
608 | InvalidatePage( pPage ); | ||||
609 | if ( GetNext() ) | ||||
610 | GetNext()->InvalidatePos_(); | ||||
611 | if( aRectFnSet.GetHeight(getFrameArea()) ) | ||||
612 | pParent->Grow( aRectFnSet.GetHeight(getFrameArea()) ); | ||||
613 | |||||
614 | // If the predecessor is the master and/or the successor is the Follow, | ||||
615 | // then take their content and destroy them. | ||||
616 | if ( GetPrev() && GetPrev() == GetMaster() ) | ||||
617 | { | ||||
618 | OSL_ENSURE( SwFlowFrame::CastFlowFrame( GetPrev()->GetLower() ),do { if (true && (!(SwFlowFrame::CastFlowFrame( GetPrev ()->GetLower() )))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "619" ": "), "%s", "Footnote without content?"); } } while (false) | ||||
619 | "Footnote without content?" )do { if (true && (!(SwFlowFrame::CastFlowFrame( GetPrev ()->GetLower() )))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "619" ": "), "%s", "Footnote without content?"); } } while (false); | ||||
620 | SwFlowFrame::CastFlowFrame( GetPrev()->GetLower())-> | ||||
621 | MoveSubTree( this, GetLower() ); | ||||
622 | SwFrame *pDel = GetPrev(); | ||||
623 | pDel->Cut(); | ||||
624 | SwFrame::DestroyFrame(pDel); | ||||
625 | } | ||||
626 | if ( GetNext() && GetNext() == GetFollow() ) | ||||
627 | { | ||||
628 | OSL_ENSURE( SwFlowFrame::CastFlowFrame( GetNext()->GetLower() ),do { if (true && (!(SwFlowFrame::CastFlowFrame( GetNext ()->GetLower() )))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "629" ": "), "%s", "Footnote without content?"); } } while (false) | ||||
629 | "Footnote without content?" )do { if (true && (!(SwFlowFrame::CastFlowFrame( GetNext ()->GetLower() )))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "629" ": "), "%s", "Footnote without content?"); } } while (false); | ||||
630 | SwFlowFrame::CastFlowFrame( GetNext()->GetLower() )->MoveSubTree( this ); | ||||
631 | SwFrame *pDel = GetNext(); | ||||
632 | pDel->Cut(); | ||||
633 | SwFrame::DestroyFrame(pDel); | ||||
634 | } | ||||
635 | #if OSL_DEBUG_LEVEL1 > 0 | ||||
636 | SwDoc *pDoc = GetFormat()->GetDoc(); | ||||
637 | if ( GetPrev() ) | ||||
638 | { | ||||
639 | OSL_ENSURE( lcl_FindFootnotePos( pDoc, static_cast<SwFootnoteFrame*>(GetPrev())->GetAttr() ) <=do { if (true && (!(lcl_FindFootnotePos( pDoc, static_cast <SwFootnoteFrame*>(GetPrev())->GetAttr() ) <= lcl_FindFootnotePos ( pDoc, GetAttr() )))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "640" ": "), "%s", "Prev is not FootnotePrev"); } } while (false) | ||||
640 | lcl_FindFootnotePos( pDoc, GetAttr() ), "Prev is not FootnotePrev" )do { if (true && (!(lcl_FindFootnotePos( pDoc, static_cast <SwFootnoteFrame*>(GetPrev())->GetAttr() ) <= lcl_FindFootnotePos ( pDoc, GetAttr() )))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "640" ": "), "%s", "Prev is not FootnotePrev"); } } while (false); | ||||
641 | } | ||||
642 | if ( GetNext() ) | ||||
643 | { | ||||
644 | OSL_ENSURE( lcl_FindFootnotePos( pDoc, GetAttr() ) <=do { if (true && (!(lcl_FindFootnotePos( pDoc, GetAttr () ) <= lcl_FindFootnotePos( pDoc, static_cast<SwFootnoteFrame *>(GetNext())->GetAttr() )))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "646" ": "), "%s", "Next is not FootnoteNext"); } } while (false) | ||||
645 | lcl_FindFootnotePos( pDoc, static_cast<SwFootnoteFrame*>(GetNext())->GetAttr() ),do { if (true && (!(lcl_FindFootnotePos( pDoc, GetAttr () ) <= lcl_FindFootnotePos( pDoc, static_cast<SwFootnoteFrame *>(GetNext())->GetAttr() )))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "646" ": "), "%s", "Next is not FootnoteNext"); } } while (false) | ||||
646 | "Next is not FootnoteNext" )do { if (true && (!(lcl_FindFootnotePos( pDoc, GetAttr () ) <= lcl_FindFootnotePos( pDoc, static_cast<SwFootnoteFrame *>(GetNext())->GetAttr() )))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "646" ": "), "%s", "Next is not FootnoteNext"); } } while (false); | ||||
647 | } | ||||
648 | #endif | ||||
649 | InvalidateNxtFootnoteCnts( pPage ); | ||||
650 | } | ||||
651 | |||||
652 | /// Return the next layout leaf in that the frame can be moved. | ||||
653 | /// New pages will only be created if specified by the parameter. | ||||
654 | SwLayoutFrame *SwFrame::GetNextFootnoteLeaf( MakePageType eMakePage ) | ||||
655 | { | ||||
656 | SwFootnoteBossFrame *pOldBoss = FindFootnoteBossFrame(); | ||||
657 | SwPageFrame* pOldPage = pOldBoss->FindPageFrame(); | ||||
658 | SwPageFrame* pPage; | ||||
659 | SwFootnoteBossFrame *pBoss = pOldBoss->IsColumnFrame() ? | ||||
660 | static_cast<SwFootnoteBossFrame*>(pOldBoss->GetNext()) : nullptr; // next column, if existing | ||||
661 | if( pBoss ) | ||||
662 | pPage = nullptr; | ||||
663 | else | ||||
664 | { | ||||
665 | if( pOldBoss->GetUpper()->IsSctFrame() ) | ||||
666 | { // this can only be in a column area | ||||
667 | SwLayoutFrame* pNxt = pOldBoss->GetNextSctLeaf( eMakePage ); | ||||
668 | if( pNxt ) | ||||
669 | { | ||||
670 | OSL_ENSURE( pNxt->IsColBodyFrame(), "GetNextFootnoteLeaf: Funny Leaf" )do { if (true && (!(pNxt->IsColBodyFrame()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "670" ": "), "%s", "GetNextFootnoteLeaf: Funny Leaf"); } } while (false); | ||||
671 | pBoss = static_cast<SwFootnoteBossFrame*>(pNxt->GetUpper()); | ||||
672 | pPage = pBoss->FindPageFrame(); | ||||
673 | } | ||||
674 | else | ||||
675 | return nullptr; | ||||
676 | } | ||||
677 | else | ||||
678 | { | ||||
679 | // next page | ||||
680 | pPage = static_cast<SwPageFrame*>(pOldPage->GetNext()); | ||||
681 | // skip empty pages | ||||
682 | if( pPage && pPage->IsEmptyPage() ) | ||||
683 | pPage = static_cast<SwPageFrame*>(pPage->GetNext()); | ||||
684 | pBoss = pPage; | ||||
685 | } | ||||
686 | } | ||||
687 | // What do we have until here? | ||||
688 | // pBoss != NULL, pPage==NULL => pBoss is the next column on the same page | ||||
689 | // pBoss != NULL, pPage!=NULL => pBoss and pPage are the following page (empty pages skipped) | ||||
690 | // pBoss == NULL => pPage == NULL, so there are no following pages | ||||
691 | |||||
692 | // If the footnote has already a Follow we do not need to search. | ||||
693 | // However, if there are unwanted empty columns/pages between Footnote and Follow, | ||||
694 | // create another Follow on the next best column/page and the rest will sort itself out. | ||||
695 | SwFootnoteFrame *pFootnote = FindFootnoteFrame(); | ||||
696 | if ( pFootnote && pFootnote->GetFollow() ) | ||||
697 | { | ||||
698 | SwFootnoteBossFrame* pTmpBoss = pFootnote->GetFollow()->FindFootnoteBossFrame(); | ||||
699 | // Following cases will be handled: | ||||
700 | // 1. both "FootnoteBoss"es are neighboring columns/pages | ||||
701 | // 2. the new one is the first column of a neighboring page | ||||
702 | // 3. the new one is the first column in a section of the next page | ||||
703 | while( pTmpBoss != pBoss && pTmpBoss && !pTmpBoss->GetPrev() ) | ||||
704 | pTmpBoss = pTmpBoss->GetUpper()->FindFootnoteBossFrame(); | ||||
705 | if( pTmpBoss == pBoss ) | ||||
706 | return pFootnote->GetFollow(); | ||||
707 | } | ||||
708 | |||||
709 | // If no pBoss could be found or it is a "wrong" page, we need a new page. | ||||
710 | if ( !pBoss || ( pPage && pPage->IsEndNotePage() && !pOldPage->IsEndNotePage() ) ) | ||||
711 | { | ||||
712 | if ( eMakePage == MAKEPAGE_APPEND || eMakePage == MAKEPAGE_INSERT ) | ||||
713 | { | ||||
714 | pBoss = InsertPage( pOldPage, pOldPage->IsFootnotePage() ); | ||||
715 | static_cast<SwPageFrame*>(pBoss)->SetEndNotePage( pOldPage->IsEndNotePage() ); | ||||
716 | } | ||||
717 | else | ||||
718 | return nullptr; | ||||
719 | } | ||||
720 | if( pBoss->IsPageFrame() ) | ||||
721 | { | ||||
722 | // If this page has columns, then go to the first one | ||||
723 | SwLayoutFrame* pLay = pBoss->FindBodyCont(); | ||||
724 | if( pLay && pLay->Lower() && pLay->Lower()->IsColumnFrame() ) | ||||
725 | pBoss = static_cast<SwFootnoteBossFrame*>(pLay->Lower()); | ||||
726 | } | ||||
727 | // found column/page - add myself | ||||
728 | SwFootnoteContFrame *pCont = pBoss->FindFootnoteCont(); | ||||
729 | if ( !pCont && pBoss->GetMaxFootnoteHeight() && | ||||
730 | ( eMakePage == MAKEPAGE_APPEND || eMakePage == MAKEPAGE_INSERT ) ) | ||||
731 | pCont = pBoss->MakeFootnoteCont(); | ||||
732 | return pCont; | ||||
733 | } | ||||
734 | |||||
735 | /// Get the preceding layout leaf in that the frame can be moved. | ||||
736 | SwLayoutFrame *SwFrame::GetPrevFootnoteLeaf( MakePageType eMakeFootnote ) | ||||
737 | { | ||||
738 | // The predecessor of a footnote is (if possible) | ||||
739 | // the master of the chain of the footnote. | ||||
740 | SwFootnoteFrame *pFootnote = FindFootnoteFrame(); | ||||
741 | SwLayoutFrame *pRet = pFootnote->GetMaster(); | ||||
742 | |||||
743 | SwFootnoteBossFrame* pOldBoss = FindFootnoteBossFrame(); | ||||
744 | SwPageFrame *pOldPage = pOldBoss->FindPageFrame(); | ||||
745 | |||||
746 | if ( !pOldBoss->GetPrev() && !pOldPage->GetPrev() ) | ||||
747 | return pRet; // there is neither a predecessor column nor page | ||||
748 | |||||
749 | if ( !pRet ) | ||||
750 | { | ||||
751 | bool bEndn = pFootnote->GetAttr()->GetFootnote().IsEndNote(); | ||||
752 | SwFrame* pTmpRef = nullptr; | ||||
753 | const IDocumentSettingAccess& rSettings | ||||
754 | = pFootnote->GetAttrSet()->GetDoc()->getIDocumentSettingAccess(); | ||||
755 | if( bEndn && pFootnote->IsInSct() ) | ||||
756 | { | ||||
757 | SwSectionFrame* pSect = pFootnote->FindSctFrame(); | ||||
758 | if( pSect->IsEndnAtEnd() ) | ||||
759 | // Endnotes at the end of the section. | ||||
760 | pTmpRef = pSect->FindLastContent( SwFindMode::LastCnt ); | ||||
761 | } | ||||
762 | else if (bEndn && rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES)) | ||||
763 | { | ||||
764 | // Endnotes at the end of the document. | ||||
765 | SwPageFrame* pPage = getRootFrame()->GetLastPage(); | ||||
766 | assert(pPage)(static_cast <bool> (pPage) ? void (0) : __assert_fail ( "pPage", "/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" , 766, __extension__ __PRETTY_FUNCTION__)); | ||||
767 | SwFrame* pPrevPage = pPage->GetPrev(); | ||||
768 | if (pPrevPage) | ||||
769 | { | ||||
770 | // Have a last but one page, use that since we try to get a preceding frame. | ||||
771 | assert(pPrevPage->IsPageFrame())(static_cast <bool> (pPrevPage->IsPageFrame()) ? void (0) : __assert_fail ("pPrevPage->IsPageFrame()", "/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" , 771, __extension__ __PRETTY_FUNCTION__)); | ||||
772 | pPage = static_cast<SwPageFrame*>(pPrevPage); | ||||
773 | } | ||||
774 | pTmpRef = pPage->FindLastBodyContent(); | ||||
775 | } | ||||
776 | if( !pTmpRef ) | ||||
777 | // Endnotes on a separate page. | ||||
778 | pTmpRef = pFootnote->GetRef(); | ||||
779 | SwFootnoteBossFrame* pStop = pTmpRef->FindFootnoteBossFrame( !bEndn ); | ||||
780 | |||||
781 | const sal_uInt16 nNum = pStop->GetPhyPageNum(); | ||||
782 | |||||
783 | // Do not leave the corresponding page if the footnote should | ||||
784 | // be shown at the document ending or the footnote is an endnote. | ||||
785 | const bool bEndNote = pOldPage->IsEndNotePage(); | ||||
786 | const bool bFootnoteEndDoc = pOldPage->IsFootnotePage(); | ||||
787 | SwFootnoteBossFrame* pNxtBoss = pOldBoss; | ||||
788 | SwSectionFrame *pSect = pNxtBoss->GetUpper()->IsSctFrame() ? | ||||
789 | static_cast<SwSectionFrame*>(pNxtBoss->GetUpper()) : nullptr; | ||||
790 | |||||
791 | do | ||||
792 | { | ||||
793 | if( pNxtBoss->IsColumnFrame() && pNxtBoss->GetPrev() ) | ||||
794 | pNxtBoss = static_cast<SwFootnoteBossFrame*>(pNxtBoss->GetPrev()); // one column backwards | ||||
795 | else // one page backwards | ||||
796 | { | ||||
797 | SwLayoutFrame* pBody = nullptr; | ||||
798 | if( pSect ) | ||||
799 | { | ||||
800 | if( pSect->IsFootnoteLock() ) | ||||
801 | { | ||||
802 | if( pNxtBoss == pOldBoss ) | ||||
803 | return nullptr; | ||||
804 | pStop = pNxtBoss; | ||||
805 | } | ||||
806 | else | ||||
807 | { | ||||
808 | pSect = pSect->FindMaster(); | ||||
809 | if( !pSect || !pSect->Lower() ) | ||||
810 | return nullptr; | ||||
811 | OSL_ENSURE( pSect->Lower()->IsColumnFrame(),do { if (true && (!(pSect->Lower()->IsColumnFrame ()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "812" ": "), "%s", "GetPrevFootnoteLeaf: Where's the column?" ); } } while (false) | ||||
812 | "GetPrevFootnoteLeaf: Where's the column?" )do { if (true && (!(pSect->Lower()->IsColumnFrame ()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "812" ": "), "%s", "GetPrevFootnoteLeaf: Where's the column?" ); } } while (false); | ||||
813 | pNxtBoss = static_cast<SwFootnoteBossFrame*>(pSect->Lower()); | ||||
814 | pBody = pSect; | ||||
815 | } | ||||
816 | } | ||||
817 | else | ||||
818 | { | ||||
819 | SwPageFrame* pPage = static_cast<SwPageFrame*>(pNxtBoss->FindPageFrame()->GetPrev()); | ||||
820 | if( !pPage || pPage->GetPhyPageNum() < nNum || | ||||
821 | bEndNote != pPage->IsEndNotePage() || bFootnoteEndDoc != pPage->IsFootnotePage() ) | ||||
822 | return nullptr; // no further pages found | ||||
823 | pNxtBoss = pPage; | ||||
824 | pBody = pPage->FindBodyCont(); | ||||
825 | } | ||||
826 | // We have the previous page, we might need to find the last column of it | ||||
827 | if( pBody ) | ||||
828 | { | ||||
829 | if ( pBody->Lower() && pBody->Lower()->IsColumnFrame() ) | ||||
830 | { | ||||
831 | pNxtBoss = static_cast<SwFootnoteBossFrame*>(pBody->GetLastLower()); | ||||
832 | } | ||||
833 | } | ||||
834 | } | ||||
835 | SwFootnoteContFrame *pCont = pNxtBoss->FindFootnoteCont(); | ||||
836 | if ( pCont ) | ||||
837 | { | ||||
838 | pRet = pCont; | ||||
839 | break; | ||||
840 | } | ||||
841 | if ( pStop == pNxtBoss ) | ||||
842 | { | ||||
843 | // Reached the column/page of the reference. | ||||
844 | // Try to add a container and paste our content. | ||||
845 | if ( eMakeFootnote == MAKEPAGE_FTN && pNxtBoss->GetMaxFootnoteHeight() ) | ||||
846 | pRet = pNxtBoss->MakeFootnoteCont(); | ||||
847 | break; | ||||
848 | } | ||||
849 | } while( !pRet ); | ||||
850 | } | ||||
851 | if ( pRet ) | ||||
852 | { | ||||
853 | const SwFootnoteBossFrame* pNewBoss = pRet->FindFootnoteBossFrame(); | ||||
854 | bool bJump = false; | ||||
855 | if( pOldBoss->IsColumnFrame() && pOldBoss->GetPrev() ) // a previous column exists | ||||
856 | bJump = pOldBoss->GetPrev() != static_cast<SwFrame const *>(pNewBoss); // did we chose it? | ||||
857 | else if( pNewBoss->IsColumnFrame() && pNewBoss->GetNext() ) | ||||
858 | bJump = true; // there is another column after the boss (not the old boss) | ||||
859 | else | ||||
860 | { | ||||
861 | // Will be reached only if old and new boss are both either pages or the last (new) | ||||
862 | // or first (old) column of a page. In this case, check if pages were skipped. | ||||
863 | const sal_uInt16 nDiff = pOldPage->GetPhyPageNum() - pRet->FindPageFrame()->GetPhyPageNum(); | ||||
864 | if ( nDiff > 2 || | ||||
865 | (nDiff > 1 && !static_cast<SwPageFrame*>(pOldPage->GetPrev())->IsEmptyPage()) ) | ||||
866 | bJump = true; | ||||
867 | } | ||||
868 | if( bJump ) | ||||
869 | SwFlowFrame::SetMoveBwdJump( true ); | ||||
870 | } | ||||
871 | return pRet; | ||||
872 | } | ||||
873 | |||||
874 | bool SwFrame::IsFootnoteAllowed() const | ||||
875 | { | ||||
876 | if ( !IsInDocBody() ) | ||||
877 | return false; | ||||
878 | |||||
879 | if ( IsInTab() ) | ||||
880 | { | ||||
881 | // no footnotes in repeated headlines | ||||
882 | const SwTabFrame *pTab = const_cast<SwFrame*>(this)->ImplFindTabFrame(); | ||||
883 | assert(pTab)(static_cast <bool> (pTab) ? void (0) : __assert_fail ( "pTab", "/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" , 883, __extension__ __PRETTY_FUNCTION__)); | ||||
884 | if ( pTab->IsFollow() ) | ||||
885 | return !pTab->IsInHeadline( *this ); | ||||
886 | } | ||||
887 | return true; | ||||
888 | } | ||||
889 | |||||
890 | void SwRootFrame::UpdateFootnoteNums() | ||||
891 | { | ||||
892 | // page numbering only if set at the document | ||||
893 | if ( GetFormat()->GetDoc()->GetFootnoteInfo().m_eNum == FTNNUM_PAGE ) | ||||
894 | { | ||||
895 | SwPageFrame *pPage = static_cast<SwPageFrame*>(Lower()); | ||||
896 | while ( pPage && !pPage->IsFootnotePage() ) | ||||
897 | { | ||||
898 | pPage->UpdateFootnoteNum(); | ||||
899 | pPage = static_cast<SwPageFrame*>(pPage->GetNext()); | ||||
900 | } | ||||
901 | } | ||||
902 | } | ||||
903 | |||||
904 | /// remove all footnotes (not the references) and all footnote pages | ||||
905 | void sw_RemoveFootnotes( SwFootnoteBossFrame* pBoss, bool bPageOnly, bool bEndNotes ) | ||||
906 | { | ||||
907 | do | ||||
908 | { | ||||
909 | SwFootnoteContFrame *pCont = pBoss->FindFootnoteCont(); | ||||
910 | if ( pCont ) | ||||
911 | { | ||||
912 | SwFootnoteFrame *pFootnote = static_cast<SwFootnoteFrame*>(pCont->Lower()); | ||||
913 | assert(pFootnote)(static_cast <bool> (pFootnote) ? void (0) : __assert_fail ("pFootnote", "/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" , 913, __extension__ __PRETTY_FUNCTION__)); | ||||
914 | if ( bPageOnly ) | ||||
915 | while ( pFootnote->GetMaster() ) | ||||
916 | pFootnote = pFootnote->GetMaster(); | ||||
917 | do | ||||
918 | { | ||||
919 | SwFootnoteFrame *pNxt = static_cast<SwFootnoteFrame*>(pFootnote->GetNext()); | ||||
920 | if ( !pFootnote->GetAttr()->GetFootnote().IsEndNote() || | ||||
921 | bEndNotes ) | ||||
922 | { | ||||
923 | pFootnote->GetRef()->Prepare( PrepareHint::FootnoteInvalidation, static_cast<void*>(pFootnote->GetAttr()) ); | ||||
924 | if ( bPageOnly && !pNxt ) | ||||
925 | pNxt = pFootnote->GetFollow(); | ||||
926 | pFootnote->Cut(); | ||||
927 | SwFrame::DestroyFrame(pFootnote); | ||||
928 | } | ||||
929 | pFootnote = pNxt; | ||||
930 | |||||
931 | } while ( pFootnote ); | ||||
932 | } | ||||
933 | if( !pBoss->IsInSct() ) | ||||
934 | { | ||||
935 | // A sectionframe with the Footnote/EndnAtEnd-flags may contain | ||||
936 | // foot/endnotes. If the last lower frame of the bodyframe is | ||||
937 | // a multicolumned sectionframe, it may contain footnotes, too. | ||||
938 | SwLayoutFrame* pBody = pBoss->FindBodyCont(); | ||||
939 | if( pBody && pBody->Lower() ) | ||||
940 | { | ||||
941 | SwFrame* pLow = pBody->Lower(); | ||||
942 | while (pLow) | ||||
943 | { | ||||
944 | if( pLow->IsSctFrame() && ( !pLow->GetNext() || | ||||
945 | static_cast<SwSectionFrame*>(pLow)->IsAnyNoteAtEnd() ) && | ||||
946 | static_cast<SwSectionFrame*>(pLow)->Lower() && | ||||
947 | static_cast<SwSectionFrame*>(pLow)->Lower()->IsColumnFrame() ) | ||||
948 | sw_RemoveFootnotes( static_cast<SwColumnFrame*>(static_cast<SwSectionFrame*>(pLow)->Lower()), | ||||
949 | bPageOnly, bEndNotes ); | ||||
950 | pLow = pLow->GetNext(); | ||||
951 | } | ||||
952 | } | ||||
953 | } | ||||
954 | // is there another column? | ||||
955 | pBoss = pBoss->IsColumnFrame() ? static_cast<SwColumnFrame*>(pBoss->GetNext()) : nullptr; | ||||
956 | } while( pBoss ); | ||||
957 | } | ||||
958 | |||||
959 | void SwRootFrame::RemoveFootnotes( SwPageFrame *pPage, bool bPageOnly, bool bEndNotes ) | ||||
960 | { | ||||
961 | if ( !pPage ) | ||||
962 | pPage = static_cast<SwPageFrame*>(Lower()); | ||||
963 | |||||
964 | do | ||||
965 | { // On columned pages we have to clean up in all columns | ||||
966 | SwFootnoteBossFrame* pBoss; | ||||
967 | SwLayoutFrame* pBody = pPage->FindBodyCont(); | ||||
968 | if( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrame() ) | ||||
969 | pBoss = static_cast<SwFootnoteBossFrame*>(pBody->Lower()); // the first column | ||||
970 | else | ||||
971 | pBoss = pPage; // no columns | ||||
972 | sw_RemoveFootnotes( pBoss, bPageOnly, bEndNotes ); | ||||
973 | if ( !bPageOnly ) | ||||
974 | { | ||||
975 | if ( pPage->IsFootnotePage() && | ||||
976 | (!pPage->IsEndNotePage() || bEndNotes) ) | ||||
977 | { | ||||
978 | SwFrame *pDel = pPage; | ||||
979 | pPage = static_cast<SwPageFrame*>(pPage->GetNext()); | ||||
980 | pDel->Cut(); | ||||
981 | SwFrame::DestroyFrame(pDel); | ||||
982 | } | ||||
983 | else | ||||
984 | pPage = static_cast<SwPageFrame*>(pPage->GetNext()); | ||||
985 | } | ||||
986 | else | ||||
987 | break; | ||||
988 | |||||
989 | } while ( pPage ); | ||||
990 | } | ||||
991 | |||||
992 | /// Change the page template of the footnote pages | ||||
993 | void SwRootFrame::CheckFootnotePageDescs( bool bEndNote ) | ||||
994 | { | ||||
995 | SwPageFrame *pPage = static_cast<SwPageFrame*>(Lower()); | ||||
996 | while ( pPage && !pPage->IsFootnotePage() ) | ||||
997 | pPage = static_cast<SwPageFrame*>(pPage->GetNext()); | ||||
998 | while ( pPage && pPage->IsEndNotePage() != bEndNote ) | ||||
999 | pPage = static_cast<SwPageFrame*>(pPage->GetNext()); | ||||
1000 | |||||
1001 | if ( pPage ) | ||||
1002 | SwFrame::CheckPageDescs( pPage, false ); | ||||
1003 | } | ||||
1004 | |||||
1005 | /** Insert a footnote container | ||||
1006 | * | ||||
1007 | * A footnote container is always placed directly behind the body text. | ||||
1008 | * | ||||
1009 | * The frame format (FrameFormat) is always the default frame format. | ||||
1010 | * | ||||
1011 | * @return footnote container frame | ||||
1012 | */ | ||||
1013 | SwFootnoteContFrame *SwFootnoteBossFrame::MakeFootnoteCont() | ||||
1014 | { | ||||
1015 | SAL_WARN_IF(FindFootnoteCont(), "sw.core", "footnote container exists already")do { if (true && (FindFootnoteCont())) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "sw.core")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "footnote container exists already" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.core" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "1015" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "footnote container exists already") , 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "footnote container exists already"; ::sal::detail:: log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.core"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "1015" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "footnote container exists already") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.core"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "1015" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "footnote container exists already") , 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "footnote container exists already"; ::sal::detail:: log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.core"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "1015" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||
1016 | |||||
1017 | SwFootnoteContFrame *pNew = new SwFootnoteContFrame( GetFormat()->GetDoc()->GetDfltFrameFormat(), this ); | ||||
1018 | SwLayoutFrame *pLay = FindBodyCont(); | ||||
1019 | pNew->Paste( this, pLay->GetNext() ); | ||||
1020 | return pNew; | ||||
1021 | } | ||||
1022 | |||||
1023 | SwFootnoteContFrame *SwFootnoteBossFrame::FindFootnoteCont() | ||||
1024 | { | ||||
1025 | SwFrame *pFrame = Lower(); | ||||
1026 | while( pFrame && !pFrame->IsFootnoteContFrame() ) | ||||
1027 | pFrame = pFrame->GetNext(); | ||||
1028 | |||||
1029 | #if OSL_DEBUG_LEVEL1 > 0 | ||||
1030 | if ( pFrame ) | ||||
1031 | { | ||||
1032 | SwFrame *pFootnote = pFrame->GetLower(); | ||||
1033 | assert(pFootnote)(static_cast <bool> (pFootnote) ? void (0) : __assert_fail ("pFootnote", "/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" , 1033, __extension__ __PRETTY_FUNCTION__)); | ||||
1034 | while ( pFootnote ) | ||||
1035 | { | ||||
1036 | assert(pFootnote->IsFootnoteFrame() && "Neighbor of footnote must be a footnote")(static_cast <bool> (pFootnote->IsFootnoteFrame() && "Neighbor of footnote must be a footnote") ? void (0) : __assert_fail ("pFootnote->IsFootnoteFrame() && \"Neighbor of footnote must be a footnote\"" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" , 1036, __extension__ __PRETTY_FUNCTION__)); | ||||
1037 | pFootnote = pFootnote->GetNext(); | ||||
1038 | } | ||||
1039 | } | ||||
1040 | #endif | ||||
1041 | |||||
1042 | return static_cast<SwFootnoteContFrame*>(pFrame); | ||||
1043 | } | ||||
1044 | |||||
1045 | /// Search the next available footnote container. | ||||
1046 | SwFootnoteContFrame *SwFootnoteBossFrame::FindNearestFootnoteCont( bool bDontLeave ) | ||||
1047 | { | ||||
1048 | SwFootnoteContFrame *pCont = nullptr; | ||||
1049 | if ( !GetFormat()->GetDoc()->GetFootnoteIdxs().empty() ) | ||||
1050 | { | ||||
1051 | pCont = FindFootnoteCont(); | ||||
1052 | if ( !pCont ) | ||||
1053 | { | ||||
1054 | SwPageFrame *pPage = FindPageFrame(); | ||||
1055 | SwFootnoteBossFrame* pBoss = this; | ||||
1056 | bool bEndNote = pPage->IsEndNotePage(); | ||||
1057 | do | ||||
1058 | { | ||||
1059 | bool bChgPage = lcl_NextFootnoteBoss( pBoss, pPage, bDontLeave ); | ||||
1060 | // Found another boss? When changing pages, also the endnote flag must match. | ||||
1061 | if( pBoss && ( !bChgPage || pPage->IsEndNotePage() == bEndNote ) ) | ||||
1062 | pCont = pBoss->FindFootnoteCont(); | ||||
1063 | } while ( !pCont && pPage ); | ||||
1064 | } | ||||
1065 | } | ||||
1066 | return pCont; | ||||
1067 | } | ||||
1068 | |||||
1069 | SwFootnoteFrame *SwFootnoteBossFrame::FindFirstFootnote() | ||||
1070 | { | ||||
1071 | // search for the nearest footnote container | ||||
1072 | SwFootnoteContFrame *pCont = FindNearestFootnoteCont(); | ||||
1073 | if ( !pCont ) | ||||
1074 | return nullptr; | ||||
1075 | |||||
1076 | // Starting from the first footnote, search the first | ||||
1077 | // footnote that is referenced by the current column/page | ||||
1078 | |||||
1079 | SwFootnoteFrame *pRet = static_cast<SwFootnoteFrame*>(pCont->Lower()); | ||||
1080 | const sal_uInt16 nRefNum = FindPageFrame()->GetPhyPageNum(); | ||||
1081 | const sal_uInt16 nRefCol = lcl_ColumnNum( this ); | ||||
1082 | sal_uInt16 nPgNum, nColNum; // page number, column number | ||||
1083 | SwFootnoteBossFrame* pBoss; | ||||
1084 | SwPageFrame* pPage; | ||||
1085 | if( pRet ) | ||||
1086 | { | ||||
1087 | pBoss = pRet->GetRef()->FindFootnoteBossFrame(); | ||||
1088 | OSL_ENSURE( pBoss, "FindFirstFootnote: No boss found" )do { if (true && (!(pBoss))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "1088" ": "), "%s", "FindFirstFootnote: No boss found"); } } while (false); | ||||
1089 | if( !pBoss ) | ||||
1090 | return nullptr; // ?There must be a bug, but no GPF | ||||
1091 | pPage = pBoss->FindPageFrame(); | ||||
1092 | nPgNum = pPage->GetPhyPageNum(); | ||||
1093 | if ( nPgNum == nRefNum ) | ||||
1094 | { | ||||
1095 | nColNum = lcl_ColumnNum( pBoss ); | ||||
1096 | if( nColNum == nRefCol ) | ||||
1097 | return pRet; // found | ||||
1098 | else if( nColNum > nRefCol ) | ||||
1099 | return nullptr; // at least one column too far | ||||
1100 | } | ||||
1101 | else if ( nPgNum > nRefNum ) | ||||
1102 | return nullptr; // at least one column too far | ||||
1103 | } | ||||
1104 | else | ||||
1105 | return nullptr; | ||||
1106 | // Done if Ref is on a subsequent page or on the same page in a subsequent column | ||||
1107 | |||||
1108 | do | ||||
1109 | { | ||||
1110 | while ( pRet->GetFollow() ) | ||||
1111 | pRet = pRet->GetFollow(); | ||||
1112 | |||||
1113 | SwFootnoteFrame *pNxt = static_cast<SwFootnoteFrame*>(pRet->GetNext()); | ||||
1114 | if ( !pNxt ) | ||||
1115 | { | ||||
1116 | pBoss = pRet->FindFootnoteBossFrame(); | ||||
1117 | pPage = pBoss->FindPageFrame(); | ||||
1118 | lcl_NextFootnoteBoss( pBoss, pPage, false ); // next FootnoteBoss | ||||
1119 | pCont = pBoss ? pBoss->FindNearestFootnoteCont() : nullptr; | ||||
1120 | if ( pCont ) | ||||
1121 | pNxt = static_cast<SwFootnoteFrame*>(pCont->Lower()); | ||||
1122 | } | ||||
1123 | if ( pNxt ) | ||||
1124 | { | ||||
1125 | pRet = pNxt; | ||||
1126 | pBoss = pRet->GetRef()->FindFootnoteBossFrame(); | ||||
1127 | pPage = pBoss->FindPageFrame(); | ||||
1128 | nPgNum = pPage->GetPhyPageNum(); | ||||
1129 | if ( nPgNum == nRefNum ) | ||||
1130 | { | ||||
1131 | nColNum = lcl_ColumnNum( pBoss ); | ||||
1132 | if( nColNum == nRefCol ) | ||||
1133 | break; // found | ||||
1134 | else if( nColNum > nRefCol ) | ||||
1135 | pRet = nullptr; // at least one column too far | ||||
1136 | } | ||||
1137 | else if ( nPgNum > nRefNum ) | ||||
1138 | pRet = nullptr; // at least a page too far | ||||
1139 | } | ||||
1140 | else | ||||
1141 | pRet = nullptr; // there is none | ||||
1142 | } while( pRet ); | ||||
1143 | return pRet; | ||||
1144 | } | ||||
1145 | |||||
1146 | /// Get the first footnote of a given content | ||||
1147 | const SwFootnoteFrame *SwFootnoteBossFrame::FindFirstFootnote( SwContentFrame const *pCnt ) const | ||||
1148 | { | ||||
1149 | const SwFootnoteFrame *pRet = const_cast<SwFootnoteBossFrame*>(this)->FindFirstFootnote(); | ||||
1150 | if ( pRet ) | ||||
1151 | { | ||||
1152 | const sal_uInt16 nColNum = lcl_ColumnNum( this ); | ||||
1153 | const sal_uInt16 nPageNum = GetPhyPageNum(); | ||||
1154 | while ( pRet && (pRet->GetRef() != pCnt) ) | ||||
1155 | { | ||||
1156 | while ( pRet->GetFollow() ) | ||||
1157 | pRet = pRet->GetFollow(); | ||||
1158 | |||||
1159 | if ( pRet->GetNext() ) | ||||
1160 | pRet = static_cast<const SwFootnoteFrame*>(pRet->GetNext()); | ||||
1161 | else | ||||
1162 | { SwFootnoteBossFrame *pBoss = const_cast<SwFootnoteBossFrame*>(pRet->FindFootnoteBossFrame()); | ||||
1163 | SwPageFrame *pPage = pBoss->FindPageFrame(); | ||||
1164 | lcl_NextFootnoteBoss( pBoss, pPage, false ); // next FootnoteBoss | ||||
1165 | SwFootnoteContFrame *pCont = pBoss ? pBoss->FindNearestFootnoteCont() : nullptr; | ||||
1166 | pRet = pCont ? static_cast<SwFootnoteFrame*>(pCont->Lower()) : nullptr; | ||||
1167 | } | ||||
1168 | if ( pRet ) | ||||
1169 | { | ||||
1170 | const SwFootnoteBossFrame* pBoss = pRet->GetRef()->FindFootnoteBossFrame(); | ||||
1171 | if( pBoss->GetPhyPageNum() != nPageNum || | ||||
1172 | nColNum != lcl_ColumnNum( pBoss ) ) | ||||
1173 | pRet = nullptr; | ||||
1174 | } | ||||
1175 | } | ||||
1176 | } | ||||
1177 | return pRet; | ||||
1178 | } | ||||
1179 | |||||
1180 | void SwFootnoteBossFrame::ResetFootnote( const SwFootnoteFrame *pCheck ) | ||||
1181 | { | ||||
1182 | // Destroy the incarnations of footnotes to an attribute, if they don't | ||||
1183 | // belong to pAssumed | ||||
1184 | OSL_ENSURE( !pCheck->GetMaster(), "given master is not a Master." )do { if (true && (!(!pCheck->GetMaster()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "1184" ": "), "%s", "given master is not a Master."); } } while (false); | ||||
1185 | |||||
1186 | SwNodeIndex aIdx( *pCheck->GetAttr()->GetStartNode(), 1 ); | ||||
1187 | SwContentNode *pNd = aIdx.GetNode().GetContentNode(); | ||||
1188 | if ( !pNd ) | ||||
1189 | pNd = pCheck->GetFormat()->GetDoc()-> | ||||
1190 | GetNodes().GoNextSection( &aIdx, true, false ); | ||||
1191 | SwIterator<SwFrame, SwContentNode, sw::IteratorMode::UnwrapMulti> aIter(*pNd); | ||||
1192 | SwFrame* pFrame = aIter.First(); | ||||
1193 | while( pFrame ) | ||||
1194 | { | ||||
1195 | if( pFrame->getRootFrame() == pCheck->getRootFrame() ) | ||||
1196 | { | ||||
1197 | SwFrame *pTmp = pFrame->GetUpper(); | ||||
1198 | while ( pTmp && !pTmp->IsFootnoteFrame() ) | ||||
1199 | pTmp = pTmp->GetUpper(); | ||||
1200 | |||||
1201 | SwFootnoteFrame *pFootnote = static_cast<SwFootnoteFrame*>(pTmp); | ||||
1202 | while ( pFootnote && pFootnote->GetMaster() ) | ||||
1203 | pFootnote = pFootnote->GetMaster(); | ||||
1204 | if ( pFootnote != pCheck ) | ||||
1205 | { | ||||
1206 | while (pFootnote && !pFootnote->IsDeleteForbidden()) | ||||
1207 | { | ||||
1208 | SwFootnoteFrame *pNxt = pFootnote->GetFollow(); | ||||
1209 | pFootnote->Cut(); | ||||
1210 | SwFrame::DestroyFrame(pFootnote); | ||||
1211 | pFootnote = pNxt; | ||||
1212 | } | ||||
1213 | } | ||||
1214 | } | ||||
1215 | |||||
1216 | pFrame = aIter.Next(); | ||||
1217 | } | ||||
1218 | } | ||||
1219 | |||||
1220 | void SwFootnoteBossFrame::InsertFootnote( SwFootnoteFrame* pNew ) | ||||
1221 | { | ||||
1222 | // Place the footnote in front of the footnote whose attribute | ||||
1223 | // is in front of the new one (get position via the Doc). | ||||
1224 | // If there is no footnote in this footnote-boss yet, create a new container. | ||||
1225 | // If there is a container but no footnote for this footnote-boss yet, place | ||||
1226 | // the footnote behind the last footnote of the closest previous column/page. | ||||
1227 | |||||
1228 | ResetFootnote( pNew ); | ||||
1229 | SwFootnoteFrame *pSibling = FindFirstFootnote(); | ||||
1230 | bool bDontLeave = false; | ||||
1231 | |||||
1232 | // Ok, a sibling has been found, but is the sibling in an acceptable | ||||
1233 | // environment? | ||||
1234 | if( IsInSct() ) | ||||
1235 | { | ||||
1236 | SwSectionFrame* pMySect = ImplFindSctFrame(); | ||||
1237 | bool bEndnt = pNew->GetAttr()->GetFootnote().IsEndNote(); | ||||
1238 | if( bEndnt ) | ||||
1239 | { | ||||
1240 | const SwSectionFormat* pEndFormat = pMySect->GetEndSectFormat(); | ||||
1241 | bDontLeave = nullptr != pEndFormat; | ||||
1242 | if( pSibling ) | ||||
1243 | { | ||||
1244 | if( pEndFormat ) | ||||
1245 | { | ||||
1246 | if( !pSibling->IsInSct() || | ||||
1247 | !pSibling->ImplFindSctFrame()->IsDescendantFrom( pEndFormat ) ) | ||||
1248 | pSibling = nullptr; | ||||
1249 | } | ||||
1250 | else if( pSibling->IsInSct() ) | ||||
1251 | pSibling = nullptr; | ||||
1252 | } | ||||
1253 | } | ||||
1254 | else | ||||
1255 | { | ||||
1256 | bDontLeave = pMySect->IsFootnoteAtEnd(); | ||||
1257 | if( pSibling ) | ||||
1258 | { | ||||
1259 | if( pMySect->IsFootnoteAtEnd() ) | ||||
1260 | { | ||||
1261 | if( !pSibling->IsInSct() || | ||||
1262 | !pMySect->IsAnFollow( pSibling->ImplFindSctFrame() ) ) | ||||
1263 | pSibling = nullptr; | ||||
1264 | } | ||||
1265 | else if( pSibling->IsInSct() ) | ||||
1266 | pSibling = nullptr; | ||||
1267 | } | ||||
1268 | } | ||||
1269 | } | ||||
1270 | |||||
1271 | if( pSibling && pSibling->FindPageFrame()->IsEndNotePage() != | ||||
1272 | FindPageFrame()->IsEndNotePage() ) | ||||
1273 | pSibling = nullptr; | ||||
1274 | |||||
1275 | // use the Doc to find out the position | ||||
1276 | SwDoc *pDoc = GetFormat()->GetDoc(); | ||||
1277 | const sal_uLong nStPos = ::lcl_FindFootnotePos( pDoc, pNew->GetAttr() ); | ||||
1278 | |||||
1279 | sal_uLong nCmpPos = 0; | ||||
1280 | sal_uLong nLastPos = 0; | ||||
1281 | SwFootnoteContFrame *pParent = nullptr; | ||||
1282 | if( pSibling ) | ||||
1283 | { | ||||
1284 | nCmpPos = ::lcl_FindFootnotePos( pDoc, pSibling->GetAttr() ); | ||||
1285 | if( nCmpPos > nStPos ) | ||||
1286 | pSibling = nullptr; | ||||
1287 | } | ||||
1288 | |||||
1289 | if ( !pSibling ) | ||||
1290 | { pParent = FindFootnoteCont(); | ||||
1291 | if ( !pParent ) | ||||
1292 | { | ||||
1293 | // There is no footnote container yet. Before creating one, keep in mind that | ||||
1294 | // there might exist another following footnote that must be placed before the | ||||
1295 | // new inserted one e.g. because it was divided over multiple pages etc. | ||||
1296 | pParent = FindNearestFootnoteCont( bDontLeave ); | ||||
1297 | if ( pParent ) | ||||
1298 | { | ||||
1299 | SwFootnoteFrame *pFootnote = static_cast<SwFootnoteFrame*>(pParent->Lower()); | ||||
1300 | if ( pFootnote ) | ||||
1301 | { | ||||
1302 | |||||
1303 | nCmpPos = ::lcl_FindFootnotePos( pDoc, pFootnote->GetAttr() ); | ||||
1304 | if ( nCmpPos > nStPos ) | ||||
1305 | pParent = nullptr; | ||||
1306 | } | ||||
1307 | else | ||||
1308 | pParent = nullptr; | ||||
1309 | } | ||||
1310 | } | ||||
1311 | if ( !pParent ) | ||||
1312 | // here, we are sure that we can create a footnote container | ||||
1313 | pParent = MakeFootnoteCont(); | ||||
1314 | else | ||||
1315 | { | ||||
1316 | // Based on the first footnote below the Parent, search for the first footnote whose | ||||
1317 | // index is after the index of the newly inserted, to place the new one correctly | ||||
1318 | pSibling = static_cast<SwFootnoteFrame*>(pParent->Lower()); | ||||
1319 | if ( !pSibling ) | ||||
1320 | { | ||||
1321 | OSL_ENSURE( false, "Could not find space for footnote.")do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "1321" ": "), "%s", "Could not find space for footnote." ); } } while (false); | ||||
1322 | return; | ||||
1323 | } | ||||
1324 | nCmpPos = ::lcl_FindFootnotePos( pDoc, pSibling->GetAttr() ); | ||||
1325 | |||||
1326 | SwFootnoteBossFrame *pNxtB; // remember the last one to not | ||||
1327 | SwFootnoteFrame *pLastSib = nullptr; // go too far. | ||||
1328 | |||||
1329 | while ( pSibling && nCmpPos <= nStPos ) | ||||
1330 | { | ||||
1331 | pLastSib = pSibling; // potential candidate | ||||
1332 | nLastPos = nCmpPos; | ||||
1333 | |||||
1334 | while ( pSibling->GetFollow() ) | ||||
1335 | pSibling = pSibling->GetFollow(); | ||||
1336 | |||||
1337 | if ( pSibling->GetNext() ) | ||||
1338 | { | ||||
1339 | pSibling = static_cast<SwFootnoteFrame*>(pSibling->GetNext()); | ||||
1340 | OSL_ENSURE( !pSibling->GetMaster() || ( ENDNOTE > nStPos &&do { if (true && (!(!pSibling->GetMaster() || ( 0x80000000 > nStPos && pSibling->GetAttr()->GetFootnote ().IsEndNote() )))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "1342" ": "), "%s", "InsertFootnote: Master expected I") ; } } while (false) | ||||
1341 | pSibling->GetAttr()->GetFootnote().IsEndNote() ),do { if (true && (!(!pSibling->GetMaster() || ( 0x80000000 > nStPos && pSibling->GetAttr()->GetFootnote ().IsEndNote() )))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "1342" ": "), "%s", "InsertFootnote: Master expected I") ; } } while (false) | ||||
1342 | "InsertFootnote: Master expected I" )do { if (true && (!(!pSibling->GetMaster() || ( 0x80000000 > nStPos && pSibling->GetAttr()->GetFootnote ().IsEndNote() )))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "1342" ": "), "%s", "InsertFootnote: Master expected I") ; } } while (false); | ||||
1343 | } | ||||
1344 | else | ||||
1345 | { | ||||
1346 | pNxtB = pSibling->FindFootnoteBossFrame(); | ||||
1347 | SwPageFrame *pSibPage = pNxtB->FindPageFrame(); | ||||
1348 | bool bEndNote = pSibPage->IsEndNotePage(); | ||||
1349 | bool bChgPage = lcl_NextFootnoteBoss( pNxtB, pSibPage, bDontLeave ); | ||||
1350 | // When changing pages, also the endnote flag must match. | ||||
1351 | SwFootnoteContFrame *pCont = pNxtB && ( !bChgPage || | ||||
1352 | pSibPage->IsEndNotePage() == bEndNote ) | ||||
1353 | ? pNxtB->FindNearestFootnoteCont( bDontLeave ) : nullptr; | ||||
1354 | if( pCont ) | ||||
1355 | pSibling = static_cast<SwFootnoteFrame*>(pCont->Lower()); | ||||
1356 | else // no further FootnoteContainer, insert after pSibling | ||||
1357 | break; | ||||
1358 | } | ||||
1359 | if ( pSibling ) | ||||
1360 | { | ||||
1361 | nCmpPos = ::lcl_FindFootnotePos( pDoc, pSibling->GetAttr() ); | ||||
1362 | OSL_ENSURE( nCmpPos > nLastPos, "InsertFootnote: Order of FootnoteFrame's buggy" )do { if (true && (!(nCmpPos > nLastPos))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "1362" ": "), "%s", "InsertFootnote: Order of FootnoteFrame's buggy" ); } } while (false); | ||||
1363 | } | ||||
1364 | } | ||||
1365 | // pLastSib is the last footnote before the new one and | ||||
1366 | // pSibling is empty or the first one after the new one | ||||
1367 | if ( pSibling && pLastSib && (pSibling != pLastSib) ) | ||||
1368 | { | ||||
1369 | // too far? | ||||
1370 | if ( nCmpPos > nStPos ) | ||||
1371 | pSibling = pLastSib; | ||||
1372 | } | ||||
1373 | else if ( !pSibling ) | ||||
1374 | { | ||||
1375 | // Last chance: Take the last footnote of the parent. | ||||
1376 | // Special case that happens e.g. when moving paragraphs with multiple footnotes. | ||||
1377 | // To keep the order, use the parent of the last inspected footnote. | ||||
1378 | pSibling = pLastSib; | ||||
1379 | while( pSibling->GetFollow() ) | ||||
1380 | pSibling = pSibling->GetFollow(); | ||||
1381 | OSL_ENSURE( !pSibling->GetNext(), "InsertFootnote: Who's that guy?" )do { if (true && (!(!pSibling->GetNext()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "1381" ": "), "%s", "InsertFootnote: Who's that guy?"); } } while (false); | ||||
1382 | } | ||||
1383 | } | ||||
1384 | } | ||||
1385 | else | ||||
1386 | { | ||||
1387 | // First footnote of the column/page found. Now search from there for the first one on the | ||||
1388 | // same column/page whose index is after the given one. The last one found is the predecessor. | ||||
1389 | SwFootnoteBossFrame* pBoss = pNew->GetRef()->FindFootnoteBossFrame( | ||||
1390 | !pNew->GetAttr()->GetFootnote().IsEndNote() ); | ||||
1391 | sal_uInt16 nRefNum = pBoss->GetPhyPageNum(); // page number of the new footnote | ||||
1392 | sal_uInt16 nRefCol = lcl_ColumnNum( pBoss ); // column number of the new footnote | ||||
1393 | bool bEnd = false; | ||||
1394 | SwFootnoteFrame *pLastSib = nullptr; | ||||
1395 | while ( pSibling && !bEnd && (nCmpPos <= nStPos) ) | ||||
1396 | { | ||||
1397 | pLastSib = pSibling; | ||||
1398 | nLastPos = nCmpPos; | ||||
1399 | |||||
1400 | while ( pSibling->GetFollow() ) | ||||
1401 | pSibling = pSibling->GetFollow(); | ||||
1402 | |||||
1403 | SwFootnoteFrame *pFoll = static_cast<SwFootnoteFrame*>(pSibling->GetNext()); | ||||
1404 | if ( pFoll ) | ||||
1405 | { | ||||
1406 | pBoss = pSibling->GetRef()->FindFootnoteBossFrame( !pSibling-> | ||||
1407 | GetAttr()->GetFootnote().IsEndNote() ); | ||||
1408 | sal_uInt16 nTmpRef; | ||||
1409 | if( nStPos >= ENDNOTE0x80000000 || | ||||
1410 | (nTmpRef = pBoss->GetPhyPageNum()) < nRefNum || | ||||
1411 | ( nTmpRef == nRefNum && lcl_ColumnNum( pBoss ) <= nRefCol )) | ||||
1412 | pSibling = pFoll; | ||||
1413 | else | ||||
1414 | bEnd = true; | ||||
1415 | } | ||||
1416 | else | ||||
1417 | { | ||||
1418 | SwFootnoteBossFrame* pNxtB = pSibling->FindFootnoteBossFrame(); | ||||
1419 | SwPageFrame *pSibPage = pNxtB->FindPageFrame(); | ||||
1420 | bool bEndNote = pSibPage->IsEndNotePage(); | ||||
1421 | bool bChgPage = lcl_NextFootnoteBoss( pNxtB, pSibPage, bDontLeave ); | ||||
1422 | // When changing pages, also the endnote flag must match. | ||||
1423 | SwFootnoteContFrame *pCont = pNxtB && ( !bChgPage || | ||||
1424 | pSibPage->IsEndNotePage() == bEndNote ) | ||||
1425 | ? pNxtB->FindNearestFootnoteCont( bDontLeave ) : nullptr; | ||||
1426 | if ( pCont ) | ||||
1427 | pSibling = static_cast<SwFootnoteFrame*>(pCont->Lower()); | ||||
1428 | else | ||||
1429 | bEnd = true; | ||||
1430 | } | ||||
1431 | if ( !bEnd && pSibling ) | ||||
1432 | nCmpPos = ::lcl_FindFootnotePos( pDoc, pSibling->GetAttr() ); | ||||
1433 | if (pSibling && (pSibling != pLastSib)) | ||||
1434 | { | ||||
1435 | // too far? | ||||
1436 | if ( (nLastPos < nCmpPos) && (nCmpPos > nStPos) ) | ||||
1437 | { | ||||
1438 | pSibling = pLastSib; | ||||
1439 | bEnd = true; | ||||
1440 | } | ||||
1441 | } | ||||
1442 | } | ||||
1443 | } | ||||
1444 | if ( pSibling ) | ||||
1445 | { | ||||
1446 | nCmpPos = ::lcl_FindFootnotePos( pDoc, pSibling->GetAttr() ); | ||||
1447 | if ( nCmpPos < nStPos ) | ||||
1448 | { | ||||
1449 | while ( pSibling->GetFollow() ) | ||||
1450 | pSibling = pSibling->GetFollow(); | ||||
1451 | pParent = static_cast<SwFootnoteContFrame*>(pSibling->GetUpper()); | ||||
1452 | pSibling = static_cast<SwFootnoteFrame*>(pSibling->GetNext()); | ||||
1453 | } | ||||
1454 | else | ||||
1455 | { | ||||
1456 | if( pSibling->GetMaster() ) | ||||
1457 | { | ||||
1458 | if( ENDNOTE0x80000000 > nCmpPos || nStPos >= ENDNOTE0x80000000 ) | ||||
1459 | { | ||||
1460 | OSL_FAIL( "InsertFootnote: Master expected II" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "1460" ": "), "%s", "InsertFootnote: Master expected II" ); } } while (false); | ||||
1461 | do | ||||
1462 | pSibling = pSibling->GetMaster(); | ||||
1463 | while ( pSibling->GetMaster() ); | ||||
1464 | } | ||||
1465 | } | ||||
1466 | pParent = static_cast<SwFootnoteContFrame*>(pSibling->GetUpper()); | ||||
1467 | } | ||||
1468 | } | ||||
1469 | OSL_ENSURE( pParent, "paste in space?" )do { if (true && (!(pParent))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "1469" ": "), "%s", "paste in space?"); } } while (false ); | ||||
1470 | pNew->Paste( pParent, pSibling ); | ||||
1471 | } | ||||
1472 | |||||
1473 | static SwPageFrame* lcl_GetApproximateFootnotePage(const bool bEnd, const SwPageFrame* pPage, | ||||
1474 | const SwDoc *pDoc, const SwTextFootnote *pAttr) | ||||
1475 | { | ||||
1476 | // We can at least search the approximately correct page | ||||
1477 | // to ensure that we will finish in finite time even if | ||||
1478 | // hundreds of footnotes exist. | ||||
1479 | const SwPageFrame *pNxt = static_cast<const SwPageFrame*>(pPage->GetNext()); | ||||
1480 | const sal_uLong nStPos = ::lcl_FindFootnotePos(pDoc, pAttr); | ||||
1481 | while (pNxt && (bEnd ? pNxt->IsEndNotePage() : pNxt->IsFootnotePage() && !pNxt->IsEndNotePage())) | ||||
1482 | { | ||||
1483 | const SwFootnoteContFrame *pCont = pNxt->FindFootnoteCont(); | ||||
1484 | if (pCont && pCont->Lower()) | ||||
1485 | { | ||||
1486 | OSL_ENSURE( pCont->Lower()->IsFootnoteFrame(), "no footnote in the container" )do { if (true && (!(pCont->Lower()->IsFootnoteFrame ()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "1486" ": "), "%s", "no footnote in the container"); } } while (false); | ||||
1487 | if (nStPos > ::lcl_FindFootnotePos(pDoc, | ||||
1488 | static_cast<const SwFootnoteFrame*>(pCont->Lower())->GetAttr())) | ||||
1489 | { | ||||
1490 | pPage = pNxt; | ||||
1491 | pNxt = static_cast<const SwPageFrame*>(pPage->GetNext()); | ||||
1492 | continue; | ||||
1493 | } | ||||
1494 | } | ||||
1495 | break; | ||||
1496 | } | ||||
1497 | return const_cast<SwPageFrame*>(pPage); | ||||
1498 | } | ||||
1499 | |||||
1500 | void SwFootnoteBossFrame::AppendFootnote( SwContentFrame *pRef, SwTextFootnote *pAttr ) | ||||
1501 | { | ||||
1502 | // If the footnote already exists, do nothing. | ||||
1503 | if ( FindFootnote( pRef, pAttr ) ) | ||||
1504 | return; | ||||
1505 | |||||
1506 | // If footnotes are inserted at the end of the document, | ||||
1507 | // we only need to search from the relevant page on. | ||||
1508 | // If there is none yet, we need to create one. | ||||
1509 | // If it is an Endnote, we need to search for or create an | ||||
1510 | // Endnote page. | ||||
1511 | SwDoc *pDoc = GetFormat()->GetDoc(); | ||||
1512 | SwFootnoteBossFrame *pBoss = this; | ||||
1513 | SwPageFrame *pPage = FindPageFrame(); | ||||
1514 | SwPageFrame *pMyPage = pPage; | ||||
1515 | bool bChgPage = false; | ||||
1516 | const bool bEnd = pAttr->GetFootnote().IsEndNote(); | ||||
1517 | if (bEnd) | ||||
1518 | { | ||||
1519 | const IDocumentSettingAccess& rSettings = *pAttr->GetTextNode().getIDocumentSettingAccess(); | ||||
1520 | if( GetUpper()->IsSctFrame() && | ||||
1521 | static_cast<SwSectionFrame*>(GetUpper())->IsEndnAtEnd() ) | ||||
1522 | { | ||||
1523 | // Endnotes at the end of the section. | ||||
1524 | SwFrame* pLast = | ||||
1525 | static_cast<SwSectionFrame*>(GetUpper())->FindLastContent( SwFindMode::EndNote ); | ||||
1526 | if( pLast ) | ||||
1527 | { | ||||
1528 | pBoss = pLast->FindFootnoteBossFrame(); | ||||
1529 | pPage = pBoss->FindPageFrame(); | ||||
1530 | } | ||||
1531 | } | ||||
1532 | else if (rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES)) | ||||
1533 | { | ||||
1534 | // Endnotes at the end of the document. | ||||
1535 | pBoss = getRootFrame()->GetLastPage(); | ||||
1536 | pPage = pBoss->FindPageFrame(); | ||||
1537 | } | ||||
1538 | else | ||||
1539 | { | ||||
1540 | // Endnotes on a separate page. | ||||
1541 | while ( pPage->GetNext() && !pPage->IsEndNotePage() ) | ||||
1542 | { | ||||
1543 | pPage = static_cast<SwPageFrame*>(pPage->GetNext()); | ||||
1544 | bChgPage = true; | ||||
1545 | } | ||||
1546 | if ( !pPage->IsEndNotePage() ) | ||||
1547 | { | ||||
1548 | SwPageDesc *pDesc = pDoc->GetEndNoteInfo().GetPageDesc( *pDoc ); | ||||
1549 | pPage = ::InsertNewPage( *pDesc, pPage->GetUpper(), | ||||
1550 | !pPage->OnRightPage(), false, false, true, nullptr ); | ||||
1551 | pPage->SetEndNotePage( true ); | ||||
1552 | bChgPage = true; | ||||
1553 | } | ||||
1554 | else | ||||
1555 | pPage = lcl_GetApproximateFootnotePage(true, pPage, pDoc, pAttr); | ||||
1556 | } | ||||
1557 | } | ||||
1558 | else if( FTNPOS_CHAPTER == pDoc->GetFootnoteInfo().m_ePos && ( !GetUpper()-> | ||||
1559 | IsSctFrame() || !static_cast<SwSectionFrame*>(GetUpper())->IsFootnoteAtEnd() ) ) | ||||
1560 | { | ||||
1561 | while ( pPage->GetNext() && !pPage->IsFootnotePage() && | ||||
1562 | !static_cast<SwPageFrame*>(pPage->GetNext())->IsEndNotePage() ) | ||||
1563 | { | ||||
1564 | pPage = static_cast<SwPageFrame*>(pPage->GetNext()); | ||||
1565 | bChgPage = true; | ||||
1566 | } | ||||
1567 | |||||
1568 | if ( !pPage->IsFootnotePage() ) | ||||
1569 | { | ||||
1570 | SwPageDesc *pDesc = pDoc->GetFootnoteInfo().GetPageDesc( *pDoc ); | ||||
1571 | pPage = ::InsertNewPage( *pDesc, pPage->GetUpper(), | ||||
1572 | !pPage->OnRightPage(), false, false, true, pPage->GetNext() ); | ||||
1573 | bChgPage = true; | ||||
1574 | } | ||||
1575 | else | ||||
1576 | pPage = lcl_GetApproximateFootnotePage(false, pPage, pDoc, pAttr); | ||||
1577 | } | ||||
1578 | |||||
1579 | // For now, create a footnote and the corresponding content frames | ||||
1580 | if ( !pAttr->GetStartNode() ) | ||||
1581 | { | ||||
1582 | OSL_ENSURE( false, "no footnote content." )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "1582" ": "), "%s", "no footnote content."); } } while ( false); | ||||
1583 | return; | ||||
1584 | } | ||||
1585 | |||||
1586 | // If there is already a footnote content on the column/page, | ||||
1587 | // another one cannot be created in a column area. | ||||
1588 | if( pBoss->IsInSct() && pBoss->IsColumnFrame() && !pPage->IsFootnotePage() ) | ||||
1589 | { | ||||
1590 | SwSectionFrame* pSct = pBoss->FindSctFrame(); | ||||
1591 | if( bEnd ? !pSct->IsEndnAtEnd() : !pSct->IsFootnoteAtEnd() ) | ||||
1592 | { | ||||
1593 | SwFootnoteContFrame* pFootnoteCont = pSct->FindFootnoteBossFrame(!bEnd)->FindFootnoteCont(); | ||||
1594 | if( pFootnoteCont ) | ||||
1595 | { | ||||
1596 | SwFootnoteFrame* pTmp = static_cast<SwFootnoteFrame*>(pFootnoteCont->Lower()); | ||||
1597 | if( bEnd ) | ||||
1598 | while( pTmp && !pTmp->GetAttr()->GetFootnote().IsEndNote() ) | ||||
1599 | pTmp = static_cast<SwFootnoteFrame*>(pTmp->GetNext()); | ||||
1600 | if( pTmp && *pTmp < pAttr ) | ||||
1601 | return; | ||||
1602 | } | ||||
1603 | } | ||||
1604 | } | ||||
1605 | |||||
1606 | SwFootnoteFrame *pNew = new SwFootnoteFrame( pDoc->GetDfltFrameFormat(), this, pRef, pAttr ); | ||||
1607 | { | ||||
1608 | SwNodeIndex aIdx( *pAttr->GetStartNode(), 1 ); | ||||
1609 | ::InsertCnt_( pNew, pDoc, aIdx.GetIndex() ); | ||||
1610 | } | ||||
1611 | // If the page was changed or newly created, | ||||
1612 | // we need to place ourselves in the first column | ||||
1613 | if( bChgPage ) | ||||
1614 | { | ||||
1615 | SwLayoutFrame* pBody = pPage->FindBodyCont(); | ||||
1616 | OSL_ENSURE( pBody, "AppendFootnote: NoPageBody?" )do { if (true && (!(pBody))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "1616" ": "), "%s", "AppendFootnote: NoPageBody?"); } } while (false); | ||||
1617 | if( pBody->Lower() && pBody->Lower()->IsColumnFrame() ) | ||||
1618 | pBoss = static_cast<SwFootnoteBossFrame*>(pBody->Lower()); | ||||
1619 | else | ||||
1620 | pBoss = pPage; // page if no columns exist | ||||
1621 | } | ||||
1622 | pBoss->InsertFootnote( pNew ); | ||||
1623 | if ( pNew->GetUpper() ) // inserted or not? | ||||
1624 | { | ||||
1625 | ::RegistFlys( pNew->FindPageFrame(), pNew ); | ||||
1626 | SwSectionFrame* pSect = FindSctFrame(); | ||||
1627 | // The content of a FootnoteContainer in a (column) section only need to be calculated | ||||
1628 | // if the section stretches already to the bottom edge of the Upper. | ||||
1629 | if( pSect && !pSect->IsJoinLocked() && ( bEnd ? !pSect->IsEndnAtEnd() : | ||||
1630 | !pSect->IsFootnoteAtEnd() ) && pSect->Growable() ) | ||||
1631 | pSect->InvalidateSize(); | ||||
1632 | else | ||||
1633 | { | ||||
1634 | // #i49383# - disable unlock of position of | ||||
1635 | // lower objects during format of footnote content. | ||||
1636 | const bool bOldFootnoteFrameLocked( pNew->IsColLocked() ); | ||||
1637 | pNew->ColLock(); | ||||
1638 | pNew->KeepLockPosOfLowerObjs(); | ||||
1639 | // #i57914# - adjust fix #i49383# | ||||
1640 | SwContentFrame *pCnt = pNew->ContainsContent(); | ||||
1641 | while ( pCnt && pCnt->FindFootnoteFrame()->GetAttr() == pAttr ) | ||||
1642 | { | ||||
1643 | pCnt->Calc(getRootFrame()->GetCurrShell()->GetOut()); | ||||
1644 | // #i49383# - format anchored objects | ||||
1645 | if ( pCnt->IsTextFrame() && pCnt->isFrameAreaDefinitionValid() ) | ||||
1646 | { | ||||
1647 | if ( !SwObjectFormatter::FormatObjsAtFrame( *pCnt, | ||||
1648 | *(pCnt->FindPageFrame()) ) ) | ||||
1649 | { | ||||
1650 | // restart format with first content | ||||
1651 | pCnt = pNew->ContainsContent(); | ||||
1652 | continue; | ||||
1653 | } | ||||
1654 | } | ||||
1655 | pCnt = pCnt->FindNextCnt(); | ||||
1656 | } | ||||
1657 | // #i49383# | ||||
1658 | if ( !bOldFootnoteFrameLocked ) | ||||
1659 | { | ||||
1660 | pNew->ColUnlock(); | ||||
1661 | } | ||||
1662 | // #i57914# - adjust fix #i49383# | ||||
1663 | // enable lock of lower object position before format of footnote frame. | ||||
1664 | pNew->UnlockPosOfLowerObjs(); | ||||
1665 | pNew->Calc(getRootFrame()->GetCurrShell()->GetOut()); | ||||
1666 | // #i57914# - adjust fix #i49383# | ||||
1667 | if ( !bOldFootnoteFrameLocked && !pNew->GetLower() && | ||||
1668 | !pNew->IsColLocked() && !pNew->IsBackMoveLocked() && | ||||
1669 | !pNew->IsDeleteForbidden() ) | ||||
1670 | { | ||||
1671 | pNew->Cut(); | ||||
1672 | SwFrame::DestroyFrame(pNew); | ||||
1673 | } | ||||
1674 | } | ||||
1675 | pMyPage->UpdateFootnoteNum(); | ||||
1676 | } | ||||
1677 | else | ||||
1678 | SwFrame::DestroyFrame(pNew); | ||||
1679 | } | ||||
1680 | |||||
1681 | SwFootnoteFrame *SwFootnoteBossFrame::FindFootnote( const SwContentFrame *pRef, const SwTextFootnote *pAttr ) | ||||
1682 | { | ||||
1683 | // the easiest and savest way goes via the attribute | ||||
1684 | OSL_ENSURE( pAttr->GetStartNode(), "FootnoteAtr without StartNode." )do { if (true && (!(pAttr->GetStartNode()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "1684" ": "), "%s", "FootnoteAtr without StartNode."); } } while (false); | ||||
1685 | SwNodeIndex aIdx( *pAttr->GetStartNode(), 1 ); | ||||
1686 | SwContentNode *pNd = aIdx.GetNode().GetContentNode(); | ||||
1687 | if ( !pNd ) | ||||
1688 | pNd = pRef->GetAttrSet()->GetDoc()-> | ||||
1689 | GetNodes().GoNextSection( &aIdx, true, false ); | ||||
1690 | if ( !pNd ) | ||||
1691 | return nullptr; | ||||
1692 | SwIterator<SwFrame, SwContentNode, sw::IteratorMode::UnwrapMulti> aIter(*pNd); | ||||
1693 | SwFrame* pFrame = aIter.First(); | ||||
1694 | if( pFrame ) | ||||
1695 | do | ||||
1696 | { | ||||
1697 | pFrame = pFrame->GetUpper(); | ||||
1698 | // #i28500#, #i27243# Due to the endnode collector, there are | ||||
1699 | // SwFootnoteFrames, which are not in the layout. Therefore the | ||||
1700 | // bInfFootnote flags are not set correctly, and a cell of FindFootnoteFrame | ||||
1701 | // would return 0. Therefore we better call ImplFindFootnoteFrame(). | ||||
1702 | SwFootnoteFrame *pFootnote = pFrame->ImplFindFootnoteFrame(); | ||||
1703 | if ( pFootnote && pFootnote->GetRef() == pRef ) | ||||
1704 | { | ||||
1705 | // The following condition becomes true, if the whole | ||||
1706 | // footnotecontent is a section. While no frames exist, | ||||
1707 | // the HiddenFlag of the section is set, this causes | ||||
1708 | // the GoNextSection-function leaves the footnote. | ||||
1709 | if( pFootnote->GetAttr() != pAttr ) | ||||
1710 | return nullptr; | ||||
1711 | while ( pFootnote && pFootnote->GetMaster() ) | ||||
1712 | pFootnote = pFootnote->GetMaster(); | ||||
1713 | return pFootnote; | ||||
1714 | } | ||||
1715 | |||||
1716 | } while ( nullptr != (pFrame = aIter.Next()) ); | ||||
1717 | |||||
1718 | return nullptr; | ||||
1719 | } | ||||
1720 | |||||
1721 | bool SwFootnoteBossFrame::RemoveFootnote( | ||||
1722 | const SwContentFrame *const pRef, const SwTextFootnote *const pAttr, | ||||
1723 | bool bPrep ) | ||||
1724 | { | ||||
1725 | bool ret(false); | ||||
1726 | SwFootnoteFrame *pFootnote = FindFootnote( pRef, pAttr ); | ||||
1727 | if( pFootnote ) | ||||
1728 | { | ||||
1729 | ret = true; | ||||
1730 | do | ||||
1731 | { | ||||
1732 | SwFootnoteFrame *pFoll = pFootnote->GetFollow(); | ||||
1733 | pFootnote->Cut(); | ||||
1734 | SwFrame::DestroyFrame(pFootnote); | ||||
1735 | pFootnote = pFoll; | ||||
1736 | } while ( pFootnote ); | ||||
1737 | if( bPrep && pRef->IsFollow() ) | ||||
1738 | { | ||||
1739 | OSL_ENSURE( pRef->IsTextFrame(), "NoTextFrame has Footnote?" )do { if (true && (!(pRef->IsTextFrame()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "1739" ": "), "%s", "NoTextFrame has Footnote?"); } } while (false); | ||||
1740 | SwTextFrame* pMaster = pRef->FindMaster(); | ||||
1741 | if( !pMaster->IsLocked() ) | ||||
1742 | pMaster->Prepare( PrepareHint::FootnoteInvalidationGone ); | ||||
1743 | } | ||||
1744 | } | ||||
1745 | FindPageFrame()->UpdateFootnoteNum(); | ||||
1746 | return ret; | ||||
1747 | } | ||||
1748 | |||||
1749 | void SwFootnoteBossFrame::ChangeFootnoteRef( const SwContentFrame *pOld, const SwTextFootnote *pAttr, | ||||
1750 | SwContentFrame *pNew ) | ||||
1751 | { | ||||
1752 | SwFootnoteFrame *pFootnote = FindFootnote( pOld, pAttr ); | ||||
1753 | while ( pFootnote ) | ||||
1754 | { | ||||
1755 | pFootnote->SetRef( pNew ); | ||||
1756 | pFootnote = pFootnote->GetFollow(); | ||||
1757 | } | ||||
1758 | } | ||||
1759 | |||||
1760 | /// OD 03.04.2003 #108446# - add parameter <_bCollectOnlyPreviousFootnotes> in | ||||
1761 | /// order to control, if only footnotes, which are positioned before the | ||||
1762 | /// footnote boss frame <this> have to be collected. | ||||
1763 | void SwFootnoteBossFrame::CollectFootnotes( const SwContentFrame* _pRef, | ||||
1764 | SwFootnoteBossFrame* _pOld, | ||||
1765 | SwFootnoteFrames& _rFootnoteArr, | ||||
1766 | const bool _bCollectOnlyPreviousFootnotes ) | ||||
1767 | { | ||||
1768 | SwFootnoteFrame *pFootnote = _pOld->FindFirstFootnote(); | ||||
1769 | while( !pFootnote ) | ||||
1770 | { | ||||
1771 | if( _pOld->IsColumnFrame() ) | ||||
1772 | { | ||||
1773 | // visit columns | ||||
1774 | while ( !pFootnote && _pOld->GetPrev() ) | ||||
1775 | { | ||||
1776 | // Still no problem if no footnote was found yet. The loop is needed to pick up | ||||
1777 | // following rows in tables. In all other cases it might correct bad contexts. | ||||
1778 | _pOld = static_cast<SwFootnoteBossFrame*>(_pOld->GetPrev()); | ||||
1779 | pFootnote = _pOld->FindFirstFootnote(); | ||||
1780 | } | ||||
1781 | } | ||||
1782 | if( !pFootnote ) | ||||
1783 | { | ||||
1784 | // previous page | ||||
1785 | SwPageFrame* pPg; | ||||
1786 | for ( SwFrame* pTmp = _pOld; | ||||
1787 | nullptr != ( pPg = static_cast<SwPageFrame*>(pTmp->FindPageFrame()->GetPrev())) | ||||
1788 | && pPg->IsEmptyPage() ; | ||||
1789 | ) | ||||
1790 | { | ||||
1791 | pTmp = pPg; | ||||
1792 | } | ||||
1793 | if( !pPg ) | ||||
1794 | return; | ||||
1795 | |||||
1796 | SwLayoutFrame* pBody = pPg->FindBodyCont(); | ||||
1797 | if( pBody->Lower() && pBody->Lower()->IsColumnFrame() ) | ||||
1798 | { | ||||
1799 | // multiple columns on one page => search last column | ||||
1800 | _pOld = static_cast<SwFootnoteBossFrame*>(pBody->GetLastLower()); | ||||
1801 | } | ||||
1802 | else | ||||
1803 | _pOld = pPg; // single column page | ||||
1804 | pFootnote = _pOld->FindFirstFootnote(); | ||||
1805 | } | ||||
1806 | } | ||||
1807 | |||||
1808 | CollectFootnotes_(_pRef, pFootnote, _rFootnoteArr, _bCollectOnlyPreviousFootnotes ? this : nullptr); | ||||
1809 | } | ||||
1810 | |||||
1811 | static void FootnoteInArr( SwFootnoteFrames& rFootnoteArr, SwFootnoteFrame* pFootnote ) | ||||
1812 | { | ||||
1813 | if ( rFootnoteArr.end() == std::find( rFootnoteArr.begin(), rFootnoteArr.end(), pFootnote ) ) | ||||
1814 | rFootnoteArr.push_back( pFootnote ); | ||||
1815 | } | ||||
1816 | |||||
1817 | void SwFootnoteBossFrame::CollectFootnotes_( const SwContentFrame* _pRef, | ||||
1818 | SwFootnoteFrame* _pFootnote, | ||||
1819 | SwFootnoteFrames& _rFootnoteArr, | ||||
1820 | const SwFootnoteBossFrame* _pRefFootnoteBossFrame) | ||||
1821 | { | ||||
1822 | // Collect all footnotes referenced by pRef (attribute by attribute), combine them | ||||
1823 | // (the content might be divided over multiple pages) and cut them. | ||||
1824 | |||||
1825 | // For robustness, we do not log the corresponding footnotes here. If a footnote | ||||
1826 | // is touched twice, there might be a crash. This allows this function here to | ||||
1827 | // also handle corrupt layouts in some degrees (without loops or even crashes). | ||||
1828 | SwFootnoteFrames aNotFootnoteArr; | ||||
1829 | |||||
1830 | // here we have a footnote placed in front of the first one of the reference | ||||
1831 | OSL_ENSURE( !_pFootnote->GetMaster() || _pFootnote->GetRef() != _pRef, "move FollowFootnote?" )do { if (true && (!(!_pFootnote->GetMaster() || _pFootnote ->GetRef() != _pRef))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "1831" ": "), "%s", "move FollowFootnote?"); } } while ( false); | ||||
1832 | while ( _pFootnote->GetMaster() ) | ||||
1833 | _pFootnote = _pFootnote->GetMaster(); | ||||
1834 | |||||
1835 | bool bFound = false; | ||||
1836 | |||||
1837 | do | ||||
1838 | { | ||||
1839 | // Search for the next footnote in this column/page so that | ||||
1840 | // we do not start from zero again after cutting one footnote. | ||||
1841 | SwFootnoteFrame *pNxtFootnote = _pFootnote; | ||||
1842 | while ( pNxtFootnote->GetFollow() ) | ||||
1843 | pNxtFootnote = pNxtFootnote->GetFollow(); | ||||
1844 | pNxtFootnote = static_cast<SwFootnoteFrame*>(pNxtFootnote->GetNext()); | ||||
1845 | |||||
1846 | if ( !pNxtFootnote ) | ||||
1847 | { | ||||
1848 | SwFootnoteBossFrame* pBoss = _pFootnote->FindFootnoteBossFrame(); | ||||
1849 | SwPageFrame* pPage = pBoss->FindPageFrame(); | ||||
1850 | do | ||||
1851 | { | ||||
1852 | lcl_NextFootnoteBoss( pBoss, pPage, false ); | ||||
1853 | if( pBoss ) | ||||
1854 | { | ||||
1855 | SwLayoutFrame* pCont = pBoss->FindFootnoteCont(); | ||||
1856 | if( pCont ) | ||||
1857 | { | ||||
1858 | pNxtFootnote = static_cast<SwFootnoteFrame*>(pCont->Lower()); | ||||
1859 | if( pNxtFootnote ) | ||||
1860 | { | ||||
1861 | while( pNxtFootnote->GetMaster() ) | ||||
1862 | pNxtFootnote = pNxtFootnote->GetMaster(); | ||||
1863 | if( pNxtFootnote == _pFootnote ) | ||||
1864 | pNxtFootnote = nullptr; | ||||
1865 | } | ||||
1866 | } | ||||
1867 | } | ||||
1868 | } while( !pNxtFootnote && pBoss ); | ||||
1869 | } | ||||
1870 | else if( !pNxtFootnote->GetAttr()->GetFootnote().IsEndNote() ) | ||||
1871 | { | ||||
1872 | OSL_ENSURE( !pNxtFootnote->GetMaster(), "_CollectFootnote: Master expected" )do { if (true && (!(!pNxtFootnote->GetMaster()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "1872" ": "), "%s", "_CollectFootnote: Master expected") ; } } while (false); | ||||
1873 | while ( pNxtFootnote->GetMaster() ) | ||||
1874 | pNxtFootnote = pNxtFootnote->GetMaster(); | ||||
1875 | } | ||||
1876 | if ( pNxtFootnote == _pFootnote ) | ||||
1877 | { | ||||
1878 | OSL_FAIL( "_CollectFootnote: Vicious circle" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "1878" ": "), "%s", "_CollectFootnote: Vicious circle"); } } while (false); | ||||
1879 | pNxtFootnote = nullptr; | ||||
1880 | } | ||||
1881 | |||||
1882 | // OD 03.04.2003 #108446# - determine, if found footnote has to be collected. | ||||
1883 | bool bCollectFoundFootnote = false; | ||||
1884 | // Ignore endnotes which are on a separate endnote page. | ||||
1885 | bool bEndNote = _pFootnote->GetAttr()->GetFootnote().IsEndNote(); | ||||
1886 | const IDocumentSettingAccess& rSettings | ||||
1887 | = _pFootnote->GetAttrSet()->GetDoc()->getIDocumentSettingAccess(); | ||||
1888 | bool bContinuousEndnotes = rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES); | ||||
1889 | if (_pFootnote->GetRef() == _pRef && (!bEndNote || bContinuousEndnotes)) | ||||
1890 | { | ||||
1891 | if (_pRefFootnoteBossFrame) | ||||
1892 | { | ||||
1893 | SwFootnoteBossFrame* pBossOfFoundFootnote = _pFootnote->FindFootnoteBossFrame( true ); | ||||
1894 | OSL_ENSURE( pBossOfFoundFootnote,do { if (true && (!(pBossOfFoundFootnote))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "1895" ": "), "%s", "<SwFootnoteBossFrame::CollectFootnotes_(..)> - footnote boss frame of found footnote frame missing.\nWrong layout!" ); } } while (false) | ||||
1895 | "<SwFootnoteBossFrame::CollectFootnotes_(..)> - footnote boss frame of found footnote frame missing.\nWrong layout!" )do { if (true && (!(pBossOfFoundFootnote))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "1895" ": "), "%s", "<SwFootnoteBossFrame::CollectFootnotes_(..)> - footnote boss frame of found footnote frame missing.\nWrong layout!" ); } } while (false); | ||||
1896 | if ( !pBossOfFoundFootnote || // don't crash, if no footnote boss is found. | ||||
1897 | pBossOfFoundFootnote->IsBefore( _pRefFootnoteBossFrame ) | ||||
1898 | ) | ||||
1899 | { | ||||
1900 | bCollectFoundFootnote = true; | ||||
1901 | } | ||||
1902 | } | ||||
1903 | else | ||||
1904 | { | ||||
1905 | bCollectFoundFootnote = true; | ||||
1906 | } | ||||
1907 | } | ||||
1908 | |||||
1909 | if ( bCollectFoundFootnote ) | ||||
1910 | { | ||||
1911 | OSL_ENSURE( !_pFootnote->GetMaster(), "move FollowFootnote?" )do { if (true && (!(!_pFootnote->GetMaster()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "1911" ": "), "%s", "move FollowFootnote?"); } } while ( false); | ||||
1912 | SwFootnoteFrame *pNxt = _pFootnote->GetFollow(); | ||||
1913 | while ( pNxt ) | ||||
1914 | { | ||||
1915 | SwFrame *pCnt = pNxt->ContainsAny(); | ||||
1916 | if ( pCnt ) | ||||
1917 | { | ||||
1918 | // destroy the follow on the way as it is empty | ||||
1919 | do | ||||
1920 | { SwFrame *pNxtCnt = pCnt->GetNext(); | ||||
1921 | pCnt->Cut(); | ||||
1922 | pCnt->Paste( _pFootnote ); | ||||
1923 | pCnt = pNxtCnt; | ||||
1924 | } while ( pCnt ); | ||||
1925 | } | ||||
1926 | else | ||||
1927 | { | ||||
1928 | OSL_ENSURE( !pNxt, "footnote without content?" )do { if (true && (!(!pNxt))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "1928" ": "), "%s", "footnote without content?"); } } while (false); | ||||
1929 | pNxt->Cut(); | ||||
1930 | SwFrame::DestroyFrame(pNxt); | ||||
1931 | } | ||||
1932 | pNxt = _pFootnote->GetFollow(); | ||||
1933 | } | ||||
1934 | _pFootnote->Cut(); | ||||
1935 | FootnoteInArr( _rFootnoteArr, _pFootnote ); | ||||
1936 | bFound = true; | ||||
1937 | } | ||||
1938 | else | ||||
1939 | { | ||||
1940 | FootnoteInArr( aNotFootnoteArr, _pFootnote ); | ||||
1941 | if( bFound ) | ||||
1942 | break; | ||||
1943 | } | ||||
1944 | if ( pNxtFootnote && | ||||
1945 | _rFootnoteArr.end() == std::find( _rFootnoteArr.begin(), _rFootnoteArr.end(), pNxtFootnote ) && | ||||
1946 | aNotFootnoteArr.end() == std::find( aNotFootnoteArr.begin(), aNotFootnoteArr.end(), pNxtFootnote ) ) | ||||
1947 | _pFootnote = pNxtFootnote; | ||||
1948 | else | ||||
1949 | break; | ||||
1950 | } | ||||
1951 | while ( _pFootnote ); | ||||
1952 | } | ||||
1953 | |||||
1954 | void SwFootnoteBossFrame::MoveFootnotes_( SwFootnoteFrames &rFootnoteArr, bool bCalc ) | ||||
1955 | { | ||||
1956 | // All footnotes referenced by pRef need to be moved | ||||
1957 | // to a new position (based on the new column/page) | ||||
1958 | const sal_uInt16 nMyNum = FindPageFrame()->GetPhyPageNum(); | ||||
1959 | const sal_uInt16 nMyCol = lcl_ColumnNum( this ); | ||||
1960 | SwRectFnSet aRectFnSet(this); | ||||
1961 | |||||
1962 | // #i21478# - keep last inserted footnote in order to | ||||
1963 | // format the content of the following one. | ||||
1964 | SwFootnoteFrame* pLastInsertedFootnote = nullptr; | ||||
1965 | for (SwFootnoteFrame* pFootnote : rFootnoteArr) | ||||
1966 | { | ||||
1967 | SwFootnoteBossFrame* pRefBoss(pFootnote->GetRef()->FindFootnoteBossFrame( | ||||
1968 | !pFootnote->GetAttr()->GetFootnote().IsEndNote())); | ||||
1969 | if( pRefBoss != this ) | ||||
1970 | { | ||||
1971 | const sal_uInt16 nRefNum = pRefBoss->FindPageFrame()->GetPhyPageNum(); | ||||
1972 | const sal_uInt16 nRefCol = lcl_ColumnNum( this ); | ||||
1973 | if( nRefNum < nMyNum || ( nRefNum == nMyNum && nRefCol <= nMyCol ) ) | ||||
1974 | pRefBoss = this; | ||||
1975 | } | ||||
1976 | pRefBoss->InsertFootnote( pFootnote ); | ||||
1977 | |||||
1978 | if ( pFootnote->GetUpper() ) // robust, e.g. with duplicates | ||||
1979 | { | ||||
1980 | // First condense the content so that footnote frames that do not fit on the page | ||||
1981 | // do not do too much harm (Loop 66312). So, the footnote content first grows as | ||||
1982 | // soon as the content gets formatted and it is sure that it fits on the page. | ||||
1983 | SwFrame *pCnt = pFootnote->ContainsAny(); | ||||
1984 | while( pCnt ) | ||||
1985 | { | ||||
1986 | if( pCnt->IsLayoutFrame() ) | ||||
1987 | { | ||||
1988 | SwFrame* pTmp = static_cast<SwLayoutFrame*>(pCnt)->ContainsAny(); | ||||
1989 | while( pTmp && static_cast<SwLayoutFrame*>(pCnt)->IsAnLower( pTmp ) ) | ||||
1990 | { | ||||
1991 | pTmp->Prepare( PrepareHint::FootnoteMove ); | ||||
1992 | |||||
1993 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*pTmp); | ||||
1994 | aRectFnSet.SetHeight(aFrm, 0); | ||||
1995 | |||||
1996 | SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*pTmp); | ||||
1997 | aRectFnSet.SetHeight(aPrt, 0); | ||||
1998 | |||||
1999 | pTmp = pTmp->FindNext(); | ||||
2000 | } | ||||
2001 | } | ||||
2002 | else | ||||
2003 | { | ||||
2004 | pCnt->Prepare( PrepareHint::FootnoteMove ); | ||||
2005 | } | ||||
2006 | |||||
2007 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*pCnt); | ||||
2008 | aRectFnSet.SetHeight(aFrm, 0); | ||||
2009 | |||||
2010 | SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*pCnt); | ||||
2011 | aRectFnSet.SetHeight(aPrt, 0); | ||||
2012 | |||||
2013 | pCnt = pCnt->GetNext(); | ||||
2014 | } | ||||
2015 | |||||
2016 | { | ||||
2017 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*pFootnote); | ||||
2018 | aRectFnSet.SetHeight(aFrm, 0); | ||||
2019 | } | ||||
2020 | |||||
2021 | { | ||||
2022 | SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*pFootnote); | ||||
2023 | aRectFnSet.SetHeight(aPrt, 0); | ||||
2024 | } | ||||
2025 | |||||
2026 | pFootnote->Calc(getRootFrame()->GetCurrShell()->GetOut()); | ||||
2027 | pFootnote->GetUpper()->Calc(getRootFrame()->GetCurrShell()->GetOut()); | ||||
2028 | |||||
2029 | if( bCalc ) | ||||
2030 | { | ||||
2031 | SwTextFootnote *pAttr = pFootnote->GetAttr(); | ||||
2032 | pCnt = pFootnote->ContainsAny(); | ||||
2033 | bool bUnlock = !pFootnote->IsBackMoveLocked(); | ||||
2034 | pFootnote->LockBackMove(); | ||||
2035 | |||||
2036 | // #i49383# - disable unlock of position of | ||||
2037 | // lower objects during format of footnote content. | ||||
2038 | pFootnote->KeepLockPosOfLowerObjs(); | ||||
2039 | // #i57914# - adjust fix #i49383# | ||||
2040 | |||||
2041 | while ( pCnt && pCnt->FindFootnoteFrame()->GetAttr() == pAttr ) | ||||
2042 | { | ||||
2043 | pCnt->InvalidatePos_(); | ||||
2044 | pCnt->Calc(getRootFrame()->GetCurrShell()->GetOut()); | ||||
2045 | // #i49383# - format anchored objects | ||||
2046 | if ( pCnt->IsTextFrame() && pCnt->isFrameAreaDefinitionValid() ) | ||||
2047 | { | ||||
2048 | if ( !SwObjectFormatter::FormatObjsAtFrame( *pCnt, | ||||
2049 | *(pCnt->FindPageFrame()) ) ) | ||||
2050 | { | ||||
2051 | // restart format with first content | ||||
2052 | pCnt = pFootnote->ContainsAny(); | ||||
2053 | continue; | ||||
2054 | } | ||||
2055 | } | ||||
2056 | if( pCnt->IsSctFrame() ) | ||||
2057 | { | ||||
2058 | // If the area is not empty, iterate also over the content | ||||
2059 | SwFrame* pTmp = static_cast<SwSectionFrame*>(pCnt)->ContainsAny(); | ||||
2060 | if( pTmp ) | ||||
2061 | pCnt = pTmp; | ||||
2062 | else | ||||
2063 | pCnt = pCnt->FindNext(); | ||||
2064 | } | ||||
2065 | else | ||||
2066 | pCnt = pCnt->FindNext(); | ||||
2067 | } | ||||
2068 | if( bUnlock ) | ||||
2069 | { | ||||
2070 | pFootnote->UnlockBackMove(); | ||||
2071 | if( !pFootnote->ContainsAny() && !pFootnote->IsColLocked() ) | ||||
2072 | { | ||||
2073 | pFootnote->Cut(); | ||||
2074 | SwFrame::DestroyFrame(pFootnote); | ||||
2075 | // #i21478# | ||||
2076 | pFootnote = nullptr; | ||||
2077 | } | ||||
2078 | } | ||||
2079 | // #i49383# | ||||
2080 | if ( pFootnote ) | ||||
2081 | { | ||||
2082 | // #i57914# - adjust fix #i49383# | ||||
2083 | // enable lock of lower object position before format of footnote frame. | ||||
2084 | pFootnote->UnlockPosOfLowerObjs(); | ||||
2085 | pFootnote->Calc(getRootFrame()->GetCurrShell()->GetOut()); | ||||
2086 | } | ||||
2087 | } | ||||
2088 | } | ||||
2089 | else | ||||
2090 | { | ||||
2091 | OSL_ENSURE( !pFootnote->GetMaster() && !pFootnote->GetFollow(),do { if (true && (!(!pFootnote->GetMaster() && !pFootnote->GetFollow()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "2092" ": "), "%s", "DelFootnote and Master/Follow?"); } } while (false) | ||||
2092 | "DelFootnote and Master/Follow?" )do { if (true && (!(!pFootnote->GetMaster() && !pFootnote->GetFollow()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "2092" ": "), "%s", "DelFootnote and Master/Follow?"); } } while (false); | ||||
2093 | SwFrame::DestroyFrame(pFootnote); | ||||
2094 | // #i21478# | ||||
2095 | pFootnote = nullptr; | ||||
2096 | } | ||||
2097 | |||||
2098 | // #i21478# | ||||
2099 | if ( pFootnote ) | ||||
2100 | { | ||||
2101 | pLastInsertedFootnote = pFootnote; | ||||
2102 | } | ||||
2103 | } | ||||
2104 | |||||
2105 | // #i21478# - format content of footnote following | ||||
2106 | // the new inserted ones. | ||||
2107 | if ( !(bCalc && pLastInsertedFootnote) ) | ||||
2108 | return; | ||||
2109 | |||||
2110 | if ( !pLastInsertedFootnote->GetNext() ) | ||||
2111 | return; | ||||
2112 | |||||
2113 | SwFootnoteFrame* pNextFootnote = static_cast<SwFootnoteFrame*>(pLastInsertedFootnote->GetNext()); | ||||
2114 | SwTextFootnote* pAttr = pNextFootnote->GetAttr(); | ||||
2115 | SwFrame* pCnt = pNextFootnote->ContainsAny(); | ||||
2116 | |||||
2117 | bool bUnlock = !pNextFootnote->IsBackMoveLocked(); | ||||
2118 | pNextFootnote->LockBackMove(); | ||||
2119 | // #i49383# - disable unlock of position of | ||||
2120 | // lower objects during format of footnote content. | ||||
2121 | pNextFootnote->KeepLockPosOfLowerObjs(); | ||||
2122 | // #i57914# - adjust fix #i49383# | ||||
2123 | |||||
2124 | while ( pCnt && pCnt->FindFootnoteFrame()->GetAttr() == pAttr ) | ||||
2125 | { | ||||
2126 | pCnt->InvalidatePos_(); | ||||
2127 | pCnt->Calc(getRootFrame()->GetCurrShell()->GetOut()); | ||||
2128 | // #i49383# - format anchored objects | ||||
2129 | if ( pCnt->IsTextFrame() && pCnt->isFrameAreaDefinitionValid() ) | ||||
2130 | { | ||||
2131 | if ( !SwObjectFormatter::FormatObjsAtFrame( *pCnt, | ||||
2132 | *(pCnt->FindPageFrame()) ) ) | ||||
2133 | { | ||||
2134 | // restart format with first content | ||||
2135 | pCnt = pNextFootnote->ContainsAny(); | ||||
2136 | continue; | ||||
2137 | } | ||||
2138 | } | ||||
2139 | if( pCnt->IsSctFrame() ) | ||||
2140 | { | ||||
2141 | // If the area is not empty, iterate also over the content | ||||
2142 | SwFrame* pTmp = static_cast<SwSectionFrame*>(pCnt)->ContainsAny(); | ||||
2143 | if( pTmp ) | ||||
2144 | pCnt = pTmp; | ||||
2145 | else | ||||
2146 | pCnt = pCnt->FindNext(); | ||||
2147 | } | ||||
2148 | else | ||||
2149 | pCnt = pCnt->FindNext(); | ||||
2150 | } | ||||
2151 | if( bUnlock ) | ||||
2152 | { | ||||
2153 | pNextFootnote->UnlockBackMove(); | ||||
2154 | } | ||||
2155 | // #i49383# | ||||
2156 | // #i57914# - adjust fix #i49383# | ||||
2157 | // enable lock of lower object position before format of footnote frame. | ||||
2158 | pNextFootnote->UnlockPosOfLowerObjs(); | ||||
2159 | pNextFootnote->Calc(getRootFrame()->GetCurrShell()->GetOut()); | ||||
2160 | } | ||||
2161 | |||||
2162 | void SwFootnoteBossFrame::MoveFootnotes( const SwContentFrame *pSrc, SwContentFrame *pDest, | ||||
2163 | SwTextFootnote const *pAttr ) | ||||
2164 | { | ||||
2165 | if( ( GetFormat()->GetDoc()->GetFootnoteInfo().m_ePos == FTNPOS_CHAPTER && | ||||
2166 | (!GetUpper()->IsSctFrame() || !static_cast<SwSectionFrame*>(GetUpper())->IsFootnoteAtEnd())) | ||||
2167 | || pAttr->GetFootnote().IsEndNote() ) | ||||
2168 | return; | ||||
2169 | |||||
2170 | OSL_ENSURE( this == pSrc->FindFootnoteBossFrame( true ),do { if (true && (!(this == pSrc->FindFootnoteBossFrame ( true )))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "2171" ": "), "%s", "SwPageFrame::MoveFootnotes: source frame isn't on that FootnoteBoss" ); } } while (false) | ||||
2171 | "SwPageFrame::MoveFootnotes: source frame isn't on that FootnoteBoss" )do { if (true && (!(this == pSrc->FindFootnoteBossFrame ( true )))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "2171" ": "), "%s", "SwPageFrame::MoveFootnotes: source frame isn't on that FootnoteBoss" ); } } while (false); | ||||
2172 | |||||
2173 | SwFootnoteFrame *pFootnote = FindFirstFootnote(); | ||||
2174 | if( !pFootnote ) | ||||
2175 | return; | ||||
2176 | |||||
2177 | ChangeFootnoteRef( pSrc, pAttr, pDest ); | ||||
2178 | SwFootnoteBossFrame *pDestBoss = pDest->FindFootnoteBossFrame( true ); | ||||
2179 | OSL_ENSURE( pDestBoss, "+SwPageFrame::MoveFootnotes: no destination boss" )do { if (true && (!(pDestBoss))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "2179" ": "), "%s", "+SwPageFrame::MoveFootnotes: no destination boss" ); } } while (false); | ||||
2180 | if( !pDestBoss ) // robust | ||||
2181 | return; | ||||
2182 | |||||
2183 | SwFootnoteFrames aFootnoteArr; | ||||
2184 | SwFootnoteBossFrame::CollectFootnotes_(pDest, pFootnote, aFootnoteArr, nullptr); | ||||
2185 | if ( aFootnoteArr.empty() ) | ||||
2186 | return; | ||||
2187 | |||||
2188 | pDestBoss->MoveFootnotes_( aFootnoteArr, true ); | ||||
2189 | SwPageFrame* pSrcPage = FindPageFrame(); | ||||
2190 | SwPageFrame* pDestPage = pDestBoss->FindPageFrame(); | ||||
2191 | // update FootnoteNum only at page change | ||||
2192 | if( pSrcPage != pDestPage ) | ||||
2193 | { | ||||
2194 | if( pSrcPage->GetPhyPageNum() > pDestPage->GetPhyPageNum() ) | ||||
2195 | pSrcPage->UpdateFootnoteNum(); | ||||
2196 | pDestPage->UpdateFootnoteNum(); | ||||
2197 | } | ||||
2198 | } | ||||
2199 | |||||
2200 | void SwFootnoteBossFrame::RearrangeFootnotes( const SwTwips nDeadLine, const bool bLock, | ||||
2201 | const SwTextFootnote *pAttr ) | ||||
2202 | { | ||||
2203 | // Format all footnotes of a column/page so that they might change the column/page. | ||||
2204 | |||||
2205 | SwSaveFootnoteHeight aSave( this, nDeadLine ); | ||||
2206 | SwFootnoteFrame *pFootnote = FindFirstFootnote(); | ||||
2207 | if( pFootnote && pFootnote->GetPrev() && bLock ) | ||||
| |||||
2208 | { | ||||
2209 | SwFootnoteFrame* pFirst = static_cast<SwFootnoteFrame*>(pFootnote->GetUpper()->Lower()); | ||||
2210 | SwFrame* pContent = pFirst->ContainsAny(); | ||||
2211 | if( pContent ) | ||||
2212 | { | ||||
2213 | bool bUnlock = !pFirst->IsBackMoveLocked(); | ||||
2214 | pFirst->LockBackMove(); | ||||
2215 | pFirst->Calc(getRootFrame()->GetCurrShell()->GetOut()); | ||||
2216 | pContent->Calc(getRootFrame()->GetCurrShell()->GetOut()); | ||||
2217 | // #i49383# - format anchored objects | ||||
2218 | if ( pContent->IsTextFrame() && pContent->isFrameAreaDefinitionValid() ) | ||||
2219 | { | ||||
2220 | SwObjectFormatter::FormatObjsAtFrame( *pContent, | ||||
2221 | *(pContent->FindPageFrame()) ); | ||||
2222 | } | ||||
2223 | if( bUnlock ) | ||||
2224 | pFirst->UnlockBackMove(); | ||||
2225 | } | ||||
2226 | pFootnote = FindFirstFootnote(); | ||||
2227 | } | ||||
2228 | SwDoc *pDoc = GetFormat()->GetDoc(); | ||||
2229 | const sal_uLong nFootnotePos = pAttr ? ::lcl_FindFootnotePos( pDoc, pAttr ) : 0; | ||||
2230 | SwFrame *pCnt = pFootnote
| ||||
2231 | if ( !pCnt ) | ||||
2232 | return; | ||||
2233 | |||||
2234 | bool bMore = true; | ||||
2235 | bool bStart = pAttr == nullptr; // If no attribute is given, process all | ||||
2236 | // #i49383# - disable unlock of position of | ||||
2237 | // lower objects during format of footnote and footnote content. | ||||
2238 | SwFootnoteFrame* pLastFootnoteFrame( nullptr ); | ||||
2239 | // footnote frame needs to be locked, if <bLock> isn't set. | ||||
2240 | bool bUnlockLastFootnoteFrame( false ); | ||||
2241 | do | ||||
2242 | { | ||||
2243 | if( !bStart
| ||||
2244 | bStart = ::lcl_FindFootnotePos( pDoc, pCnt->FindFootnoteFrame()->GetAttr() ) | ||||
2245 | == nFootnotePos; | ||||
2246 | if( bStart
| ||||
2247 | { | ||||
2248 | pCnt->InvalidatePos_(); | ||||
2249 | pCnt->InvalidateSize_(); | ||||
2250 | pCnt->Prepare( PrepareHint::AdjustSizeWithoutFormatting ); | ||||
2251 | SwFootnoteFrame* pFootnoteFrame = pCnt->FindFootnoteFrame(); | ||||
2252 | // #i49383# | ||||
2253 | if ( pFootnoteFrame != pLastFootnoteFrame ) | ||||
2254 | { | ||||
2255 | if ( pLastFootnoteFrame ) | ||||
2256 | { | ||||
2257 | if ( !bLock && bUnlockLastFootnoteFrame ) | ||||
2258 | { | ||||
2259 | pLastFootnoteFrame->ColUnlock(); | ||||
2260 | } | ||||
2261 | // #i57914# - adjust fix #i49383# | ||||
2262 | // enable lock of lower object position before format of footnote frame. | ||||
2263 | pLastFootnoteFrame->UnlockPosOfLowerObjs(); | ||||
2264 | pLastFootnoteFrame->Calc(getRootFrame()->GetCurrShell()->GetOut()); | ||||
2265 | if ( !bLock && bUnlockLastFootnoteFrame && | ||||
2266 | !pLastFootnoteFrame->GetLower() && | ||||
2267 | !pLastFootnoteFrame->IsColLocked() && | ||||
2268 | !pLastFootnoteFrame->IsBackMoveLocked() && | ||||
2269 | !pLastFootnoteFrame->IsDeleteForbidden() ) | ||||
2270 | { | ||||
2271 | pLastFootnoteFrame->Cut(); | ||||
2272 | SwFrame::DestroyFrame(pLastFootnoteFrame); | ||||
2273 | pLastFootnoteFrame = nullptr; | ||||
2274 | } | ||||
2275 | } | ||||
2276 | if ( !bLock ) | ||||
2277 | { | ||||
2278 | bUnlockLastFootnoteFrame = !pFootnoteFrame->IsColLocked(); | ||||
2279 | pFootnoteFrame->ColLock(); | ||||
2280 | } | ||||
2281 | pFootnoteFrame->KeepLockPosOfLowerObjs(); | ||||
2282 | pLastFootnoteFrame = pFootnoteFrame; | ||||
2283 | } | ||||
2284 | // OD 30.10.2002 #97265# - invalidate position of footnote | ||||
2285 | // frame, if it's below its footnote container, in order to | ||||
2286 | // assure its correct position, probably calculating its previous | ||||
2287 | // footnote frames. | ||||
2288 | { | ||||
2289 | SwRectFnSet aRectFnSet(this); | ||||
2290 | SwFrame* pFootnoteContFrame = pFootnoteFrame->GetUpper(); | ||||
| |||||
2291 | if ( aRectFnSet.TopDist(pFootnoteFrame->getFrameArea(), aRectFnSet.GetPrtBottom(*pFootnoteContFrame)) > 0 ) | ||||
2292 | { | ||||
2293 | pFootnoteFrame->InvalidatePos_(); | ||||
2294 | } | ||||
2295 | } | ||||
2296 | if ( bLock ) | ||||
2297 | { | ||||
2298 | bool bUnlock = !pFootnoteFrame->IsBackMoveLocked(); | ||||
2299 | pFootnoteFrame->LockBackMove(); | ||||
2300 | pFootnoteFrame->Calc(getRootFrame()->GetCurrShell()->GetOut()); | ||||
2301 | pCnt->Calc(getRootFrame()->GetCurrShell()->GetOut()); | ||||
2302 | // #i49383# - format anchored objects | ||||
2303 | if ( pCnt->IsTextFrame() && pCnt->isFrameAreaDefinitionValid() ) | ||||
2304 | { | ||||
2305 | SwFrameDeleteGuard aDeleteGuard(pFootnote); | ||||
2306 | if ( !SwObjectFormatter::FormatObjsAtFrame( *pCnt, | ||||
2307 | *(pCnt->FindPageFrame()) ) ) | ||||
2308 | { | ||||
2309 | // restart format with first content | ||||
2310 | pCnt = pFootnote ? pFootnote->ContainsAny() : nullptr; | ||||
2311 | if (!pCnt) | ||||
2312 | bMore = false; | ||||
2313 | continue; | ||||
2314 | } | ||||
2315 | } | ||||
2316 | if( bUnlock ) | ||||
2317 | { | ||||
2318 | pFootnoteFrame->UnlockBackMove(); | ||||
2319 | if( !pFootnoteFrame->Lower() && | ||||
2320 | !pFootnoteFrame->IsColLocked() ) | ||||
2321 | { | ||||
2322 | // #i49383# | ||||
2323 | OSL_ENSURE( pLastFootnoteFrame == pFootnoteFrame,do { if (true && (!(pLastFootnoteFrame == pFootnoteFrame ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "2324" ": "), "%s", "<SwFootnoteBossFrame::RearrangeFootnotes(..)> - <pLastFootnoteFrame> != <pFootnoteFrame>" ); } } while (false) | ||||
2324 | "<SwFootnoteBossFrame::RearrangeFootnotes(..)> - <pLastFootnoteFrame> != <pFootnoteFrame>" )do { if (true && (!(pLastFootnoteFrame == pFootnoteFrame ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "2324" ": "), "%s", "<SwFootnoteBossFrame::RearrangeFootnotes(..)> - <pLastFootnoteFrame> != <pFootnoteFrame>" ); } } while (false); | ||||
2325 | pLastFootnoteFrame = nullptr; | ||||
2326 | pFootnoteFrame->Cut(); | ||||
2327 | SwFrame::DestroyFrame(pFootnoteFrame); | ||||
2328 | if (pFootnote == pFootnoteFrame) | ||||
2329 | pFootnote = nullptr; | ||||
2330 | } | ||||
2331 | } | ||||
2332 | } | ||||
2333 | else | ||||
2334 | { | ||||
2335 | pFootnoteFrame->Calc(getRootFrame()->GetCurrShell()->GetOut()); | ||||
2336 | pCnt->Calc(getRootFrame()->GetCurrShell()->GetOut()); | ||||
2337 | // #i49383# - format anchored objects | ||||
2338 | if ( pCnt->IsTextFrame() && pCnt->isFrameAreaDefinitionValid() ) | ||||
2339 | { | ||||
2340 | if ( !SwObjectFormatter::FormatObjsAtFrame( *pCnt, | ||||
2341 | *(pCnt->FindPageFrame()) ) ) | ||||
2342 | { | ||||
2343 | // restart format with first content | ||||
2344 | pCnt = pFootnote->ContainsAny(); | ||||
2345 | continue; | ||||
2346 | } | ||||
2347 | } | ||||
2348 | } | ||||
2349 | } | ||||
2350 | SwSectionFrame *pDel = nullptr; | ||||
2351 | if( pCnt->IsSctFrame() ) | ||||
2352 | { | ||||
2353 | SwFrame* pTmp = static_cast<SwSectionFrame*>(pCnt)->ContainsAny(); | ||||
2354 | if( pTmp ) | ||||
2355 | { | ||||
2356 | pCnt = pTmp; | ||||
2357 | continue; | ||||
2358 | } | ||||
2359 | pDel = static_cast<SwSectionFrame*>(pCnt); | ||||
2360 | } | ||||
2361 | if ( pCnt->GetNext() ) | ||||
2362 | pCnt = pCnt->GetNext(); | ||||
2363 | else | ||||
2364 | { | ||||
2365 | pCnt = pCnt->FindNext(); | ||||
2366 | if ( pCnt ) | ||||
2367 | { | ||||
2368 | SwFootnoteFrame* pFootnoteFrame = pCnt->FindFootnoteFrame(); | ||||
2369 | if( pFootnoteFrame->GetRef()->FindFootnoteBossFrame( | ||||
2370 | pFootnoteFrame->GetAttr()->GetFootnote().IsEndNote() ) != this ) | ||||
2371 | bMore = false; | ||||
2372 | } | ||||
2373 | else | ||||
2374 | bMore = false; | ||||
2375 | } | ||||
2376 | if( pDel ) | ||||
2377 | { | ||||
2378 | bool bUnlockLastFootnoteFrameGuard = pLastFootnoteFrame && !pLastFootnoteFrame->IsColLocked(); | ||||
2379 | if (bUnlockLastFootnoteFrameGuard) | ||||
2380 | pLastFootnoteFrame->ColLock(); | ||||
2381 | pDel->Cut(); | ||||
2382 | if (bUnlockLastFootnoteFrameGuard) | ||||
2383 | pLastFootnoteFrame->ColUnlock(); | ||||
2384 | SwFrame::DestroyFrame(pDel); | ||||
2385 | } | ||||
2386 | if ( bMore ) | ||||
2387 | { | ||||
2388 | // Go not further than to the provided footnote (if given) | ||||
2389 | if ( pAttr && | ||||
2390 | (::lcl_FindFootnotePos( pDoc, | ||||
2391 | pCnt->FindFootnoteFrame()->GetAttr()) > nFootnotePos ) ) | ||||
2392 | bMore = false; | ||||
2393 | } | ||||
2394 | } while ( bMore ); | ||||
2395 | // #i49383# | ||||
2396 | if ( !pLastFootnoteFrame ) | ||||
2397 | return; | ||||
2398 | |||||
2399 | if ( !bLock && bUnlockLastFootnoteFrame ) | ||||
2400 | { | ||||
2401 | pLastFootnoteFrame->ColUnlock(); | ||||
2402 | } | ||||
2403 | // #i57914# - adjust fix #i49383# | ||||
2404 | // enable lock of lower object position before format of footnote frame. | ||||
2405 | pLastFootnoteFrame->UnlockPosOfLowerObjs(); | ||||
2406 | pLastFootnoteFrame->Calc(getRootFrame()->GetCurrShell()->GetOut()); | ||||
2407 | if ( !bLock && bUnlockLastFootnoteFrame && | ||||
2408 | !pLastFootnoteFrame->GetLower() && | ||||
2409 | !pLastFootnoteFrame->IsColLocked() && | ||||
2410 | !pLastFootnoteFrame->IsBackMoveLocked() ) | ||||
2411 | { | ||||
2412 | pLastFootnoteFrame->Cut(); | ||||
2413 | SwFrame::DestroyFrame(pLastFootnoteFrame); | ||||
2414 | } | ||||
2415 | } | ||||
2416 | |||||
2417 | void SwPageFrame::UpdateFootnoteNum() | ||||
2418 | { | ||||
2419 | // page numbering only if set at the document | ||||
2420 | if ( GetFormat()->GetDoc()->GetFootnoteInfo().m_eNum != FTNNUM_PAGE ) | ||||
2421 | return; | ||||
2422 | |||||
2423 | SwLayoutFrame* pBody = FindBodyCont(); | ||||
2424 | if( !pBody || !pBody->Lower() ) | ||||
2425 | return; | ||||
2426 | |||||
2427 | SwContentFrame* pContent = pBody->ContainsContent(); | ||||
2428 | sal_uInt16 nNum = 0; | ||||
2429 | |||||
2430 | while( pContent && pContent->FindPageFrame() == this ) | ||||
2431 | { | ||||
2432 | if( static_cast<SwTextFrame*>(pContent)->HasFootnote() ) | ||||
2433 | { | ||||
2434 | SwFootnoteBossFrame* pBoss = pContent->FindFootnoteBossFrame( true ); | ||||
2435 | if( pBoss->GetUpper()->IsSctFrame() && | ||||
2436 | static_cast<SwSectionFrame*>(pBoss->GetUpper())->IsOwnFootnoteNum() ) | ||||
2437 | pContent = static_cast<SwSectionFrame*>(pBoss->GetUpper())->FindLastContent(); | ||||
2438 | else | ||||
2439 | { | ||||
2440 | SwFootnoteFrame* pFootnote = const_cast<SwFootnoteFrame*>(pBoss->FindFirstFootnote( pContent )); | ||||
2441 | while( pFootnote ) | ||||
2442 | { | ||||
2443 | SwTextFootnote* pTextFootnote = pFootnote->GetAttr(); | ||||
2444 | if( !pTextFootnote->GetFootnote().IsEndNote() && | ||||
2445 | pTextFootnote->GetFootnote().GetNumStr().isEmpty() && | ||||
2446 | !pFootnote->GetMaster()) | ||||
2447 | { | ||||
2448 | // sw_redlinehide: the layout can only keep one number | ||||
2449 | // up to date; depending on its setting, this is either | ||||
2450 | // the non-hidden or the hidden number; the other | ||||
2451 | // number will simply be preserved as-is (so in case | ||||
2452 | // there are 2 layouts, maybe both can be updated...) | ||||
2453 | ++nNum; | ||||
2454 | sal_uInt16 const nOldNum(pTextFootnote->GetFootnote().GetNumber()); | ||||
2455 | sal_uInt16 const nOldNumRLHidden(pTextFootnote->GetFootnote().GetNumberRLHidden()); | ||||
2456 | if (getRootFrame()->IsHideRedlines()) | ||||
2457 | { | ||||
2458 | if (nNum != nOldNumRLHidden) | ||||
2459 | { | ||||
2460 | pTextFootnote->SetNumber(nOldNum, nNum, OUString()); | ||||
2461 | } | ||||
2462 | } | ||||
2463 | else | ||||
2464 | { | ||||
2465 | if (nNum != nOldNum) | ||||
2466 | { | ||||
2467 | pTextFootnote->SetNumber(nNum, nOldNumRLHidden, OUString()); | ||||
2468 | } | ||||
2469 | } | ||||
2470 | } | ||||
2471 | if ( pFootnote->GetNext() ) | ||||
2472 | pFootnote = static_cast<SwFootnoteFrame*>(pFootnote->GetNext()); | ||||
2473 | else | ||||
2474 | { | ||||
2475 | SwFootnoteBossFrame* pTmpBoss = pFootnote->FindFootnoteBossFrame( true ); | ||||
2476 | if( pTmpBoss ) | ||||
2477 | { | ||||
2478 | SwPageFrame* pPage = pTmpBoss->FindPageFrame(); | ||||
2479 | pFootnote = nullptr; | ||||
2480 | lcl_NextFootnoteBoss( pTmpBoss, pPage, false ); | ||||
2481 | SwFootnoteContFrame *pCont = pTmpBoss ? pTmpBoss->FindNearestFootnoteCont() : nullptr; | ||||
2482 | if ( pCont ) | ||||
2483 | pFootnote = static_cast<SwFootnoteFrame*>(pCont->Lower()); | ||||
2484 | } | ||||
2485 | } | ||||
2486 | if( pFootnote && pFootnote->GetRef() != pContent ) | ||||
2487 | pFootnote = nullptr; | ||||
2488 | } | ||||
2489 | } | ||||
2490 | } | ||||
2491 | pContent = pContent->FindNextCnt(); | ||||
2492 | } | ||||
2493 | } | ||||
2494 | |||||
2495 | void SwFootnoteBossFrame::SetFootnoteDeadLine( const SwTwips nDeadLine ) | ||||
2496 | { | ||||
2497 | SwFrame *pBody = FindBodyCont(); | ||||
2498 | pBody->Calc(getRootFrame()->GetCurrShell()->GetOut()); | ||||
2499 | |||||
2500 | SwFrame *pCont = FindFootnoteCont(); | ||||
2501 | const SwTwips nMax = m_nMaxFootnoteHeight;// current should exceed MaxHeight | ||||
2502 | SwRectFnSet aRectFnSet(this); | ||||
2503 | if ( pCont ) | ||||
2504 | { | ||||
2505 | pCont->Calc(getRootFrame()->GetCurrShell()->GetOut()); | ||||
2506 | m_nMaxFootnoteHeight = -aRectFnSet.BottomDist( pCont->getFrameArea(), nDeadLine ); | ||||
2507 | } | ||||
2508 | else | ||||
2509 | m_nMaxFootnoteHeight = -aRectFnSet.BottomDist( pBody->getFrameArea(), nDeadLine ); | ||||
2510 | |||||
2511 | const SwViewShell *pSh = getRootFrame() ? getRootFrame()->GetCurrShell() : nullptr; | ||||
2512 | if( pSh && pSh->GetViewOptions()->getBrowseMode() ) | ||||
2513 | m_nMaxFootnoteHeight += pBody->Grow( LONG_MAX9223372036854775807L, true ); | ||||
2514 | if ( IsInSct() ) | ||||
2515 | m_nMaxFootnoteHeight += FindSctFrame()->Grow( LONG_MAX9223372036854775807L, true ); | ||||
2516 | |||||
2517 | if ( m_nMaxFootnoteHeight < 0 ) | ||||
2518 | m_nMaxFootnoteHeight = 0; | ||||
2519 | if ( nMax != LONG_MAX9223372036854775807L && m_nMaxFootnoteHeight > nMax ) | ||||
2520 | m_nMaxFootnoteHeight = nMax; | ||||
2521 | } | ||||
2522 | |||||
2523 | SwTwips SwFootnoteBossFrame::GetVarSpace() const | ||||
2524 | { | ||||
2525 | // To not fall below 20% of the page height | ||||
2526 | // (in contrast to MSOffice where footnotes can fill a whole column/page) | ||||
2527 | |||||
2528 | const SwPageFrame* pPg = FindPageFrame(); | ||||
2529 | OSL_ENSURE( pPg || IsInSct(), "Footnote lost page" )do { if (true && (!(pPg || IsInSct()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "2529" ": "), "%s", "Footnote lost page"); } } while (false ); | ||||
2530 | |||||
2531 | const SwFrame *pBody = FindBodyCont(); | ||||
2532 | SwTwips nRet; | ||||
2533 | if( pBody ) | ||||
2534 | { | ||||
2535 | SwRectFnSet aRectFnSet(this); | ||||
2536 | if( IsInSct() ) | ||||
2537 | { | ||||
2538 | nRet = 0; | ||||
2539 | SwTwips nTmp = aRectFnSet.YDiff( aRectFnSet.GetPrtTop(*pBody), | ||||
2540 | aRectFnSet.GetTop(getFrameArea()) ); | ||||
2541 | const SwSectionFrame* pSect = FindSctFrame(); | ||||
2542 | // Endnotes in a ftncontainer causes a deadline: | ||||
2543 | // the bottom of the last contentfrm | ||||
2544 | if( pSect->IsEndnAtEnd() ) // endnotes allowed? | ||||
2545 | { | ||||
2546 | OSL_ENSURE( !Lower() || !Lower()->GetNext() || Lower()->GetNext()->do { if (true && (!(!Lower() || !Lower()->GetNext( ) || Lower()->GetNext()-> IsFootnoteContFrame()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "2547" ": "), "%s", "FootnoteContainer expected"); } } while (false) | ||||
2547 | IsFootnoteContFrame(), "FootnoteContainer expected" )do { if (true && (!(!Lower() || !Lower()->GetNext( ) || Lower()->GetNext()-> IsFootnoteContFrame()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "2547" ": "), "%s", "FootnoteContainer expected"); } } while (false); | ||||
2548 | const SwFootnoteContFrame* pCont = Lower() ? | ||||
2549 | static_cast<const SwFootnoteContFrame*>(Lower()->GetNext()) : nullptr; | ||||
2550 | if( pCont ) | ||||
2551 | { | ||||
2552 | const SwFootnoteFrame* pFootnote = static_cast<const SwFootnoteFrame*>(pCont->Lower()); | ||||
2553 | while( pFootnote) | ||||
2554 | { | ||||
2555 | if( pFootnote->GetAttr()->GetFootnote().IsEndNote() ) | ||||
2556 | { // endnote found | ||||
2557 | const SwFrame* pFrame = static_cast<const SwLayoutFrame*>(Lower())->Lower(); | ||||
2558 | if( pFrame ) | ||||
2559 | { | ||||
2560 | while( pFrame->GetNext() ) | ||||
2561 | pFrame = pFrame->GetNext(); // last cntntfrm | ||||
2562 | nTmp += aRectFnSet.YDiff( | ||||
2563 | aRectFnSet.GetTop(getFrameArea()), | ||||
2564 | aRectFnSet.GetBottom(pFrame->getFrameArea()) ); | ||||
2565 | } | ||||
2566 | break; | ||||
2567 | } | ||||
2568 | pFootnote = static_cast<const SwFootnoteFrame*>(pFootnote->GetNext()); | ||||
2569 | } | ||||
2570 | } | ||||
2571 | } | ||||
2572 | if( nTmp < nRet ) | ||||
2573 | nRet = nTmp; | ||||
2574 | } | ||||
2575 | else | ||||
2576 | nRet = - aRectFnSet.GetHeight(pPg->getFramePrintArea())/5; | ||||
2577 | nRet += aRectFnSet.GetHeight(pBody->getFrameArea()); | ||||
2578 | if( nRet < 0 ) | ||||
2579 | nRet = 0; | ||||
2580 | } | ||||
2581 | else | ||||
2582 | nRet = 0; | ||||
2583 | if ( IsPageFrame() ) | ||||
2584 | { | ||||
2585 | const SwViewShell *pSh = getRootFrame() ? getRootFrame()->GetCurrShell() : nullptr; | ||||
2586 | if( pSh && pSh->GetViewOptions()->getBrowseMode() ) | ||||
2587 | nRet += BROWSE_HEIGHT(56700L * 10L) - getFrameArea().Height(); | ||||
2588 | } | ||||
2589 | return nRet; | ||||
2590 | } | ||||
2591 | |||||
2592 | /** Obtain if pFrame's size adjustment should be processed | ||||
2593 | * | ||||
2594 | * For a page frame of columns directly below the page AdjustNeighbourhood() needs | ||||
2595 | * to be called, or Grow()/ Shrink() for frame columns respectively. | ||||
2596 | * | ||||
2597 | * A column section is special, since if there is a footnote container in a column | ||||
2598 | * and those footnotes are not collected, it is handled like a page frame. | ||||
2599 | * | ||||
2600 | * @see AdjustNeighbourhood() | ||||
2601 | * @see Grow() | ||||
2602 | * @see Shrink() | ||||
2603 | */ | ||||
2604 | SwNeighbourAdjust SwFootnoteBossFrame::NeighbourhoodAdjustment_() const | ||||
2605 | { | ||||
2606 | SwNeighbourAdjust nRet = SwNeighbourAdjust::OnlyAdjust; | ||||
2607 | if( GetUpper() && !GetUpper()->IsPageBodyFrame() ) | ||||
2608 | { | ||||
2609 | // column sections need grow/shrink | ||||
2610 | if( GetUpper()->IsFlyFrame() ) | ||||
2611 | nRet = SwNeighbourAdjust::GrowShrink; | ||||
2612 | else | ||||
2613 | { | ||||
2614 | OSL_ENSURE( GetUpper()->IsSctFrame(), "NeighbourhoodAdjustment: Unexpected Upper" )do { if (true && (!(GetUpper()->IsSctFrame()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "2614" ": "), "%s", "NeighbourhoodAdjustment: Unexpected Upper" ); } } while (false); | ||||
2615 | if( !GetNext() && !GetPrev() ) | ||||
2616 | nRet = SwNeighbourAdjust::GrowAdjust; // section with a single column (FootnoteAtEnd) | ||||
2617 | else | ||||
2618 | { | ||||
2619 | const SwFrame* pTmp = Lower(); | ||||
2620 | OSL_ENSURE( pTmp, "NeighbourhoodAdjustment: Missing Lower()" )do { if (true && (!(pTmp))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "2620" ": "), "%s", "NeighbourhoodAdjustment: Missing Lower()" ); } } while (false); | ||||
2621 | if( !pTmp->GetNext() ) | ||||
2622 | nRet = SwNeighbourAdjust::GrowShrink; | ||||
2623 | else if( !GetUpper()->IsColLocked() ) | ||||
2624 | nRet = SwNeighbourAdjust::AdjustGrow; | ||||
2625 | OSL_ENSURE( !pTmp->GetNext() || pTmp->GetNext()->IsFootnoteContFrame(),do { if (true && (!(!pTmp->GetNext() || pTmp->GetNext ()->IsFootnoteContFrame()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "2626" ": "), "%s", "NeighbourhoodAdjustment: Who's that guy?" ); } } while (false) | ||||
2626 | "NeighbourhoodAdjustment: Who's that guy?" )do { if (true && (!(!pTmp->GetNext() || pTmp->GetNext ()->IsFootnoteContFrame()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "2626" ": "), "%s", "NeighbourhoodAdjustment: Who's that guy?" ); } } while (false); | ||||
2627 | } | ||||
2628 | } | ||||
2629 | } | ||||
2630 | return nRet; | ||||
2631 | } | ||||
2632 | |||||
2633 | void SwPageFrame::SetColMaxFootnoteHeight() | ||||
2634 | { | ||||
2635 | SwLayoutFrame *pBody = FindBodyCont(); | ||||
2636 | if( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrame() ) | ||||
2637 | { | ||||
2638 | SwColumnFrame* pCol = static_cast<SwColumnFrame*>(pBody->Lower()); | ||||
2639 | do | ||||
2640 | { | ||||
2641 | pCol->SetMaxFootnoteHeight( GetMaxFootnoteHeight() ); | ||||
2642 | pCol = static_cast<SwColumnFrame*>(pCol->GetNext()); | ||||
2643 | } while ( pCol ); | ||||
2644 | } | ||||
2645 | } | ||||
2646 | |||||
2647 | bool SwLayoutFrame::MoveLowerFootnotes( SwContentFrame *pStart, SwFootnoteBossFrame *pOldBoss, | ||||
2648 | SwFootnoteBossFrame *pNewBoss, const bool bFootnoteNums ) | ||||
2649 | { | ||||
2650 | SwDoc *pDoc = GetFormat()->GetDoc(); | ||||
2651 | if ( pDoc->GetFootnoteIdxs().empty() ) | ||||
2652 | return false; | ||||
2653 | if( pDoc->GetFootnoteInfo().m_ePos == FTNPOS_CHAPTER && | ||||
2654 | ( !IsInSct() || !FindSctFrame()->IsFootnoteAtEnd() ) ) | ||||
2655 | return true; | ||||
2656 | |||||
2657 | if ( !pNewBoss ) | ||||
2658 | pNewBoss = FindFootnoteBossFrame( true ); | ||||
2659 | if ( pNewBoss == pOldBoss ) | ||||
2660 | return false; | ||||
2661 | |||||
2662 | bool bMoved = false; | ||||
2663 | if( !pStart ) | ||||
2664 | pStart = ContainsContent(); | ||||
2665 | |||||
2666 | SwFootnoteFrames aFootnoteArr; | ||||
2667 | |||||
2668 | while ( IsAnLower( pStart ) ) | ||||
2669 | { | ||||
2670 | if ( static_cast<SwTextFrame*>(pStart)->HasFootnote() ) | ||||
2671 | { | ||||
2672 | // OD 03.04.2003 #108446# - To avoid unnecessary moves of footnotes | ||||
2673 | // use new parameter <_bCollectOnlyPreviousFootnote> (4th parameter of | ||||
2674 | // method <SwFootnoteBossFrame::CollectFootnote(..)>) to control, that only | ||||
2675 | // footnotes have to be collected, that are positioned before the | ||||
2676 | // new dedicated footnote boss frame. | ||||
2677 | pNewBoss->CollectFootnotes( pStart, pOldBoss, aFootnoteArr, true ); | ||||
2678 | } | ||||
2679 | pStart = pStart->GetNextContentFrame(); | ||||
2680 | } | ||||
2681 | |||||
2682 | OSL_ENSURE( pOldBoss->IsInSct() == pNewBoss->IsInSct(),do { if (true && (!(pOldBoss->IsInSct() == pNewBoss ->IsInSct()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "2683" ": "), "%s", "MoveLowerFootnotes: Section confusion" ); } } while (false) | ||||
2683 | "MoveLowerFootnotes: Section confusion" )do { if (true && (!(pOldBoss->IsInSct() == pNewBoss ->IsInSct()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "2683" ": "), "%s", "MoveLowerFootnotes: Section confusion" ); } } while (false); | ||||
2684 | std::unique_ptr<SwFootnoteFrames> pFootnoteArr; | ||||
2685 | SwLayoutFrame* pNewChief = nullptr; | ||||
2686 | SwLayoutFrame* pOldChief = nullptr; | ||||
2687 | |||||
2688 | bool bFoundCandidate = false; | ||||
2689 | if (pStart && pOldBoss->IsInSct()) | ||||
2690 | { | ||||
2691 | pOldChief = pOldBoss->FindSctFrame(); | ||||
2692 | pNewChief = pNewBoss->FindSctFrame(); | ||||
2693 | bFoundCandidate = pOldChief != pNewChief; | ||||
2694 | } | ||||
2695 | |||||
2696 | if (bFoundCandidate) | ||||
2697 | { | ||||
2698 | pFootnoteArr.reset(new SwFootnoteFrames); | ||||
2699 | pOldChief = pOldBoss->FindFootnoteBossFrame( true ); | ||||
2700 | pNewChief = pNewBoss->FindFootnoteBossFrame( true ); | ||||
2701 | while( pOldChief->IsAnLower( pStart ) ) | ||||
2702 | { | ||||
2703 | if ( static_cast<SwTextFrame*>(pStart)->HasFootnote() ) | ||||
2704 | static_cast<SwFootnoteBossFrame*>(pNewChief)->CollectFootnotes( pStart, | ||||
2705 | pOldBoss, *pFootnoteArr ); | ||||
2706 | pStart = pStart->GetNextContentFrame(); | ||||
2707 | } | ||||
2708 | if( pFootnoteArr->empty() ) | ||||
2709 | { | ||||
2710 | pFootnoteArr.reset(); | ||||
2711 | } | ||||
2712 | } | ||||
2713 | else | ||||
2714 | pFootnoteArr = nullptr; | ||||
2715 | |||||
2716 | if ( !aFootnoteArr.empty() || pFootnoteArr ) | ||||
2717 | { | ||||
2718 | if( !aFootnoteArr.empty() ) | ||||
2719 | pNewBoss->MoveFootnotes_( aFootnoteArr, true ); | ||||
2720 | if( pFootnoteArr ) | ||||
2721 | { | ||||
2722 | assert(pNewChief)(static_cast <bool> (pNewChief) ? void (0) : __assert_fail ("pNewChief", "/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" , 2722, __extension__ __PRETTY_FUNCTION__)); | ||||
2723 | static_cast<SwFootnoteBossFrame*>(pNewChief)->MoveFootnotes_( *pFootnoteArr, true ); | ||||
2724 | pFootnoteArr.reset(); | ||||
2725 | } | ||||
2726 | bMoved = true; | ||||
2727 | |||||
2728 | // update FootnoteNum only at page change | ||||
2729 | if ( bFootnoteNums ) | ||||
2730 | { | ||||
2731 | SwPageFrame* pOldPage = pOldBoss->FindPageFrame(); | ||||
2732 | SwPageFrame* pNewPage =pNewBoss->FindPageFrame(); | ||||
2733 | if( pOldPage != pNewPage ) | ||||
2734 | { | ||||
2735 | pOldPage->UpdateFootnoteNum(); | ||||
2736 | pNewPage->UpdateFootnoteNum(); | ||||
2737 | } | ||||
2738 | } | ||||
2739 | } | ||||
2740 | return bMoved; | ||||
2741 | } | ||||
2742 | |||||
2743 | /// Return value guarantees that a new page was not created. See SwFlowFrame::MoveFwd. | ||||
2744 | bool SwContentFrame::MoveFootnoteCntFwd( bool bMakePage, SwFootnoteBossFrame *pOldBoss ) | ||||
2745 | { | ||||
2746 | OSL_ENSURE( IsInFootnote(), "no footnote." )do { if (true && (!(IsInFootnote()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "2746" ": "), "%s", "no footnote."); } } while (false); | ||||
2747 | SwLayoutFrame *pFootnote = FindFootnoteFrame(); | ||||
2748 | |||||
2749 | // The first paragraph in the first footnote in the first column in the | ||||
2750 | // sectionfrm at the top of the page has not to move forward, if the | ||||
2751 | // columnbody is empty. | ||||
2752 | if( pOldBoss->IsInSct() && !pOldBoss->GetIndPrev() && !GetIndPrev() && | ||||
2753 | !pFootnote->GetPrev() ) | ||||
2754 | { | ||||
2755 | SwLayoutFrame* pBody = pOldBoss->FindBodyCont(); | ||||
2756 | if( !pBody || !pBody->Lower() ) | ||||
2757 | return true; | ||||
2758 | } | ||||
2759 | |||||
2760 | //fix(9538): if the footnote has neighbors behind itself, remove them temporarily | ||||
2761 | SwLayoutFrame *pNxt = static_cast<SwLayoutFrame*>(pFootnote->GetNext()); | ||||
2762 | SwLayoutFrame *pLst = nullptr; | ||||
2763 | while ( pNxt ) | ||||
2764 | { | ||||
2765 | while ( pNxt->GetNext() ) | ||||
2766 | pNxt = static_cast<SwLayoutFrame*>(pNxt->GetNext()); | ||||
2767 | if ( pNxt == pLst ) | ||||
2768 | pNxt = nullptr; | ||||
2769 | else | ||||
2770 | { pLst = pNxt; | ||||
2771 | SwContentFrame *pCnt = pNxt->ContainsContent(); | ||||
2772 | if( pCnt ) | ||||
2773 | pCnt->MoveFootnoteCntFwd( true, pOldBoss ); | ||||
2774 | pNxt = static_cast<SwLayoutFrame*>(pFootnote->GetNext()); | ||||
2775 | } | ||||
2776 | } | ||||
2777 | |||||
2778 | bool bSamePage = true; | ||||
2779 | SwLayoutFrame *pNewUpper = | ||||
2780 | GetLeaf( bMakePage ? MAKEPAGE_INSERT : MAKEPAGE_NONE, true ); | ||||
2781 | |||||
2782 | if ( pNewUpper ) | ||||
2783 | { | ||||
2784 | SwFootnoteBossFrame * const pNewBoss = pNewUpper->FindFootnoteBossFrame(); | ||||
2785 | // Are we changing the column/page? | ||||
2786 | bool bSameBoss = pNewBoss == pOldBoss; | ||||
2787 | if ( !bSameBoss ) | ||||
2788 | { | ||||
2789 | bSamePage = pOldBoss->FindPageFrame() == pNewBoss->FindPageFrame(); // page change? | ||||
2790 | pNewUpper->Calc(getRootFrame()->GetCurrShell()->GetOut()); | ||||
2791 | } | ||||
2792 | |||||
2793 | // The layout leaf of the footnote is either a footnote container or a footnote. | ||||
2794 | // If it is a footnote and it has the same footnote reference like the old Upper, | ||||
2795 | // then move the content inside of it. | ||||
2796 | // If it is a container or the reference differs, create a new footnote and add | ||||
2797 | // it into the container. | ||||
2798 | // Create also a SectionFrame if currently in an area inside a footnote. | ||||
2799 | SwFootnoteFrame* pTmpFootnote = pNewUpper->IsFootnoteFrame() ? static_cast<SwFootnoteFrame*>(pNewUpper) : nullptr; | ||||
2800 | if (!pTmpFootnote && pNewUpper->IsFootnoteContFrame()) | ||||
2801 | { | ||||
2802 | SwFootnoteContFrame *pCont = static_cast<SwFootnoteContFrame*>(pNewUpper); | ||||
2803 | pTmpFootnote = SwFootnoteContFrame::AppendChained(this, true); | ||||
2804 | SwFrame* pNx = pCont->Lower(); | ||||
2805 | if( pNx && pTmpFootnote->GetAttr()->GetFootnote().IsEndNote() ) | ||||
2806 | while(pNx && !static_cast<SwFootnoteFrame*>(pNx)->GetAttr()->GetFootnote().IsEndNote()) | ||||
2807 | pNx = pNx->GetNext(); | ||||
2808 | pTmpFootnote->Paste( pCont, pNx ); | ||||
2809 | pTmpFootnote->Calc(getRootFrame()->GetCurrShell()->GetOut()); | ||||
2810 | } | ||||
2811 | OSL_ENSURE( pTmpFootnote->GetAttr() == FindFootnoteFrame()->GetAttr(), "Wrong Footnote!" )do { if (true && (!(pTmpFootnote->GetAttr() == FindFootnoteFrame ()->GetAttr()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "2811" ": "), "%s", "Wrong Footnote!"); } } while (false ); | ||||
2812 | // areas inside of footnotes get a special treatment | ||||
2813 | SwLayoutFrame *pNewUp = pTmpFootnote; | ||||
2814 | if( IsInSct() ) | ||||
2815 | { | ||||
2816 | SwSectionFrame* pSect = FindSctFrame(); | ||||
2817 | // area inside of a footnote (or only footnote in an area)? | ||||
2818 | if( pSect->IsInFootnote() ) | ||||
2819 | { | ||||
2820 | if( pTmpFootnote->Lower() && pTmpFootnote->Lower()->IsSctFrame() && | ||||
2821 | pSect->GetFollow() == static_cast<SwSectionFrame*>(pTmpFootnote->Lower()) ) | ||||
2822 | pNewUp = static_cast<SwSectionFrame*>(pTmpFootnote->Lower()); | ||||
2823 | else | ||||
2824 | { | ||||
2825 | pNewUp = new SwSectionFrame( *pSect, false ); | ||||
2826 | pNewUp->InsertBefore( pTmpFootnote, pTmpFootnote->Lower() ); | ||||
2827 | static_cast<SwSectionFrame*>(pNewUp)->Init(); | ||||
2828 | |||||
2829 | { | ||||
2830 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*pNewUp); | ||||
2831 | aFrm.Pos() = pTmpFootnote->getFrameArea().Pos(); | ||||
2832 | aFrm.Pos().AdjustY(1 ); // for notifications | ||||
2833 | } | ||||
2834 | |||||
2835 | // If the section frame has a successor then the latter needs | ||||
2836 | // to be moved behind the new Follow of the section frame. | ||||
2837 | SwFrame* pTmp = pSect->GetNext(); | ||||
2838 | if( pTmp ) | ||||
2839 | { | ||||
2840 | SwFlowFrame* pTmpNxt; | ||||
2841 | if( pTmp->IsContentFrame() ) | ||||
2842 | pTmpNxt = static_cast<SwContentFrame*>(pTmp); | ||||
2843 | else if( pTmp->IsSctFrame() ) | ||||
2844 | pTmpNxt = static_cast<SwSectionFrame*>(pTmp); | ||||
2845 | else | ||||
2846 | { | ||||
2847 | OSL_ENSURE( pTmp->IsTabFrame(), "GetNextSctLeaf: Wrong Type" )do { if (true && (!(pTmp->IsTabFrame()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" ":" "2847" ": "), "%s", "GetNextSctLeaf: Wrong Type"); } } while (false); | ||||
2848 | pTmpNxt = static_cast<SwTabFrame*>(pTmp); | ||||
2849 | } | ||||
2850 | pTmpNxt->MoveSubTree( pTmpFootnote, pNewUp->GetNext() ); | ||||
2851 | } | ||||
2852 | } | ||||
2853 | } | ||||
2854 | } | ||||
2855 | |||||
2856 | MoveSubTree( pNewUp, pNewUp->Lower() ); | ||||
2857 | |||||
2858 | if( !bSameBoss ) | ||||
2859 | Prepare( PrepareHint::BossChanged ); | ||||
2860 | } | ||||
2861 | return bSamePage; | ||||
2862 | } | ||||
2863 | |||||
2864 | SwSaveFootnoteHeight::SwSaveFootnoteHeight( SwFootnoteBossFrame *pBs, const SwTwips nDeadLine ) : | ||||
2865 | pBoss( pBs ), | ||||
2866 | nOldHeight( pBs->GetMaxFootnoteHeight() ) | ||||
2867 | { | ||||
2868 | pBoss->SetFootnoteDeadLine( nDeadLine ); | ||||
2869 | nNewHeight = pBoss->GetMaxFootnoteHeight(); | ||||
2870 | } | ||||
2871 | |||||
2872 | SwSaveFootnoteHeight::~SwSaveFootnoteHeight() | ||||
2873 | { | ||||
2874 | // If somebody tweaked the deadline meanwhile, we let it happen | ||||
2875 | if ( nNewHeight == pBoss->GetMaxFootnoteHeight() ) | ||||
2876 | pBoss->m_nMaxFootnoteHeight = nOldHeight; | ||||
2877 | } | ||||
2878 | |||||
2879 | #ifdef DBG_UTIL | ||||
2880 | //JP 15.10.2001: in a non pro version test if the attribute has the same | ||||
2881 | // meaning which his reference is | ||||
2882 | |||||
2883 | // Normally, the pRef member and the GetRefFromAttr() result has to be | ||||
2884 | // identically. Sometimes footnote will be moved from a master to its follow, | ||||
2885 | // but the GetRef() is called first, so we have to ignore a master/follow | ||||
2886 | // mismatch. | ||||
2887 | |||||
2888 | const SwContentFrame* SwFootnoteFrame::GetRef() const | ||||
2889 | { | ||||
2890 | const SwContentFrame* pRefAttr = GetRefFromAttr(); | ||||
2891 | // check consistency: access to deleted frame? | ||||
2892 | assert(mpReference == pRefAttr || mpReference->IsAnFollow(pRefAttr)(static_cast <bool> (mpReference == pRefAttr || mpReference ->IsAnFollow(pRefAttr) || pRefAttr->IsAnFollow(mpReference )) ? void (0) : __assert_fail ("mpReference == pRefAttr || mpReference->IsAnFollow(pRefAttr) || pRefAttr->IsAnFollow(mpReference)" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" , 2893, __extension__ __PRETTY_FUNCTION__)) | ||||
2893 | || pRefAttr->IsAnFollow(mpReference))(static_cast <bool> (mpReference == pRefAttr || mpReference ->IsAnFollow(pRefAttr) || pRefAttr->IsAnFollow(mpReference )) ? void (0) : __assert_fail ("mpReference == pRefAttr || mpReference->IsAnFollow(pRefAttr) || pRefAttr->IsAnFollow(mpReference)" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" , 2893, __extension__ __PRETTY_FUNCTION__)); | ||||
2894 | (void) pRefAttr; | ||||
2895 | return mpReference; | ||||
2896 | } | ||||
2897 | |||||
2898 | SwContentFrame* SwFootnoteFrame::GetRef() | ||||
2899 | { | ||||
2900 | const SwContentFrame* pRefAttr = GetRefFromAttr(); | ||||
2901 | // check consistency: access to deleted frame? | ||||
2902 | assert(mpReference == pRefAttr || mpReference->IsAnFollow(pRefAttr)(static_cast <bool> (mpReference == pRefAttr || mpReference ->IsAnFollow(pRefAttr) || pRefAttr->IsAnFollow(mpReference )) ? void (0) : __assert_fail ("mpReference == pRefAttr || mpReference->IsAnFollow(pRefAttr) || pRefAttr->IsAnFollow(mpReference)" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" , 2903, __extension__ __PRETTY_FUNCTION__)) | ||||
2903 | || pRefAttr->IsAnFollow(mpReference))(static_cast <bool> (mpReference == pRefAttr || mpReference ->IsAnFollow(pRefAttr) || pRefAttr->IsAnFollow(mpReference )) ? void (0) : __assert_fail ("mpReference == pRefAttr || mpReference->IsAnFollow(pRefAttr) || pRefAttr->IsAnFollow(mpReference)" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" , 2903, __extension__ __PRETTY_FUNCTION__)); | ||||
2904 | (void) pRefAttr; | ||||
2905 | return mpReference; | ||||
2906 | } | ||||
2907 | #endif | ||||
2908 | |||||
2909 | const SwContentFrame* SwFootnoteFrame::GetRefFromAttr() const | ||||
2910 | { | ||||
2911 | SwFootnoteFrame* pThis = const_cast<SwFootnoteFrame*>(this); | ||||
2912 | return pThis->GetRefFromAttr(); | ||||
2913 | } | ||||
2914 | |||||
2915 | SwContentFrame* SwFootnoteFrame::GetRefFromAttr() | ||||
2916 | { | ||||
2917 | assert(mpAttribute && "invalid Attribute")(static_cast <bool> (mpAttribute && "invalid Attribute" ) ? void (0) : __assert_fail ("mpAttribute && \"invalid Attribute\"" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/ftnfrm.cxx" , 2917, __extension__ __PRETTY_FUNCTION__)); | ||||
2918 | SwTextNode& rTNd = const_cast<SwTextNode&>(mpAttribute->GetTextNode()); | ||||
2919 | SwPosition aPos( rTNd, SwIndex( &rTNd, mpAttribute->GetStart() )); | ||||
2920 | SwContentFrame* pCFrame = rTNd.getLayoutFrame(getRootFrame(), &aPos); | ||||
2921 | return pCFrame; | ||||
2922 | } | ||||
2923 | |||||
2924 | /** search for last content in the current footnote frame | ||||
2925 | |||||
2926 | OD 2005-12-02 #i27138# | ||||
2927 | */ | ||||
2928 | SwContentFrame* SwFootnoteFrame::FindLastContent() | ||||
2929 | { | ||||
2930 | SwContentFrame* pLastContentFrame( nullptr ); | ||||
2931 | |||||
2932 | // find last lower, which is a content frame or contains content. | ||||
2933 | // hidden text frames, empty sections and empty tables have to be skipped. | ||||
2934 | SwFrame* pLastLowerOfFootnote( GetLower() ); | ||||
2935 | SwFrame* pTmpLastLower( pLastLowerOfFootnote ); | ||||
2936 | while ( pTmpLastLower && pTmpLastLower->GetNext() ) | ||||
2937 | { | ||||
2938 | pTmpLastLower = pTmpLastLower->GetNext(); | ||||
2939 | if ( ( pTmpLastLower->IsTextFrame() && | ||||
2940 | !static_cast<SwTextFrame*>(pTmpLastLower)->IsHiddenNow() ) || | ||||
2941 | ( pTmpLastLower->IsSctFrame() && | ||||
2942 | static_cast<SwSectionFrame*>(pTmpLastLower)->GetSection() && | ||||
2943 | static_cast<SwSectionFrame*>(pTmpLastLower)->ContainsContent() ) || | ||||
2944 | ( pTmpLastLower->IsTabFrame() && | ||||
2945 | static_cast<SwTabFrame*>(pTmpLastLower)->ContainsContent() ) ) | ||||
2946 | { | ||||
2947 | pLastLowerOfFootnote = pTmpLastLower; | ||||
2948 | } | ||||
2949 | } | ||||
2950 | |||||
2951 | // determine last content frame depending on type of found last lower. | ||||
2952 | if ( pLastLowerOfFootnote && pLastLowerOfFootnote->IsTabFrame() ) | ||||
2953 | { | ||||
2954 | pLastContentFrame = static_cast<SwTabFrame*>(pLastLowerOfFootnote)->FindLastContent(); | ||||
2955 | } | ||||
2956 | else if ( pLastLowerOfFootnote && pLastLowerOfFootnote->IsSctFrame() ) | ||||
2957 | { | ||||
2958 | pLastContentFrame = static_cast<SwSectionFrame*>(pLastLowerOfFootnote)->FindLastContent(); | ||||
2959 | } | ||||
2960 | else | ||||
2961 | { | ||||
2962 | pLastContentFrame = dynamic_cast<SwContentFrame*>(pLastLowerOfFootnote); | ||||
2963 | } | ||||
2964 | |||||
2965 | return pLastContentFrame; | ||||
2966 | } | ||||
2967 | |||||
2968 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | /* |
3 | * This file is part of the LibreOffice project. |
4 | * |
5 | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | * |
9 | * This file incorporates work covered by the following license notice: |
10 | * |
11 | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | * contributor license agreements. See the NOTICE file distributed |
13 | * with this work for additional information regarding copyright |
14 | * ownership. The ASF licenses this file to you under the Apache |
15 | * License, Version 2.0 (the "License"); you may not use this file |
16 | * except in compliance with the License. You may obtain a copy of |
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | */ |
19 | |
20 | #ifndef INCLUDED_SW_SOURCE_CORE_INC_FRAME_HXX |
21 | #define INCLUDED_SW_SOURCE_CORE_INC_FRAME_HXX |
22 | |
23 | #include <drawinglayer/primitive2d/baseprimitive2d.hxx> |
24 | #include <editeng/borderline.hxx> |
25 | #include <svl/poolitem.hxx> |
26 | #include <swtypes.hxx> |
27 | #include <swrect.hxx> |
28 | #include <calbck.hxx> |
29 | #include <svl/SfxBroadcaster.hxx> |
30 | #include <o3tl/typed_flags_set.hxx> |
31 | #include <com/sun/star/style/TabStop.hpp> |
32 | #include <basegfx/matrix/b2dhommatrix.hxx> |
33 | #include <vcl/outdev.hxx> |
34 | |
35 | #include <memory> |
36 | |
37 | namespace drawinglayer::processor2d { class BaseProcessor2D; } |
38 | |
39 | class SwLayoutFrame; |
40 | class SwRootFrame; |
41 | class SwPageFrame; |
42 | class SwBodyFrame; |
43 | class SwFlyFrame; |
44 | class SwSectionFrame; |
45 | class SwFootnoteFrame; |
46 | class SwFootnoteBossFrame; |
47 | class SwTabFrame; |
48 | class SwRowFrame; |
49 | class SwContentFrame; |
50 | class SwAttrSet; |
51 | class Color; |
52 | class SwBorderAttrs; |
53 | class SwCache; |
54 | class SvxBrushItem; |
55 | class SvxFormatBreakItem; |
56 | class SwFormatPageDesc; |
57 | class SwSelectionList; |
58 | struct SwPosition; |
59 | struct SwCursorMoveState; |
60 | class SwFormat; |
61 | class SwPrintData; |
62 | class SwSortedObjs; |
63 | class SwAnchoredObject; |
64 | enum class SvxFrameDirection; |
65 | class IDocumentDrawModelAccess; |
66 | |
67 | // Each FrameType is represented here as a bit. |
68 | // The bits must be set in a way that it can be determined with masking of |
69 | // which kind of FrameType an instance is _and_ from what classes it was derived. |
70 | // Each frame has in its base class a member that must be set by the |
71 | // constructors accordingly. |
72 | enum class SwFrameType |
73 | { |
74 | None = 0x0000, |
75 | Root = 0x0001, |
76 | Page = 0x0002, |
77 | Column = 0x0004, |
78 | Header = 0x0008, |
79 | Footer = 0x0010, |
80 | FtnCont = 0x0020, |
81 | Ftn = 0x0040, |
82 | Body = 0x0080, |
83 | Fly = 0x0100, |
84 | Section = 0x0200, |
85 | // UNUSED 0x0400 |
86 | Tab = 0x0800, |
87 | Row = 0x1000, |
88 | Cell = 0x2000, |
89 | Txt = 0x4000, |
90 | NoTxt = 0x8000, |
91 | }; |
92 | |
93 | namespace o3tl |
94 | { |
95 | template<> struct typed_flags<SwFrameType> : is_typed_flags<SwFrameType, 0xfbff> {}; |
96 | }; |
97 | |
98 | // for internal use some common combinations |
99 | #define FRM_LAYOUTSwFrameType(0x3bFF) SwFrameType(0x3bFF) |
100 | #define FRM_ALLSwFrameType(0xfbff) SwFrameType(0xfbff) |
101 | #define FRM_CNTNT(SwFrameType::Txt | SwFrameType::NoTxt) (SwFrameType::Txt | SwFrameType::NoTxt) |
102 | #define FRM_FTNBOSS(SwFrameType::Page | SwFrameType::Column) (SwFrameType::Page | SwFrameType::Column) |
103 | #define FRM_ACCESSIBLE(SwFrameType::Root | SwFrameType::Page | SwFrameType::Header | SwFrameType::Footer | SwFrameType::Ftn | SwFrameType::Fly | SwFrameType ::Tab | SwFrameType::Cell | SwFrameType::Txt) (SwFrameType::Root | SwFrameType::Page | SwFrameType::Header | SwFrameType::Footer | SwFrameType::Ftn | SwFrameType::Fly | SwFrameType::Tab | SwFrameType::Cell | SwFrameType::Txt) |
104 | #define FRM_NEIGHBOUR(SwFrameType::Column | SwFrameType::Cell) (SwFrameType::Column | SwFrameType::Cell) |
105 | #define FRM_NOTE_VERT(SwFrameType::FtnCont | SwFrameType::Ftn | SwFrameType::Section | SwFrameType::Tab | SwFrameType::Row | SwFrameType::Cell | SwFrameType ::Txt) (SwFrameType::FtnCont | SwFrameType::Ftn | SwFrameType::Section | SwFrameType::Tab | SwFrameType::Row | SwFrameType::Cell | SwFrameType::Txt) |
106 | #define FRM_HEADFOOT(SwFrameType::Header | SwFrameType::Footer) (SwFrameType::Header | SwFrameType::Footer) |
107 | #define FRM_BODYFTNC(SwFrameType::FtnCont | SwFrameType::Body) (SwFrameType::FtnCont | SwFrameType::Body) |
108 | |
109 | // for GetNextLeaf/GetPrevLeaf. |
110 | enum MakePageType |
111 | { |
112 | MAKEPAGE_NONE, // do not create page/footnote |
113 | MAKEPAGE_APPEND, // only append page if needed |
114 | MAKEPAGE_INSERT, // add or append page if needed |
115 | MAKEPAGE_FTN, // add footnote if needed |
116 | MAKEPAGE_NOSECTION // Don't create section frames |
117 | }; |
118 | |
119 | namespace drawinglayer::attribute { |
120 | class SdrAllFillAttributesHelper; |
121 | typedef std::shared_ptr< SdrAllFillAttributesHelper > SdrAllFillAttributesHelperPtr; |
122 | } |
123 | |
124 | /// Helper class to isolate geometry-defining members of SwFrame |
125 | /// and to control their accesses. Moved to own class to have no |
126 | /// hidden accesses to 'private' members anymore. |
127 | /// |
128 | /// Added most important flags about the state of this geometric |
129 | /// information and if it is valid or not |
130 | class SAL_DLLPUBLIC_RTTI__attribute__ ((type_visibility("default"))) SwFrameAreaDefinition |
131 | { |
132 | private: |
133 | friend void FriendHackInvalidateRowFrame(SwFrameAreaDefinition &); |
134 | |
135 | // The absolute position and size of the SwFrame in the document. |
136 | // This values are set by the layouter implementations |
137 | SwRect maFrameArea; |
138 | |
139 | // The 'inner' Frame Area defined by a SwRect relative to FrameArea: |
140 | // When identical to FrameArea, Pos() will be (0, 0) and Size identical. |
141 | SwRect maFramePrintArea; |
142 | |
143 | // bitfield |
144 | bool mbFrameAreaPositionValid : 1; |
145 | bool mbFrameAreaSizeValid : 1; |
146 | bool mbFramePrintAreaValid : 1; |
147 | |
148 | // #i65250# |
149 | // frame ID is now in general available - used for layout loop control |
150 | static sal_uInt32 mnLastFrameId; |
151 | const sal_uInt32 mnFrameId; |
152 | |
153 | protected: |
154 | // write access to mb*Valid flags |
155 | void setFrameAreaPositionValid(bool bNew); |
156 | void setFrameAreaSizeValid(bool bNew); |
157 | void setFramePrintAreaValid(bool bNew); |
158 | |
159 | public: |
160 | SwFrameAreaDefinition(); |
161 | virtual ~SwFrameAreaDefinition(); |
162 | |
163 | // read access to mb*Valid flags |
164 | bool isFrameAreaPositionValid() const { return mbFrameAreaPositionValid; } |
165 | bool isFrameAreaSizeValid() const { return mbFrameAreaSizeValid; } |
166 | bool isFramePrintAreaValid() const { return mbFramePrintAreaValid; } |
167 | |
168 | // syntactic sugar: test whole FrameAreaDefinition |
169 | bool isFrameAreaDefinitionValid() const { return isFrameAreaPositionValid() && isFrameAreaSizeValid() && isFramePrintAreaValid(); } |
170 | |
171 | // #i65250# |
172 | sal_uInt32 GetFrameId() const { return mnFrameId; } |
173 | |
174 | // read accesses to FrameArea definitions - only const access allowed. |
175 | // Do *not* const_cast results, it is necessary to track changes. use |
176 | // the below offered WriteAccess helper classes instead |
177 | const SwRect& getFrameArea() const { return maFrameArea; } |
178 | const SwRect& getFramePrintArea() const { return maFramePrintArea; } |
179 | |
180 | // helper class(es) for FrameArea manipulation. These |
181 | // have to be used to apply changes to FrameAreas. They hold a copy of the |
182 | // SwRect for manipulation. It gets written back at destruction. Thus, this |
183 | // mechanism depends on scope usage, take care. It prevents errors using |
184 | // different instances of SwFrame in get/set methods which is more safe |
185 | class FrameAreaWriteAccess : public SwRect |
186 | { |
187 | private: |
188 | SwFrameAreaDefinition& mrTarget; |
189 | |
190 | FrameAreaWriteAccess(const FrameAreaWriteAccess&) = delete; |
191 | FrameAreaWriteAccess& operator=(const FrameAreaWriteAccess&) = delete; |
192 | |
193 | public: |
194 | FrameAreaWriteAccess(SwFrameAreaDefinition& rTarget) : SwRect(rTarget.getFrameArea()), mrTarget(rTarget) {} |
195 | ~FrameAreaWriteAccess(); |
196 | void setSwRect(const SwRect& rNew) { *reinterpret_cast< SwRect* >(this) = rNew; } |
197 | }; |
198 | |
199 | // same helper for FramePrintArea |
200 | class FramePrintAreaWriteAccess : public SwRect |
201 | { |
202 | private: |
203 | SwFrameAreaDefinition& mrTarget; |
204 | |
205 | FramePrintAreaWriteAccess(const FramePrintAreaWriteAccess&) = delete; |
206 | FramePrintAreaWriteAccess& operator=(const FramePrintAreaWriteAccess&) = delete; |
207 | |
208 | public: |
209 | FramePrintAreaWriteAccess(SwFrameAreaDefinition& rTarget) : SwRect(rTarget.getFramePrintArea()), mrTarget(rTarget) {} |
210 | ~FramePrintAreaWriteAccess(); |
211 | void setSwRect(const SwRect& rNew) { *reinterpret_cast< SwRect* >(this) = rNew; } |
212 | }; |
213 | |
214 | // RotateFlyFrame3 - Support for Transformations |
215 | // Hand out the Transformations for the current FrameAreaDefinition |
216 | // for the FrameArea and FramePrintArea. |
217 | // FramePrintArea is not relative to FrameArea in this |
218 | // transformation representation (to make it easier to use and understand). |
219 | // There is no 'set' method since SwFrame is a layout object. For |
220 | // some cases rotation will be included (used for SwGrfNode in inner |
221 | // SwFrame of a SwFlyFrame) |
222 | virtual basegfx::B2DHomMatrix getFrameAreaTransformation() const; |
223 | virtual basegfx::B2DHomMatrix getFramePrintAreaTransformation() const; |
224 | |
225 | // RotateFlyFrame3 - Support for Transformations |
226 | // Modify current transformations by applying given translation |
227 | virtual void transform_translate(const Point& rOffset); |
228 | }; |
229 | |
230 | /// RotateFlyFrame3: Helper class when you want to make your SwFrame derivate |
231 | /// transformable. It provides some tooling to do so. To use, add as member |
232 | /// (see e.g. SwFlyFreeFrame which uses 'std::unique_ptr< TransformableSwFrame >') |
233 | class TransformableSwFrame |
234 | { |
235 | private: |
236 | // The SwFrameAreaDefinition to work on |
237 | SwFrameAreaDefinition& mrSwFrameAreaDefinition; |
238 | |
239 | // FrameAreaTransformation and FramePrintAreaTransformation |
240 | // !identity when needed (translate/scale is used (e.g. rotation)) |
241 | basegfx::B2DHomMatrix maFrameAreaTransformation; |
242 | basegfx::B2DHomMatrix maFramePrintAreaTransformation; |
243 | |
244 | public: |
245 | TransformableSwFrame(SwFrameAreaDefinition& rSwFrameAreaDefinition) |
246 | : mrSwFrameAreaDefinition(rSwFrameAreaDefinition), |
247 | maFrameAreaTransformation(), |
248 | maFramePrintAreaTransformation() |
249 | { |
250 | } |
251 | |
252 | // get SwFrameArea in transformation form |
253 | const basegfx::B2DHomMatrix& getLocalFrameAreaTransformation() const |
254 | { |
255 | return maFrameAreaTransformation; |
256 | } |
257 | |
258 | // get SwFramePrintArea in transformation form |
259 | const basegfx::B2DHomMatrix& getLocalFramePrintAreaTransformation() const |
260 | { |
261 | return maFramePrintAreaTransformation; |
262 | } |
263 | |
264 | // Helpers to re-create the untransformed SwRect(s) originally |
265 | // in the SwFrameAreaDefinition, based on the current Transformations. |
266 | SwRect getUntransformedFrameArea() const; |
267 | SwRect getUntransformedFramePrintArea() const; |
268 | |
269 | // Helper method to re-create FrameAreaTransformations based on the |
270 | // current FrameAreaDefinition transformed by given rotation and Center |
271 | void createFrameAreaTransformations( |
272 | double fRotation, |
273 | const basegfx::B2DPoint& rCenter); |
274 | |
275 | // Tooling method to reset the SwRect(s) in the current |
276 | // SwFrameAreaDefinition which are already adapted to |
277 | // Transformation back to the untransformed state, using |
278 | // the getUntransformedFrame*Area calls above when needed. |
279 | // Only the SwRect(s) are changed back, not the transformations. |
280 | void restoreFrameAreas(); |
281 | |
282 | // Re-Creates the SwRect(s) as BoundAreas based on the current |
283 | // set Transformations. |
284 | void adaptFrameAreasToTransformations(); |
285 | |
286 | // Modify current definitions by applying the given transformation |
287 | void transform(const basegfx::B2DHomMatrix& aTransform); |
288 | }; |
289 | |
290 | /** |
291 | * Base class of the Writer layout elements. |
292 | * |
293 | * This includes not only fly frames, but everything down to the paragraph |
294 | * level: pages, headers, footers, etc. (Inside a paragraph SwLinePortion |
295 | * instances are used.) |
296 | */ |
297 | class SW_DLLPUBLIC__attribute__ ((visibility("default"))) SwFrame : public SwFrameAreaDefinition, public SwClient, public SfxBroadcaster |
298 | { |
299 | // the hidden Frame |
300 | friend class SwFlowFrame; |
301 | friend class SwLayoutFrame; |
302 | friend class SwLooping; |
303 | friend class SwDeletionChecker; // for GetDep() |
304 | |
305 | // voids lower during creation of a column |
306 | friend SwFrame *SaveContent( SwLayoutFrame *, SwFrame* pStart ); |
307 | friend void RestoreContent( SwFrame *, SwLayoutFrame *, SwFrame *pSibling ); |
308 | |
309 | // for validating a mistakenly invalidated one in SwContentFrame::MakeAll |
310 | friend void ValidateSz( SwFrame *pFrame ); |
311 | // implemented in text/txtftn.cxx, prevents Footnote oscillation |
312 | friend void ValidateText( SwFrame *pFrame ); |
313 | |
314 | friend void MakeNxt( SwFrame *pFrame, SwFrame *pNxt ); |
315 | |
316 | // cache for (border) attributes |
317 | static SwCache *mpCache; |
318 | |
319 | SwRootFrame *mpRoot; |
320 | SwLayoutFrame *mpUpper; |
321 | SwFrame *mpNext; |
322 | SwFrame *mpPrev; |
323 | |
324 | // sw_redlinehide: hide these dangerous SwClient functions |
325 | using SwClient::GetRegisteredInNonConst; |
326 | using SwClient::GetRegisteredIn; |
327 | |
328 | SwFrame *FindNext_(); |
329 | SwFrame *FindPrev_(); |
330 | |
331 | /** method to determine next content frame in the same environment |
332 | for a flow frame (content frame, table frame, section frame) |
333 | |
334 | #i27138# - adding documentation: |
335 | Travelling downwards through the layout to determine the next content |
336 | frame in the same environment. There are several environments in a |
337 | document, which form a closed context regarding this function. These |
338 | environments are: |
339 | - Each page header |
340 | - Each page footer |
341 | - Each unlinked fly frame |
342 | - Each group of linked fly frames |
343 | - All footnotes |
344 | - All document body frames |
345 | #i27138# - adding parameter <_bInSameFootnote> |
346 | Its default value is <false>. If its value is <true>, the environment |
347 | 'All footnotes' is no longer treated. Instead each footnote is treated |
348 | as an own environment. |
349 | |
350 | @param _bInSameFootnote |
351 | input parameter - boolean indicating, that the found next content |
352 | frame has to be in the same footnote frame. This parameter is only |
353 | relevant for flow frames in footnotes. |
354 | |
355 | @return SwContentFrame* |
356 | pointer to the found next content frame. It's NULL, if none exists. |
357 | */ |
358 | SwContentFrame* FindNextCnt_( const bool _bInSameFootnote ); |
359 | |
360 | /** method to determine previous content frame in the same environment |
361 | for a flow frame (content frame, table frame, section frame) |
362 | |
363 | #i27138# |
364 | Travelling upwards through the layout to determine the previous content |
365 | frame in the same environment. There are several environments in a |
366 | document, which form a closed context regarding this function. These |
367 | environments are: |
368 | - Each page header |
369 | - Each page footer |
370 | - Each unlinked fly frame |
371 | - Each group of linked fly frames |
372 | - All footnotes |
373 | - All document body frames |
374 | #i27138# - adding parameter <_bInSameFootnote> |
375 | Its default value is <false>. If its value is <true>, the environment |
376 | 'All footnotes' is no longer treated. Instead each footnote is treated |
377 | as an own environment. |
378 | |
379 | The found previous content frame has to be in the same footnote frame. This is only |
380 | relevant for flow frames in footnotes. |
381 | |
382 | @return SwContentFrame* |
383 | pointer to the found previous content frame. It's NULL, if none exists. |
384 | */ |
385 | SwContentFrame* FindPrevCnt_(); |
386 | |
387 | void UpdateAttrFrame( const SfxPoolItem*, const SfxPoolItem*, sal_uInt8 & ); |
388 | SwFrame* GetIndNext_(); |
389 | void SetDirFlags( bool bVert ); |
390 | |
391 | const SwLayoutFrame* ImplGetNextLayoutLeaf( bool bFwd ) const; |
392 | |
393 | SwPageFrame* ImplFindPageFrame(); |
394 | |
395 | protected: |
396 | std::unique_ptr<SwSortedObjs> m_pDrawObjs; // draw objects, can be null |
397 | SwFrameType mnFrameType; //Who am I? |
398 | |
399 | bool mbInDtor : 1; |
400 | bool mbInvalidR2L : 1; |
401 | bool mbDerivedR2L : 1; |
402 | bool mbRightToLeft : 1; |
403 | bool mbInvalidVert : 1; |
404 | bool mbDerivedVert : 1; |
405 | bool mbVertical : 1; |
406 | |
407 | bool mbVertLR : 1; |
408 | bool mbVertLRBT : 1; |
409 | |
410 | bool mbValidLineNum : 1; |
411 | bool mbFixSize : 1; |
412 | |
413 | // if true, frame will be painted completely even content was changed |
414 | // only partially. For ContentFrames a border (from Action) will exclusively |
415 | // painted if <mbCompletePaint> is true. |
416 | bool mbCompletePaint : 1; |
417 | |
418 | bool mbRetouche : 1; // frame is responsible for retouching |
419 | |
420 | bool mbInfInvalid : 1; // InfoFlags are invalid |
421 | bool mbInfBody : 1; // Frame is in document body |
422 | bool mbInfTab : 1; // Frame is in a table |
423 | bool mbInfFly : 1; // Frame is in a Fly |
424 | bool mbInfFootnote : 1; // Frame is in a footnote |
425 | bool mbInfSct : 1; // Frame is in a section |
426 | bool mbColLocked : 1; // lock Grow/Shrink for column-wise section |
427 | // or fly frames, will be set in Format |
428 | bool m_isInDestroy : 1; |
429 | bool mbForbidDelete : 1; |
430 | |
431 | void ColLock() { mbColLocked = true; } |
432 | void ColUnlock() { mbColLocked = false; } |
433 | |
434 | virtual void DestroyImpl(); |
435 | virtual ~SwFrame() override; |
436 | |
437 | // Only used by SwRootFrame Ctor to get 'this' into mpRoot... |
438 | void setRootFrame( SwRootFrame* pRoot ) { mpRoot = pRoot; } |
439 | |
440 | SwPageFrame *InsertPage( SwPageFrame *pSibling, bool bFootnote ); |
441 | void PrepareMake(vcl::RenderContext* pRenderContext); |
442 | void OptPrepareMake(); |
443 | virtual void MakePos(); |
444 | // Format next frame of table frame to assure keeping attributes. |
445 | // In case of nested tables method <SwFrame::MakeAll()> is called to |
446 | // avoid formatting of superior table frame. |
447 | friend SwFrame* sw_FormatNextContentForKeep( SwTabFrame* pTabFrame ); |
448 | |
449 | virtual void MakeAll(vcl::RenderContext* pRenderContext) = 0; |
450 | // adjust frames of a page |
451 | SwTwips AdjustNeighbourhood( SwTwips nDiff, bool bTst = false ); |
452 | |
453 | // change only frame size not the size of PrtArea |
454 | virtual SwTwips ShrinkFrame( SwTwips, bool bTst = false, bool bInfo = false ) = 0; |
455 | virtual SwTwips GrowFrame ( SwTwips, bool bTst = false, bool bInfo = false ) = 0; |
456 | |
457 | /// use these so we can grep for SwFrame's GetRegisteredIn accesses |
458 | /// beware that SwTextFrame may return sw::WriterMultiListener |
459 | SwModify *GetDep() { return GetRegisteredInNonConst(); } |
460 | const SwModify *GetDep() const { return GetRegisteredIn(); } |
461 | |
462 | SwFrame( SwModify*, SwFrame* ); |
463 | |
464 | void CheckDir( SvxFrameDirection nDir, bool bVert, bool bOnlyBiDi, bool bBrowse ); |
465 | |
466 | /** enumeration for the different invalidations |
467 | #i28701# |
468 | */ |
469 | enum InvalidationType |
470 | { |
471 | INVALID_SIZE, INVALID_PRTAREA, INVALID_POS, INVALID_LINENUM, INVALID_ALL |
472 | }; |
473 | |
474 | /** method to determine, if an invalidation is allowed. |
475 | #i28701 |
476 | */ |
477 | virtual bool InvalidationAllowed( const InvalidationType _nInvalid ) const; |
478 | |
479 | /** method to perform additional actions on an invalidation |
480 | |
481 | #i28701# |
482 | Method has *only* to contain actions, which has to be performed on |
483 | *every* assignment of the corresponding flag to <false>. |
484 | */ |
485 | virtual void ActionOnInvalidation( const InvalidationType _nInvalid ); |
486 | |
487 | // draw shadow and borders |
488 | void PaintShadow( const SwRect&, SwRect&, const SwBorderAttrs& ) const; |
489 | virtual void Modify( const SfxPoolItem*, const SfxPoolItem* ) override; |
490 | |
491 | virtual const IDocumentDrawModelAccess& getIDocumentDrawModelAccess( ); |
492 | |
493 | public: |
494 | virtual css::uno::Sequence< css::style::TabStop > GetTabStopInfo( SwTwips ) |
495 | { |
496 | return css::uno::Sequence< css::style::TabStop >(); |
497 | } |
498 | |
499 | |
500 | SwFrameType GetType() const { return mnFrameType; } |
501 | |
502 | static SwCache &GetCache() { return *mpCache; } |
503 | static SwCache *GetCachePtr() { return mpCache; } |
504 | static void SetCache( SwCache *pNew ) { mpCache = pNew; } |
505 | |
506 | // change PrtArea size and FrameSize |
507 | SwTwips Shrink( SwTwips, bool bTst = false, bool bInfo = false ); |
508 | SwTwips Grow ( SwTwips, bool bTst = false, bool bInfo = false ); |
509 | |
510 | // different methods for inserting in layout tree (for performance reasons) |
511 | |
512 | // insert before pBehind or at the end of the chain below mpUpper |
513 | void InsertBefore( SwLayoutFrame* pParent, SwFrame* pBehind ); |
514 | // insert after pBefore or at the beginning of the chain below mpUpper |
515 | void InsertBehind( SwLayoutFrame *pParent, SwFrame *pBefore ); |
516 | // insert before pBehind or at the end of the chain while considering |
517 | // the siblings of pSct |
518 | bool InsertGroupBefore( SwFrame* pParent, SwFrame* pWhere, SwFrame* pSct ); |
519 | void RemoveFromLayout(); |
520 | |
521 | // For internal use only - who ignores this will be put in a sack and has |
522 | // to stay there for two days |
523 | // Does special treatment for Get_[Next|Prev]Leaf() (for tables). |
524 | SwLayoutFrame *GetLeaf( MakePageType eMakePage, bool bFwd ); |
525 | SwLayoutFrame *GetNextLeaf ( MakePageType eMakePage ); |
526 | SwLayoutFrame *GetNextFootnoteLeaf( MakePageType eMakePage ); |
527 | SwLayoutFrame *GetNextSctLeaf( MakePageType eMakePage ); |
528 | SwLayoutFrame *GetNextCellLeaf(); |
529 | SwLayoutFrame *GetPrevLeaf (); |
530 | SwLayoutFrame *GetPrevFootnoteLeaf( MakePageType eMakeFootnote ); |
531 | SwLayoutFrame *GetPrevSctLeaf(); |
532 | SwLayoutFrame *GetPrevCellLeaf(); |
533 | const SwLayoutFrame *GetLeaf ( MakePageType eMakePage, bool bFwd, |
534 | const SwFrame *pAnch ) const; |
535 | |
536 | bool WrongPageDesc( SwPageFrame* pNew ); |
537 | |
538 | //#i28701# - new methods to append/remove drawing objects |
539 | void AppendDrawObj( SwAnchoredObject& _rNewObj ); |
540 | void RemoveDrawObj( SwAnchoredObject& _rToRemoveObj ); |
541 | |
542 | // work with chain of FlyFrames |
543 | void AppendFly( SwFlyFrame *pNew ); |
544 | void RemoveFly( SwFlyFrame *pToRemove ); |
545 | const SwSortedObjs *GetDrawObjs() const { return m_pDrawObjs.get(); } |
546 | SwSortedObjs *GetDrawObjs() { return m_pDrawObjs.get(); } |
547 | // #i28701# - change purpose of method and adjust its name |
548 | void InvalidateObjs( const bool _bNoInvaOfAsCharAnchoredObjs = true ); |
549 | |
550 | virtual void PaintSwFrameShadowAndBorder( |
551 | const SwRect&, |
552 | const SwPageFrame* pPage, |
553 | const SwBorderAttrs&) const; |
554 | void PaintBaBo( const SwRect&, const SwPageFrame *pPage, |
555 | const bool bOnlyTextBackground = false) const; |
556 | void PaintSwFrameBackground( const SwRect&, const SwPageFrame *pPage, |
557 | const SwBorderAttrs &, |
558 | const bool bLowerMode = false, |
559 | const bool bLowerBorder = false, |
560 | const bool bOnlyTextBackground = false ) const; |
561 | void PaintBorderLine( const SwRect&, const SwRect&, const SwPageFrame*, |
562 | const Color *pColor, |
563 | const SvxBorderLineStyle = SvxBorderLineStyle::SOLID ) const; |
564 | |
565 | std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> CreateProcessor2D( ) const; |
566 | void ProcessPrimitives( const drawinglayer::primitive2d::Primitive2DContainer& rSequence ) const; |
567 | |
568 | // retouch, not in the area of the given Rect! |
569 | void Retouch( const SwPageFrame *pPage, const SwRect &rRect ) const; |
570 | |
571 | bool GetBackgroundBrush( |
572 | drawinglayer::attribute::SdrAllFillAttributesHelperPtr& rFillAttributes, |
573 | const SvxBrushItem*& rpBrush, |
574 | const Color*& rpColor, |
575 | SwRect &rOrigRect, |
576 | bool bLowerMode, |
577 | bool bConsiderTextBox ) const; |
578 | |
579 | inline void SetCompletePaint() const; |
580 | inline void ResetCompletePaint() const; |
581 | bool IsCompletePaint() const { return mbCompletePaint; } |
582 | |
583 | inline void SetRetouche() const; |
584 | inline void ResetRetouche() const; |
585 | bool IsRetouche() const { return mbRetouche; } |
586 | |
587 | void SetInfFlags(); |
588 | void InvalidateInfFlags() { mbInfInvalid = true; } |
589 | inline bool IsInDocBody() const; // use InfoFlags, determine flags |
590 | inline bool IsInFootnote() const; // if necessary |
591 | inline bool IsInTab() const; |
592 | inline bool IsInFly() const; |
593 | inline bool IsInSct() const; |
594 | |
595 | // If frame is inside a split table row, this function returns |
596 | // the corresponding row frame in the follow table. |
597 | const SwRowFrame* IsInSplitTableRow() const; |
598 | |
599 | // If frame is inside a follow flow row, this function returns |
600 | // the corresponding row frame master table |
601 | const SwRowFrame* IsInFollowFlowRow() const; |
602 | |
603 | bool IsInBalancedSection() const; |
604 | |
605 | inline bool IsVertical() const; |
606 | inline bool IsVertLR() const; |
607 | inline bool IsVertLRBT() const; |
608 | |
609 | void SetDerivedVert( bool bNew ){ mbDerivedVert = bNew; } |
610 | void SetInvalidVert( bool bNew) { mbInvalidVert = bNew; } |
611 | inline bool IsRightToLeft() const; |
612 | void SetDerivedR2L( bool bNew ) { mbDerivedR2L = bNew; } |
613 | |
614 | void CheckDirChange(); |
615 | // returns upper left frame position for LTR and |
616 | // upper right frame position for Asian / RTL frames |
617 | Point GetFrameAnchorPos( bool bIgnoreFlysAnchoredAtThisFrame ) const; |
618 | |
619 | /** determine, if frame is moveable in given environment |
620 | |
621 | method replaced 'old' method <bool IsMoveable() const>. |
622 | Determines, if frame is moveable in given environment. if no environment |
623 | is given (parameter _pLayoutFrame == 0), the movability in the actual |
624 | environment (<GetUpper()) is checked. |
625 | |
626 | @param _pLayoutFrame |
627 | input parameter - given environment (layout frame), in which the movability |
628 | will be checked. If not set ( == 0 ), actual environment is taken. |
629 | |
630 | @return boolean, indicating, if frame is moveable in given environment |
631 | */ |
632 | bool IsMoveable( const SwLayoutFrame* _pLayoutFrame = nullptr ) const; |
633 | |
634 | // Is it permitted for the (Text)Frame to add a footnote in the current |
635 | // environment (not e.g. for repeating table headlines) |
636 | bool IsFootnoteAllowed() const; |
637 | |
638 | virtual void Format( vcl::RenderContext* pRenderContext, const SwBorderAttrs *pAttrs = nullptr ); |
639 | |
640 | virtual void CheckDirection( bool bVert ); |
641 | |
642 | void ReinitializeFrameSizeAttrFlags(); |
643 | |
644 | /// WARNING: this may not return correct RES_PAGEDESC/RES_BREAK items for |
645 | /// SwTextFrame, use GetBreakItem()/GetPageDescItem() instead |
646 | const SwAttrSet *GetAttrSet() const; |
647 | virtual const SvxFormatBreakItem& GetBreakItem() const; |
648 | virtual const SwFormatPageDesc& GetPageDescItem() const; |
649 | |
650 | bool HasFixSize() const { return mbFixSize; } |
651 | |
652 | // check all pages (starting from the given) and correct them if needed |
653 | static void CheckPageDescs( SwPageFrame *pStart, bool bNotifyFields = true, SwPageFrame** ppPrev = nullptr); |
654 | |
655 | // might return 0, with and without const |
656 | SwFrame *GetNext() { return mpNext; } |
657 | SwFrame *GetPrev() { return mpPrev; } |
658 | SwLayoutFrame *GetUpper() { return mpUpper; } |
659 | SwRootFrame *getRootFrame(){ return mpRoot; } |
660 | SwPageFrame *FindPageFrame() { return IsPageFrame() ? reinterpret_cast<SwPageFrame*>(this) : ImplFindPageFrame(); } |
661 | SwFrame *FindColFrame(); |
662 | SwRowFrame *FindRowFrame(); |
663 | SwFootnoteBossFrame *FindFootnoteBossFrame( bool bFootnotes = false ); |
664 | SwTabFrame *ImplFindTabFrame(); |
665 | SwFootnoteFrame *ImplFindFootnoteFrame(); |
666 | SwFlyFrame *ImplFindFlyFrame(); |
667 | SwSectionFrame *ImplFindSctFrame(); |
668 | const SwBodyFrame *ImplFindBodyFrame() const; |
669 | SwFrame *FindFooterOrHeader(); |
670 | SwFrame *GetLower(); |
671 | const SwFrame *GetNext() const { return mpNext; } |
672 | const SwFrame *GetPrev() const { return mpPrev; } |
673 | const SwLayoutFrame *GetUpper() const { return mpUpper; } |
674 | const SwRootFrame *getRootFrame() const { return mpRoot; } |
675 | inline SwTabFrame *FindTabFrame(); |
676 | inline SwFootnoteFrame *FindFootnoteFrame(); |
677 | inline SwFlyFrame *FindFlyFrame(); |
678 | inline SwSectionFrame *FindSctFrame(); |
679 | inline SwFrame *FindNext(); |
680 | // #i27138# - add parameter <_bInSameFootnote> |
681 | SwContentFrame* FindNextCnt( const bool _bInSameFootnote = false ); |
682 | inline SwFrame *FindPrev(); |
683 | inline const SwPageFrame *FindPageFrame() const; |
684 | inline const SwFootnoteBossFrame *FindFootnoteBossFrame( bool bFootnote = false ) const; |
685 | inline const SwFrame *FindColFrame() const; |
686 | inline const SwFrame *FindFooterOrHeader() const; |
687 | inline const SwTabFrame *FindTabFrame() const; |
688 | inline const SwFootnoteFrame *FindFootnoteFrame() const; |
689 | inline const SwFlyFrame *FindFlyFrame() const; |
690 | inline const SwSectionFrame *FindSctFrame() const; |
691 | inline const SwBodyFrame *FindBodyFrame() const; |
692 | inline const SwFrame *FindNext() const; |
693 | // #i27138# - add parameter <_bInSameFootnote> |
694 | const SwContentFrame* FindNextCnt( const bool _bInSameFootnote = false ) const; |
695 | inline const SwFrame *FindPrev() const; |
696 | const SwFrame *GetLower() const; |
697 | |
698 | SwContentFrame* FindPrevCnt(); |
699 | |
700 | const SwContentFrame* FindPrevCnt() const; |
701 | |
702 | // #i79774# |
703 | SwFrame* GetIndPrev_() const; |
704 | SwFrame* GetIndPrev() const |
705 | { return ( mpPrev || !IsInSct() ) ? mpPrev : GetIndPrev_(); } |
706 | |
707 | SwFrame* GetIndNext() |
708 | { return ( mpNext || !IsInSct() ) ? mpNext : GetIndNext_(); } |
709 | const SwFrame* GetIndNext() const { return const_cast<SwFrame*>(this)->GetIndNext(); } |
710 | |
711 | sal_uInt16 GetPhyPageNum() const; // page number without offset |
712 | sal_uInt16 GetVirtPageNum() const; // page number with offset |
713 | bool OnRightPage() const { return 0 != GetPhyPageNum() % 2; }; |
714 | bool WannaRightPage() const; |
715 | bool OnFirstPage() const; |
716 | |
717 | inline const SwLayoutFrame *GetPrevLayoutLeaf() const; |
718 | inline const SwLayoutFrame *GetNextLayoutLeaf() const; |
719 | inline SwLayoutFrame *GetPrevLayoutLeaf(); |
720 | inline SwLayoutFrame *GetNextLayoutLeaf(); |
721 | |
722 | virtual void Calc(vcl::RenderContext* pRenderContext) const; // here might be "formatted" |
723 | inline void OptCalc() const; // here we assume (for optimization) that |
724 | // the predecessors are already formatted |
725 | Point GetRelPos() const; |
726 | |
727 | // PaintArea is the area where content might be displayed. |
728 | // The margin of a page or the space between columns belongs to it. |
729 | SwRect GetPaintArea() const; |
730 | |
731 | // UnionFrame is the union of Frame- and PrtArea, normally identical |
732 | // to the FrameArea except in case of negative Prt margins. |
733 | SwRect UnionFrame( bool bBorder = false ) const; |
734 | |
735 | virtual Size ChgSize( const Size& aNewSize ); |
736 | |
737 | virtual void Cut() = 0; |
738 | virtual void Paste( SwFrame* pParent, SwFrame* pSibling = nullptr ) = 0; |
739 | |
740 | void ValidateLineNum() { mbValidLineNum = true; } |
741 | |
742 | bool GetValidLineNumFlag()const { return mbValidLineNum; } |
743 | |
744 | // Only invalidate Frame |
745 | // #i28701# - add call to method <ActionOnInvalidation(..)> |
746 | // for all invalidation methods. |
747 | // #i28701# - use method <InvalidationAllowed(..)> to |
748 | // decide, if invalidation will to be performed or not. |
749 | // #i26945# - no additional invalidation, if it's already |
750 | // invalidate. |
751 | void InvalidateSize_() |
752 | { |
753 | if ( isFrameAreaSizeValid() && InvalidationAllowed( INVALID_SIZE ) ) |
754 | { |
755 | setFrameAreaSizeValid(false); |
756 | ActionOnInvalidation( INVALID_SIZE ); |
757 | } |
758 | } |
759 | void InvalidatePrt_() |
760 | { |
761 | if ( isFramePrintAreaValid() && InvalidationAllowed( INVALID_PRTAREA ) ) |
762 | { |
763 | setFramePrintAreaValid(false); |
764 | ActionOnInvalidation( INVALID_PRTAREA ); |
765 | } |
766 | } |
767 | void InvalidatePos_() |
768 | { |
769 | if ( isFrameAreaPositionValid() && InvalidationAllowed( INVALID_POS ) ) |
770 | { |
771 | setFrameAreaPositionValid(false); |
772 | ActionOnInvalidation( INVALID_POS ); |
773 | } |
774 | } |
775 | void InvalidateLineNum_() |
776 | { |
777 | if ( mbValidLineNum && InvalidationAllowed( INVALID_LINENUM ) ) |
778 | { |
779 | mbValidLineNum = false; |
780 | ActionOnInvalidation( INVALID_LINENUM ); |
781 | } |
782 | } |
783 | void InvalidateAll_() |
784 | { |
785 | if ( ( isFrameAreaSizeValid() || isFramePrintAreaValid() || isFrameAreaPositionValid() ) && InvalidationAllowed( INVALID_ALL ) ) |
786 | { |
787 | setFrameAreaSizeValid(false); |
788 | setFrameAreaPositionValid(false); |
789 | setFramePrintAreaValid(false); |
790 | ActionOnInvalidation( INVALID_ALL ); |
791 | } |
792 | } |
793 | // also notify page at the same time |
794 | inline void InvalidateSize(); |
795 | inline void InvalidatePrt(); |
796 | inline void InvalidatePos(); |
797 | inline void InvalidateLineNum(); |
798 | inline void InvalidateAll(); |
799 | void ImplInvalidateSize(); |
800 | void ImplInvalidatePrt(); |
801 | void ImplInvalidatePos(); |
802 | void ImplInvalidateLineNum(); |
803 | |
804 | inline void InvalidateNextPos( bool bNoFootnote = false ); |
805 | void ImplInvalidateNextPos( bool bNoFootnote ); |
806 | |
807 | /** method to invalidate printing area of next frame |
808 | #i11859# |
809 | */ |
810 | void InvalidateNextPrtArea(); |
811 | |
812 | void InvalidatePage( const SwPageFrame *pPage = nullptr ) const; |
813 | |
814 | virtual bool FillSelection( SwSelectionList& rList, const SwRect& rRect ) const; |
815 | |
816 | virtual bool GetModelPositionForViewPoint( SwPosition *, Point&, |
817 | SwCursorMoveState* = nullptr, bool bTestBackground = false ) const; |
818 | virtual bool GetCharRect( SwRect &, const SwPosition&, |
819 | SwCursorMoveState* = nullptr, bool bAllowFarAway = true ) const; |
820 | virtual void PaintSwFrame( vcl::RenderContext& rRenderContext, SwRect const&, |
821 | SwPrintData const*const pPrintData = nullptr ) const; |
822 | |
823 | // HACK: shortcut between frame and formatting |
824 | // It's your own fault if you cast void* incorrectly! In any case check |
825 | // the void* for 0. |
826 | virtual bool Prepare( const PrepareHint ePrep = PrepareHint::Clear, |
827 | const void *pVoid = nullptr, bool bNotify = true ); |
828 | |
829 | // true if it is the correct class, false otherwise |
830 | inline bool IsLayoutFrame() const; |
831 | inline bool IsRootFrame() const; |
832 | inline bool IsPageFrame() const; |
833 | inline bool IsColumnFrame() const; |
834 | inline bool IsFootnoteBossFrame() const; // footnote bosses might be PageFrames or ColumnFrames |
835 | inline bool IsHeaderFrame() const; |
836 | inline bool IsFooterFrame() const; |
837 | inline bool IsFootnoteContFrame() const; |
838 | inline bool IsFootnoteFrame() const; |
839 | inline bool IsBodyFrame() const; |
840 | inline bool IsColBodyFrame() const; // implemented in layfrm.hxx, BodyFrame above ColumnFrame |
841 | inline bool IsPageBodyFrame() const; // implemented in layfrm.hxx, BodyFrame above PageFrame |
842 | inline bool IsFlyFrame() const; |
843 | inline bool IsSctFrame() const; |
844 | inline bool IsTabFrame() const; |
845 | inline bool IsRowFrame() const; |
846 | inline bool IsCellFrame() const; |
847 | inline bool IsContentFrame() const; |
848 | inline bool IsTextFrame() const; |
849 | inline bool IsNoTextFrame() const; |
850 | // Frames where its PrtArea depends on their neighbors and that are |
851 | // positioned in the content flow |
852 | inline bool IsFlowFrame() const; |
853 | // Frames that are capable of retouching or that might need to retouch behind |
854 | // themselves |
855 | inline bool IsRetoucheFrame() const; |
856 | inline bool IsAccessibleFrame() const; |
857 | |
858 | void PrepareCursor(); // CursorShell is allowed to call this |
859 | |
860 | // Is the Frame (or the section containing it) protected? Same for Fly in |
861 | // Fly in ... and footnotes |
862 | bool IsProtected() const; |
863 | |
864 | bool IsColLocked() const { return mbColLocked; } |
865 | virtual bool IsDeleteForbidden() const { return mbForbidDelete; } |
866 | |
867 | /// this is the only way to delete a SwFrame instance |
868 | static void DestroyFrame(SwFrame *const pFrame); |
869 | |
870 | bool IsInDtor() const { return mbInDtor; } |
871 | |
872 | // No inline cause we need the function pointers |
873 | long GetTopMargin() const; |
874 | long GetBottomMargin() const; |
875 | long GetLeftMargin() const; |
876 | long GetRightMargin() const; |
877 | void SetTopBottomMargins( long, long ); |
878 | void SetLeftRightMargins( long, long ); |
879 | void SetRightLeftMargins( long, long ); |
880 | long GetPrtLeft() const; |
881 | long GetPrtBottom() const; |
882 | long GetPrtRight() const; |
883 | long GetPrtTop() const; |
884 | bool SetMinLeft( long ); |
885 | bool SetMaxBottom( long ); |
886 | bool SetMaxRight( long ); |
887 | void MakeBelowPos( const SwFrame*, const SwFrame*, bool ); |
888 | void MakeLeftPos( const SwFrame*, const SwFrame*, bool ); |
889 | void MakeRightPos( const SwFrame*, const SwFrame*, bool ); |
890 | bool IsNeighbourFrame() const |
891 | { return bool(GetType() & FRM_NEIGHBOUR(SwFrameType::Column | SwFrameType::Cell)); } |
892 | |
893 | // NEW TABLES |
894 | // Some functions for covered/covering table cells. This way unnecessary |
895 | // includes can be avoided |
896 | virtual bool IsLeaveUpperAllowed() const; |
897 | virtual bool IsCoveredCell() const; |
898 | bool IsInCoveredCell() const; |
899 | |
900 | // #i81146# new loop control |
901 | bool KnowsFormat( const SwFormat& rFormat ) const; |
902 | void RegisterToFormat( SwFormat& rFormat ); |
903 | void ValidateThisAndAllLowers( const sal_uInt16 nStage ); |
904 | |
905 | void ForbidDelete() { mbForbidDelete = true; } |
906 | void AllowDelete() { mbForbidDelete = false; } |
907 | |
908 | drawinglayer::attribute::SdrAllFillAttributesHelperPtr getSdrAllFillAttributesHelper() const; |
909 | bool supportsFullDrawingLayerFillAttributeSet() const; |
910 | |
911 | public: |
912 | // if writer is NULL, dumps the layout structure as XML in layout.xml |
913 | virtual void dumpAsXml(xmlTextWriterPtr writer = nullptr) const; |
914 | void dumpTopMostAsXml(xmlTextWriterPtr writer = nullptr) const; |
915 | void dumpInfosAsXml(xmlTextWriterPtr writer) const; |
916 | virtual void dumpAsXmlAttributes(xmlTextWriterPtr writer) const; |
917 | void dumpChildrenAsXml(xmlTextWriterPtr writer) const; |
918 | bool IsCollapse() const; |
919 | }; |
920 | |
921 | inline bool SwFrame::IsInDocBody() const |
922 | { |
923 | if ( mbInfInvalid ) |
924 | const_cast<SwFrame*>(this)->SetInfFlags(); |
925 | return mbInfBody; |
926 | } |
927 | inline bool SwFrame::IsInFootnote() const |
928 | { |
929 | if ( mbInfInvalid ) |
930 | const_cast<SwFrame*>(this)->SetInfFlags(); |
931 | return mbInfFootnote; |
932 | } |
933 | inline bool SwFrame::IsInTab() const |
934 | { |
935 | if ( mbInfInvalid ) |
936 | const_cast<SwFrame*>(this)->SetInfFlags(); |
937 | return mbInfTab; |
938 | } |
939 | inline bool SwFrame::IsInFly() const |
940 | { |
941 | if ( mbInfInvalid ) |
942 | const_cast<SwFrame*>(this)->SetInfFlags(); |
943 | return mbInfFly; |
944 | } |
945 | inline bool SwFrame::IsInSct() const |
946 | { |
947 | if ( mbInfInvalid ) |
948 | const_cast<SwFrame*>(this)->SetInfFlags(); |
949 | return mbInfSct; |
950 | } |
951 | bool SwFrame::IsVertical() const |
952 | { |
953 | if( mbInvalidVert ) |
954 | const_cast<SwFrame*>(this)->SetDirFlags( true ); |
955 | return mbVertical; |
956 | } |
957 | inline bool SwFrame::IsVertLR() const |
958 | { |
959 | return mbVertLR; |
960 | } |
961 | inline bool SwFrame::IsVertLRBT() const |
962 | { |
963 | return mbVertLRBT; |
964 | } |
965 | inline bool SwFrame::IsRightToLeft() const |
966 | { |
967 | if( mbInvalidR2L ) |
968 | const_cast<SwFrame*>(this)->SetDirFlags( false ); |
969 | return mbRightToLeft; |
970 | } |
971 | |
972 | inline void SwFrame::SetCompletePaint() const |
973 | { |
974 | const_cast<SwFrame*>(this)->mbCompletePaint = true; |
975 | } |
976 | inline void SwFrame::ResetCompletePaint() const |
977 | { |
978 | const_cast<SwFrame*>(this)->mbCompletePaint = false; |
979 | } |
980 | |
981 | inline void SwFrame::SetRetouche() const |
982 | { |
983 | const_cast<SwFrame*>(this)->mbRetouche = true; |
984 | } |
985 | inline void SwFrame::ResetRetouche() const |
986 | { |
987 | const_cast<SwFrame*>(this)->mbRetouche = false; |
988 | } |
989 | |
990 | inline SwLayoutFrame *SwFrame::GetNextLayoutLeaf() |
991 | { |
992 | return const_cast<SwLayoutFrame*>(static_cast<const SwFrame*>(this)->GetNextLayoutLeaf()); |
993 | } |
994 | inline SwLayoutFrame *SwFrame::GetPrevLayoutLeaf() |
995 | { |
996 | return const_cast<SwLayoutFrame*>(static_cast<const SwFrame*>(this)->GetPrevLayoutLeaf()); |
997 | } |
998 | inline const SwLayoutFrame *SwFrame::GetNextLayoutLeaf() const |
999 | { |
1000 | return ImplGetNextLayoutLeaf( true ); |
1001 | } |
1002 | inline const SwLayoutFrame *SwFrame::GetPrevLayoutLeaf() const |
1003 | { |
1004 | return ImplGetNextLayoutLeaf( false ); |
1005 | } |
1006 | |
1007 | inline void SwFrame::InvalidateSize() |
1008 | { |
1009 | if ( isFrameAreaSizeValid() ) |
1010 | { |
1011 | ImplInvalidateSize(); |
1012 | } |
1013 | } |
1014 | inline void SwFrame::InvalidatePrt() |
1015 | { |
1016 | if ( isFramePrintAreaValid() ) |
1017 | { |
1018 | ImplInvalidatePrt(); |
1019 | } |
1020 | } |
1021 | inline void SwFrame::InvalidatePos() |
1022 | { |
1023 | if ( isFrameAreaPositionValid() ) |
1024 | { |
1025 | ImplInvalidatePos(); |
1026 | } |
1027 | } |
1028 | inline void SwFrame::InvalidateLineNum() |
1029 | { |
1030 | if ( mbValidLineNum ) |
1031 | ImplInvalidateLineNum(); |
1032 | } |
1033 | inline void SwFrame::InvalidateAll() |
1034 | { |
1035 | if ( InvalidationAllowed( INVALID_ALL ) ) |
1036 | { |
1037 | if ( isFrameAreaDefinitionValid() ) |
1038 | { |
1039 | ImplInvalidatePos(); |
1040 | } |
1041 | |
1042 | setFrameAreaSizeValid(false); |
1043 | setFrameAreaPositionValid(false); |
1044 | setFramePrintAreaValid(false); |
1045 | |
1046 | // #i28701# |
1047 | ActionOnInvalidation( INVALID_ALL ); |
1048 | } |
1049 | } |
1050 | inline void SwFrame::InvalidateNextPos( bool bNoFootnote ) |
1051 | { |
1052 | if ( mpNext && !mpNext->IsSctFrame() ) |
1053 | mpNext->InvalidatePos(); |
1054 | else |
1055 | ImplInvalidateNextPos( bNoFootnote ); |
1056 | } |
1057 | |
1058 | inline void SwFrame::OptCalc() const |
1059 | { |
1060 | if ( !isFrameAreaPositionValid() || !isFramePrintAreaValid() || !isFrameAreaSizeValid() ) |
1061 | { |
1062 | const_cast<SwFrame*>(this)->OptPrepareMake(); |
1063 | } |
1064 | } |
1065 | inline const SwPageFrame *SwFrame::FindPageFrame() const |
1066 | { |
1067 | return const_cast<SwFrame*>(this)->FindPageFrame(); |
1068 | } |
1069 | inline const SwFrame *SwFrame::FindColFrame() const |
1070 | { |
1071 | return const_cast<SwFrame*>(this)->FindColFrame(); |
1072 | } |
1073 | inline const SwFrame *SwFrame::FindFooterOrHeader() const |
1074 | { |
1075 | return const_cast<SwFrame*>(this)->FindFooterOrHeader(); |
1076 | } |
1077 | inline SwTabFrame *SwFrame::FindTabFrame() |
1078 | { |
1079 | return IsInTab() ? ImplFindTabFrame() : nullptr; |
1080 | } |
1081 | inline const SwFootnoteBossFrame *SwFrame::FindFootnoteBossFrame( bool bFootnote ) const |
1082 | { |
1083 | return const_cast<SwFrame*>(this)->FindFootnoteBossFrame( bFootnote ); |
1084 | } |
1085 | inline SwFootnoteFrame *SwFrame::FindFootnoteFrame() |
1086 | { |
1087 | return IsInFootnote() ? ImplFindFootnoteFrame() : nullptr; |
1088 | } |
1089 | inline SwFlyFrame *SwFrame::FindFlyFrame() |
1090 | { |
1091 | return IsInFly() ? ImplFindFlyFrame() : nullptr; |
1092 | } |
1093 | inline SwSectionFrame *SwFrame::FindSctFrame() |
1094 | { |
1095 | return IsInSct() ? ImplFindSctFrame() : nullptr; |
1096 | } |
1097 | |
1098 | inline const SwBodyFrame *SwFrame::FindBodyFrame() const |
1099 | { |
1100 | return IsInDocBody() ? ImplFindBodyFrame() : nullptr; |
1101 | } |
1102 | |
1103 | inline const SwTabFrame *SwFrame::FindTabFrame() const |
1104 | { |
1105 | return IsInTab() ? const_cast<SwFrame*>(this)->ImplFindTabFrame() : nullptr; |
1106 | } |
1107 | inline const SwFootnoteFrame *SwFrame::FindFootnoteFrame() const |
1108 | { |
1109 | return IsInFootnote() ? const_cast<SwFrame*>(this)->ImplFindFootnoteFrame() : nullptr; |
1110 | } |
1111 | inline const SwFlyFrame *SwFrame::FindFlyFrame() const |
1112 | { |
1113 | return IsInFly() ? const_cast<SwFrame*>(this)->ImplFindFlyFrame() : nullptr; |
1114 | } |
1115 | inline const SwSectionFrame *SwFrame::FindSctFrame() const |
1116 | { |
1117 | return IsInSct() ? const_cast<SwFrame*>(this)->ImplFindSctFrame() : nullptr; |
1118 | } |
1119 | inline SwFrame *SwFrame::FindNext() |
1120 | { |
1121 | if ( mpNext ) |
1122 | return mpNext; |
1123 | else |
1124 | return FindNext_(); |
1125 | } |
1126 | inline const SwFrame *SwFrame::FindNext() const |
1127 | { |
1128 | if ( mpNext ) |
1129 | return mpNext; |
1130 | else |
1131 | return const_cast<SwFrame*>(this)->FindNext_(); |
1132 | } |
1133 | inline SwFrame *SwFrame::FindPrev() |
1134 | { |
1135 | if ( mpPrev && !mpPrev->IsSctFrame() ) |
1136 | return mpPrev; |
1137 | else |
1138 | return FindPrev_(); |
1139 | } |
1140 | inline const SwFrame *SwFrame::FindPrev() const |
1141 | { |
1142 | if ( mpPrev && !mpPrev->IsSctFrame() ) |
1143 | return mpPrev; |
1144 | else |
1145 | return const_cast<SwFrame*>(this)->FindPrev_(); |
1146 | } |
1147 | |
1148 | inline bool SwFrame::IsLayoutFrame() const |
1149 | { |
1150 | return bool(GetType() & FRM_LAYOUTSwFrameType(0x3bFF)); |
1151 | } |
1152 | inline bool SwFrame::IsRootFrame() const |
1153 | { |
1154 | return mnFrameType == SwFrameType::Root; |
1155 | } |
1156 | inline bool SwFrame::IsPageFrame() const |
1157 | { |
1158 | return mnFrameType == SwFrameType::Page; |
1159 | } |
1160 | inline bool SwFrame::IsColumnFrame() const |
1161 | { |
1162 | return mnFrameType == SwFrameType::Column; |
1163 | } |
1164 | inline bool SwFrame::IsFootnoteBossFrame() const |
1165 | { |
1166 | return bool(GetType() & FRM_FTNBOSS(SwFrameType::Page | SwFrameType::Column)); |
1167 | } |
1168 | inline bool SwFrame::IsHeaderFrame() const |
1169 | { |
1170 | return mnFrameType == SwFrameType::Header; |
1171 | } |
1172 | inline bool SwFrame::IsFooterFrame() const |
1173 | { |
1174 | return mnFrameType == SwFrameType::Footer; |
1175 | } |
1176 | inline bool SwFrame::IsFootnoteContFrame() const |
1177 | { |
1178 | return mnFrameType == SwFrameType::FtnCont; |
1179 | } |
1180 | inline bool SwFrame::IsFootnoteFrame() const |
1181 | { |
1182 | return mnFrameType == SwFrameType::Ftn; |
1183 | } |
1184 | inline bool SwFrame::IsBodyFrame() const |
1185 | { |
1186 | return mnFrameType == SwFrameType::Body; |
1187 | } |
1188 | inline bool SwFrame::IsFlyFrame() const |
1189 | { |
1190 | return mnFrameType == SwFrameType::Fly; |
1191 | } |
1192 | inline bool SwFrame::IsSctFrame() const |
1193 | { |
1194 | return mnFrameType == SwFrameType::Section; |
1195 | } |
1196 | inline bool SwFrame::IsTabFrame() const |
1197 | { |
1198 | return mnFrameType == SwFrameType::Tab; |
1199 | } |
1200 | inline bool SwFrame::IsRowFrame() const |
1201 | { |
1202 | return mnFrameType == SwFrameType::Row; |
1203 | } |
1204 | inline bool SwFrame::IsCellFrame() const |
1205 | { |
1206 | return mnFrameType == SwFrameType::Cell; |
1207 | } |
1208 | inline bool SwFrame::IsContentFrame() const |
1209 | { |
1210 | return bool(GetType() & FRM_CNTNT(SwFrameType::Txt | SwFrameType::NoTxt)); |
1211 | } |
1212 | inline bool SwFrame::IsTextFrame() const |
1213 | { |
1214 | return mnFrameType == SwFrameType::Txt; |
1215 | } |
1216 | inline bool SwFrame::IsNoTextFrame() const |
1217 | { |
1218 | return mnFrameType == SwFrameType::NoTxt; |
1219 | } |
1220 | inline bool SwFrame::IsFlowFrame() const |
1221 | { |
1222 | return bool(GetType() & (FRM_CNTNT(SwFrameType::Txt | SwFrameType::NoTxt)|SwFrameType::Tab|SwFrameType::Section)); |
1223 | } |
1224 | inline bool SwFrame::IsRetoucheFrame() const |
1225 | { |
1226 | return bool(GetType() & (FRM_CNTNT(SwFrameType::Txt | SwFrameType::NoTxt)|SwFrameType::Tab|SwFrameType::Section|SwFrameType::Ftn)); |
1227 | } |
1228 | inline bool SwFrame::IsAccessibleFrame() const |
1229 | { |
1230 | return bool(GetType() & FRM_ACCESSIBLE(SwFrameType::Root | SwFrameType::Page | SwFrameType::Header | SwFrameType::Footer | SwFrameType::Ftn | SwFrameType::Fly | SwFrameType ::Tab | SwFrameType::Cell | SwFrameType::Txt)); |
1231 | } |
1232 | |
1233 | //use this to protect a SwFrame for a given scope from getting deleted |
1234 | class SwFrameDeleteGuard |
1235 | { |
1236 | private: |
1237 | SwFrame *m_pForbidFrame; |
1238 | public: |
1239 | //Flag pFrame for SwFrameDeleteGuard lifetime that we shouldn't delete |
1240 | //it in e.g. SwSectionFrame::MergeNext etc because we will need it |
1241 | //again after the SwFrameDeleteGuard dtor |
1242 | explicit SwFrameDeleteGuard(SwFrame* pFrame) |
1243 | : m_pForbidFrame((pFrame && !pFrame->IsDeleteForbidden()) ? |
1244 | pFrame : nullptr) |
1245 | { |
1246 | if (m_pForbidFrame) |
1247 | m_pForbidFrame->ForbidDelete(); |
1248 | } |
1249 | |
1250 | SwFrameDeleteGuard(const SwFrameDeleteGuard&) =delete; |
1251 | |
1252 | ~SwFrameDeleteGuard() |
1253 | { |
1254 | if (m_pForbidFrame) |
1255 | m_pForbidFrame->AllowDelete(); |
1256 | } |
1257 | |
1258 | SwFrameDeleteGuard& operator=(const SwFrameDeleteGuard&) =delete; |
1259 | }; |
1260 | |
1261 | typedef long (SwFrame::*SwFrameGet)() const; |
1262 | typedef bool (SwFrame::*SwFrameMax)( long ); |
1263 | typedef void (SwFrame::*SwFrameMakePos)( const SwFrame*, const SwFrame*, bool ); |
1264 | typedef long (*SwOperator)( long, long ); |
1265 | typedef void (SwFrame::*SwFrameSet)( long, long ); |
1266 | |
1267 | struct SwRectFnCollection |
1268 | { |
1269 | SwRectGet fnGetTop; |
1270 | SwRectGet fnGetBottom; |
1271 | SwRectGet fnGetLeft; |
1272 | SwRectGet fnGetRight; |
1273 | SwRectGet fnGetWidth; |
1274 | SwRectGet fnGetHeight; |
1275 | SwRectPoint fnGetPos; |
1276 | SwRectSize fnGetSize; |
1277 | |
1278 | SwRectSet fnSetTop; |
1279 | SwRectSet fnSetBottom; |
1280 | SwRectSet fnSetLeft; |
1281 | SwRectSet fnSetRight; |
1282 | SwRectSet fnSetWidth; |
1283 | SwRectSet fnSetHeight; |
1284 | |
1285 | SwRectSet fnSubTop; |
1286 | SwRectSet fnAddBottom; |
1287 | SwRectSet fnSubLeft; |
1288 | SwRectSet fnAddRight; |
1289 | SwRectSet fnAddWidth; |
1290 | SwRectSet fnAddHeight; |
1291 | |
1292 | SwRectSet fnSetPosX; |
1293 | SwRectSet fnSetPosY; |
1294 | |
1295 | SwFrameGet fnGetTopMargin; |
1296 | SwFrameGet fnGetBottomMargin; |
1297 | SwFrameGet fnGetLeftMargin; |
1298 | SwFrameGet fnGetRightMargin; |
1299 | SwFrameSet fnSetXMargins; |
1300 | SwFrameSet fnSetYMargins; |
1301 | SwFrameGet fnGetPrtTop; |
1302 | SwFrameGet fnGetPrtBottom; |
1303 | SwFrameGet fnGetPrtLeft; |
1304 | SwFrameGet fnGetPrtRight; |
1305 | SwRectDist fnTopDist; |
1306 | SwRectDist fnBottomDist; |
1307 | SwRectDist fnLeftDist; |
1308 | SwRectDist fnRightDist; |
1309 | SwFrameMax fnSetLimit; |
1310 | SwRectMax fnOverStep; |
1311 | |
1312 | SwRectSetPos fnSetPos; |
1313 | SwFrameMakePos fnMakePos; |
1314 | SwOperator fnXDiff; |
1315 | SwOperator fnYDiff; |
1316 | SwOperator fnXInc; |
1317 | SwOperator fnYInc; |
1318 | |
1319 | SwRectSetTwice fnSetLeftAndWidth; |
1320 | SwRectSetTwice fnSetTopAndHeight; |
1321 | }; |
1322 | |
1323 | typedef SwRectFnCollection* SwRectFn; |
1324 | |
1325 | // This class allows to use proper methods regardless of orientation (LTR/RTL, horizontal or vertical) |
1326 | extern SwRectFn fnRectHori, fnRectVert, fnRectVertL2R, fnRectVertL2RB2T; |
1327 | class SwRectFnSet { |
1328 | public: |
1329 | explicit SwRectFnSet(const SwFrame *pFrame) |
1330 | : m_bVert(pFrame->IsVertical()) |
1331 | , m_bVertL2R(pFrame->IsVertLR()) |
1332 | , m_bVertL2RB2T(pFrame->IsVertLRBT()) |
1333 | { |
1334 | m_fnRect = m_bVert ? (m_bVertL2R ? (m_bVertL2RB2T ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert) : fnRectHori; |
1335 | } |
1336 | |
1337 | void Refresh(const SwFrame *pFrame) |
1338 | { |
1339 | m_bVert = pFrame->IsVertical(); |
1340 | m_bVertL2R = pFrame->IsVertLR(); |
1341 | m_bVertL2RB2T = pFrame->IsVertLRBT(); |
1342 | m_fnRect = m_bVert ? (m_bVertL2R ? (m_bVertL2RB2T ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert) : fnRectHori; |
1343 | } |
1344 | |
1345 | bool IsVert() const { return m_bVert; } |
1346 | bool IsVertL2R() const { return m_bVertL2R; } |
1347 | SwRectFn FnRect() const { return m_fnRect; } |
1348 | |
1349 | bool PosDiff(const SwRect &rRect1, const SwRect &rRect2) const |
1350 | { |
1351 | return ((rRect1.*m_fnRect->fnGetTop)() != (rRect2.*m_fnRect->fnGetTop)() |
1352 | || (rRect1.*m_fnRect->fnGetLeft)() != (rRect2.*m_fnRect->fnGetLeft)()); |
1353 | } |
1354 | |
1355 | long GetTop (const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetTop) (); } |
1356 | long GetBottom(const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetBottom)(); } |
1357 | long GetLeft (const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetLeft) (); } |
1358 | long GetRight (const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetRight) (); } |
1359 | long GetWidth (const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetWidth) (); } |
1360 | long GetHeight(const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetHeight)(); } |
1361 | Point GetPos (const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetPos) (); } |
1362 | Size GetSize (const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetSize) (); } |
1363 | |
1364 | void SetTop (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetTop) (nNew); } |
1365 | void SetBottom(SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetBottom)(nNew); } |
1366 | void SetLeft (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetLeft) (nNew); } |
1367 | void SetRight (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetRight) (nNew); } |
1368 | void SetWidth (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetWidth) (nNew); } |
1369 | void SetHeight(SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetHeight)(nNew); } |
1370 | |
1371 | void SubTop (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSubTop) (nNew); } |
1372 | void AddBottom(SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnAddBottom)(nNew); } |
1373 | void SubLeft (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSubLeft) (nNew); } |
1374 | void AddRight (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnAddRight) (nNew); } |
1375 | void AddWidth (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnAddWidth) (nNew); } |
1376 | void AddHeight(SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnAddHeight)(nNew); } |
1377 | |
1378 | void SetPosX(SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetPosX)(nNew); } |
1379 | void SetPosY(SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetPosY)(nNew); } |
1380 | |
1381 | long GetTopMargin (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetTopMargin) (); } |
1382 | long GetBottomMargin(const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetBottomMargin)(); } |
1383 | long GetLeftMargin (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetLeftMargin) (); } |
1384 | long GetRightMargin (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetRightMargin) (); } |
1385 | void SetXMargins(SwFrame& rFrame, long nLeft, long nRight) const { (rFrame.*m_fnRect->fnSetXMargins)(nLeft, nRight); } |
1386 | void SetYMargins(SwFrame& rFrame, long nTop, long nBottom) const { (rFrame.*m_fnRect->fnSetYMargins)(nTop, nBottom); } |
1387 | long GetPrtTop (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetPrtTop) (); } |
1388 | long GetPrtBottom (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetPrtBottom) (); } |
1389 | long GetPrtLeft (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetPrtLeft) (); } |
1390 | long GetPrtRight (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetPrtRight) (); } |
1391 | long TopDist (const SwRect& rRect, long nPos) const { return (rRect.*m_fnRect->fnTopDist) (nPos); } |
1392 | long BottomDist(const SwRect& rRect, long nPos) const { return (rRect.*m_fnRect->fnBottomDist) (nPos); } |
1393 | long LeftDist (const SwRect& rRect, long nPos) const { return (rRect.*m_fnRect->fnLeftDist) (nPos); } |
1394 | long RightDist (const SwRect& rRect, long nPos) const { return (rRect.*m_fnRect->fnRightDist) (nPos); } |
1395 | void SetLimit (SwFrame& rFrame, long nNew) const { (rFrame.*m_fnRect->fnSetLimit) (nNew); } |
1396 | bool OverStep (const SwRect& rRect, long nPos) const { return (rRect.*m_fnRect->fnOverStep) (nPos); } |
1397 | |
1398 | void SetPos(SwRect& rRect, const Point& rNew) const { (rRect.*m_fnRect->fnSetPos)(rNew); } |
1399 | void MakePos(SwFrame& rFrame, const SwFrame* pUp, const SwFrame* pPrv, bool bNotify) const { (rFrame.*m_fnRect->fnMakePos)(pUp, pPrv, bNotify); } |
1400 | long XDiff(long n1, long n2) const { return (m_fnRect->fnXDiff) (n1, n2); } |
1401 | long YDiff(long n1, long n2) const { return (m_fnRect->fnYDiff) (n1, n2); } |
1402 | long XInc (long n1, long n2) const { return (m_fnRect->fnXInc) (n1, n2); } |
1403 | long YInc (long n1, long n2) const { return (m_fnRect->fnYInc) (n1, n2); } |
1404 | |
1405 | void SetLeftAndWidth(SwRect& rRect, long nLeft, long nWidth) const { (rRect.*m_fnRect->fnSetLeftAndWidth)(nLeft, nWidth); } |
1406 | void SetTopAndHeight(SwRect& rRect, long nTop, long nHeight) const { (rRect.*m_fnRect->fnSetTopAndHeight)(nTop, nHeight); } |
1407 | |
1408 | private: |
1409 | bool m_bVert; |
1410 | bool m_bVertL2R; |
1411 | bool m_bVertL2RB2T; |
1412 | SwRectFn m_fnRect; |
1413 | }; |
1414 | |
1415 | #endif |
1416 | |
1417 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |