File: | home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx |
Warning: | line 3373, column 50 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 <svx/svdpage.hxx> | ||||
21 | #include <editeng/brushitem.hxx> | ||||
22 | #include <editeng/shaditem.hxx> | ||||
23 | #include <editeng/ulspitem.hxx> | ||||
24 | #include <editeng/boxitem.hxx> | ||||
25 | #include <editeng/lspcitem.hxx> | ||||
26 | #include <editeng/fhgtitem.hxx> | ||||
27 | #include <sal/log.hxx> | ||||
28 | |||||
29 | #include <drawdoc.hxx> | ||||
30 | #include <fmtornt.hxx> | ||||
31 | #include <fmthdft.hxx> | ||||
32 | #include <fmtfsize.hxx> | ||||
33 | #include <fmtsrnd.hxx> | ||||
34 | #include <docary.hxx> | ||||
35 | #include <lineinfo.hxx> | ||||
36 | #include <swmodule.hxx> | ||||
37 | #include <pagefrm.hxx> | ||||
38 | #include <colfrm.hxx> | ||||
39 | #include <fesh.hxx> | ||||
40 | #include <viewimp.hxx> | ||||
41 | #include <viewopt.hxx> | ||||
42 | #include <dflyobj.hxx> | ||||
43 | #include <dcontact.hxx> | ||||
44 | #include <frmatr.hxx> | ||||
45 | #include <frmtool.hxx> | ||||
46 | #include <tabfrm.hxx> | ||||
47 | #include <rowfrm.hxx> | ||||
48 | #include <ftnfrm.hxx> | ||||
49 | #include <txtfrm.hxx> | ||||
50 | #include <notxtfrm.hxx> | ||||
51 | #include <flyfrms.hxx> | ||||
52 | #include <layact.hxx> | ||||
53 | #include <pagedesc.hxx> | ||||
54 | #include <section.hxx> | ||||
55 | #include <sectfrm.hxx> | ||||
56 | #include <node2lay.hxx> | ||||
57 | #include <ndole.hxx> | ||||
58 | #include <hints.hxx> | ||||
59 | #include "layhelp.hxx" | ||||
60 | #include <laycache.hxx> | ||||
61 | #include <rootfrm.hxx> | ||||
62 | #include <paratr.hxx> | ||||
63 | #include <redline.hxx> | ||||
64 | #include <sortedobjs.hxx> | ||||
65 | #include <objectformatter.hxx> | ||||
66 | #include <calbck.hxx> | ||||
67 | #include <ndtxt.hxx> | ||||
68 | #include <undobj.hxx> | ||||
69 | #include <DocumentSettingManager.hxx> | ||||
70 | #include <IDocumentDrawModelAccess.hxx> | ||||
71 | #include <IDocumentTimerAccess.hxx> | ||||
72 | #include <IDocumentRedlineAccess.hxx> | ||||
73 | #include <IDocumentFieldsAccess.hxx> | ||||
74 | #include <IDocumentState.hxx> | ||||
75 | #include <frameformats.hxx> | ||||
76 | #include <boost/circular_buffer.hpp> | ||||
77 | #include <svx/sdr/attribute/sdrallfillattributeshelper.hxx> | ||||
78 | |||||
79 | using namespace ::com::sun::star; | ||||
80 | |||||
81 | bool bObjsDirect = true; | ||||
82 | bool bDontCreateObjects = false; | ||||
83 | bool bSetCompletePaintOnInvalidate = false; | ||||
84 | |||||
85 | sal_uInt8 StackHack::nCnt = 0; | ||||
86 | bool StackHack::bLocked = false; | ||||
87 | |||||
88 | SwFrameNotify::SwFrameNotify( SwFrame *pF ) : | ||||
89 | mpFrame( pF ), | ||||
90 | maFrame( pF->getFrameArea() ), | ||||
91 | maPrt( pF->getFramePrintArea() ), | ||||
92 | mbInvaKeep( false ), | ||||
93 | mbValidSize( pF->isFrameAreaSizeValid() ) | ||||
94 | { | ||||
95 | if ( pF->IsTextFrame() ) | ||||
96 | { | ||||
97 | mnFlyAnchorOfst = static_cast<SwTextFrame*>(pF)->GetBaseOffsetForFly( true ); | ||||
98 | mnFlyAnchorOfstNoWrap = static_cast<SwTextFrame*>(pF)->GetBaseOffsetForFly( false ); | ||||
99 | } | ||||
100 | else | ||||
101 | { | ||||
102 | mnFlyAnchorOfst = 0; | ||||
103 | mnFlyAnchorOfstNoWrap = 0; | ||||
104 | } | ||||
105 | |||||
106 | mbHadFollow = pF->IsContentFrame() && static_cast<SwContentFrame*>(pF)->GetFollow(); | ||||
107 | } | ||||
108 | |||||
109 | SwFrameNotify::~SwFrameNotify() COVERITY_NOEXCEPT_FALSE | ||||
110 | { | ||||
111 | SwRectFnSet aRectFnSet(mpFrame); | ||||
112 | const bool bAbsP = aRectFnSet.PosDiff(maFrame, mpFrame->getFrameArea()); | ||||
113 | const bool bChgWidth = | ||||
114 | aRectFnSet.GetWidth(maFrame) != aRectFnSet.GetWidth(mpFrame->getFrameArea()); | ||||
115 | const bool bChgHeight = | ||||
116 | aRectFnSet.GetHeight(maFrame)!=aRectFnSet.GetHeight(mpFrame->getFrameArea()); | ||||
117 | const bool bChgFlyBasePos = mpFrame->IsTextFrame() && | ||||
118 | ( ( mnFlyAnchorOfst != static_cast<SwTextFrame*>(mpFrame)->GetBaseOffsetForFly( true ) ) || | ||||
119 | ( mnFlyAnchorOfstNoWrap != static_cast<SwTextFrame*>(mpFrame)->GetBaseOffsetForFly( false ) ) ); | ||||
120 | |||||
121 | if ( mpFrame->IsFlowFrame() && !mpFrame->IsInFootnote() ) | ||||
122 | { | ||||
123 | SwFlowFrame *pFlow = SwFlowFrame::CastFlowFrame( mpFrame ); | ||||
124 | |||||
125 | if ( !pFlow->IsFollow() ) | ||||
126 | { | ||||
127 | if ( !mpFrame->GetIndPrev() ) | ||||
128 | { | ||||
129 | if ( mbInvaKeep ) | ||||
130 | { | ||||
131 | SwFrame *pPre = mpFrame->FindPrev(); | ||||
132 | if ( pPre && pPre->IsFlowFrame() ) | ||||
133 | { | ||||
134 | // 1. pPre wants to keep with me: | ||||
135 | bool bInvalidPrePos = SwFlowFrame::CastFlowFrame(pPre)->IsKeep(pPre->GetAttrSet()->GetKeep(), pPre->GetBreakItem()) | ||||
136 | && pPre->GetIndPrev(); | ||||
137 | |||||
138 | // 2. pPre is a table and the last row wants to keep with me: | ||||
139 | if ( !bInvalidPrePos && pPre->IsTabFrame() ) | ||||
140 | { | ||||
141 | SwTabFrame* pPreTab = static_cast<SwTabFrame*>(pPre); | ||||
142 | if ( pPreTab->GetFormat()->GetDoc()->GetDocumentSettingManager().get(DocumentSettingId::TABLE_ROW_KEEP) ) | ||||
143 | { | ||||
144 | SwRowFrame* pLastRow = static_cast<SwRowFrame*>(pPreTab->GetLastLower()); | ||||
145 | if ( pLastRow && pLastRow->ShouldRowKeepWithNext() ) | ||||
146 | bInvalidPrePos = true; | ||||
147 | } | ||||
148 | } | ||||
149 | |||||
150 | if ( bInvalidPrePos ) | ||||
151 | pPre->InvalidatePos(); | ||||
152 | } | ||||
153 | } | ||||
154 | } | ||||
155 | else if ( !pFlow->HasFollow() ) | ||||
156 | { | ||||
157 | long nOldHeight = aRectFnSet.GetHeight(maFrame); | ||||
158 | long nNewHeight = aRectFnSet.GetHeight(mpFrame->getFrameArea()); | ||||
159 | if( (nOldHeight > nNewHeight) || (!nOldHeight && nNewHeight) ) | ||||
160 | pFlow->CheckKeep(); | ||||
161 | } | ||||
162 | } | ||||
163 | } | ||||
164 | |||||
165 | if ( bAbsP ) | ||||
166 | { | ||||
167 | mpFrame->SetCompletePaint(); | ||||
168 | |||||
169 | SwFrame* pNxt = mpFrame->GetIndNext(); | ||||
170 | // #121888# - skip empty section frames | ||||
171 | while ( pNxt && | ||||
172 | pNxt->IsSctFrame() && !static_cast<SwSectionFrame*>(pNxt)->GetSection() ) | ||||
173 | { | ||||
174 | pNxt = pNxt->GetIndNext(); | ||||
175 | } | ||||
176 | |||||
177 | if ( pNxt ) | ||||
178 | pNxt->InvalidatePos(); | ||||
179 | else | ||||
180 | { | ||||
181 | // #104100# - correct condition for setting retouche | ||||
182 | // flag for vertical layout. | ||||
183 | if( mpFrame->IsRetoucheFrame() && | ||||
184 | aRectFnSet.TopDist( maFrame, aRectFnSet.GetTop(mpFrame->getFrameArea()) ) > 0 ) | ||||
185 | { | ||||
186 | mpFrame->SetRetouche(); | ||||
187 | } | ||||
188 | |||||
189 | // A fresh follow frame does not have to be invalidated, because | ||||
190 | // it is already formatted: | ||||
191 | if ( mbHadFollow || !mpFrame->IsContentFrame() || !static_cast<SwContentFrame*>(mpFrame)->GetFollow() ) | ||||
192 | { | ||||
193 | if ( !mpFrame->IsTabFrame() || !static_cast<SwTabFrame*>(mpFrame)->GetFollow() ) | ||||
194 | mpFrame->InvalidateNextPos(); | ||||
195 | } | ||||
196 | } | ||||
197 | } | ||||
198 | |||||
199 | //For each resize of the background graphics is a repaint necessary. | ||||
200 | const bool bPrtWidth = | ||||
201 | aRectFnSet.GetWidth(maPrt) != aRectFnSet.GetWidth(mpFrame->getFramePrintArea()); | ||||
202 | const bool bPrtHeight = | ||||
203 | aRectFnSet.GetHeight(maPrt)!=aRectFnSet.GetHeight(mpFrame->getFramePrintArea()); | ||||
204 | if ( bPrtWidth || bPrtHeight ) | ||||
205 | { | ||||
206 | bool bUseNewFillProperties(false); | ||||
207 | if (mpFrame->supportsFullDrawingLayerFillAttributeSet()) | ||||
208 | { | ||||
209 | drawinglayer::attribute::SdrAllFillAttributesHelperPtr aFillAttributes(mpFrame->getSdrAllFillAttributesHelper()); | ||||
210 | if(aFillAttributes && aFillAttributes->isUsed()) | ||||
211 | { | ||||
212 | bUseNewFillProperties = true; | ||||
213 | // use SetCompletePaint if needed | ||||
214 | if(aFillAttributes->needCompleteRepaint()) | ||||
215 | { | ||||
216 | mpFrame->SetCompletePaint(); | ||||
217 | } | ||||
218 | } | ||||
219 | } | ||||
220 | if (!bUseNewFillProperties) | ||||
221 | { | ||||
222 | const SvxGraphicPosition ePos = mpFrame->GetAttrSet()->GetBackground().GetGraphicPos(); | ||||
223 | if(GPOS_NONE != ePos && GPOS_TILED != ePos) | ||||
224 | mpFrame->SetCompletePaint(); | ||||
225 | } | ||||
226 | } | ||||
227 | else | ||||
228 | { | ||||
229 | // #97597# - consider case that *only* margins between | ||||
230 | // frame and printing area has changed. Then, frame has to be repainted, | ||||
231 | // in order to force paint of the margin areas. | ||||
232 | if ( !bAbsP && (bChgWidth || bChgHeight) ) | ||||
233 | { | ||||
234 | mpFrame->SetCompletePaint(); | ||||
235 | } | ||||
236 | } | ||||
237 | |||||
238 | const bool bPrtP = aRectFnSet.PosDiff( maPrt, mpFrame->getFramePrintArea() ); | ||||
239 | if ( bAbsP || bPrtP || bChgWidth || bChgHeight || | ||||
240 | bPrtWidth || bPrtHeight || bChgFlyBasePos ) | ||||
241 | { | ||||
242 | if( mpFrame->IsAccessibleFrame() ) | ||||
243 | { | ||||
244 | SwRootFrame *pRootFrame = mpFrame->getRootFrame(); | ||||
245 | if( pRootFrame && pRootFrame->IsAnyShellAccessible() && | ||||
246 | pRootFrame->GetCurrShell() ) | ||||
247 | { | ||||
248 | pRootFrame->GetCurrShell()->Imp()->MoveAccessibleFrame( mpFrame, maFrame ); | ||||
249 | } | ||||
250 | } | ||||
251 | |||||
252 | // Notification of anchored objects | ||||
253 | if ( mpFrame->GetDrawObjs() ) | ||||
254 | { | ||||
255 | const SwSortedObjs &rObjs = *mpFrame->GetDrawObjs(); | ||||
256 | SwPageFrame* pPageFrame = nullptr; | ||||
257 | for (SwAnchoredObject* pObj : rObjs) | ||||
258 | { | ||||
259 | // OD 2004-03-31 #i26791# - no general distinction between | ||||
260 | // Writer fly frames and drawing objects | ||||
261 | bool bNotify = false; | ||||
262 | bool bNotifySize = false; | ||||
263 | SwContact* pContact = ::GetUserCall( pObj->GetDrawObj() ); | ||||
264 | const bool bAnchoredAsChar = pContact->ObjAnchoredAsChar(); | ||||
265 | if ( !bAnchoredAsChar ) | ||||
266 | { | ||||
267 | // Notify object, which aren't anchored as-character: | ||||
268 | |||||
269 | // always notify objects, if frame position has changed | ||||
270 | // or if the object is to-page|to-fly anchored. | ||||
271 | if ( bAbsP || | ||||
272 | pContact->ObjAnchoredAtPage() || | ||||
273 | pContact->ObjAnchoredAtFly() ) | ||||
274 | { | ||||
275 | bNotify = true; | ||||
276 | |||||
277 | // assure that to-fly anchored Writer fly frames are | ||||
278 | // registered at the correct page frame, if frame | ||||
279 | // position has changed. | ||||
280 | if ( bAbsP && pContact->ObjAnchoredAtFly() && | ||||
281 | dynamic_cast<const SwFlyFrame*>( pObj) != nullptr ) | ||||
282 | { | ||||
283 | // determine to-fly anchored Writer fly frame | ||||
284 | SwFlyFrame* pFlyFrame = static_cast<SwFlyFrame*>(pObj); | ||||
285 | // determine page frame of to-fly anchored | ||||
286 | // Writer fly frame | ||||
287 | SwPageFrame* pFlyPageFrame = pFlyFrame->FindPageFrame(); | ||||
288 | // determine page frame, if needed. | ||||
289 | if ( !pPageFrame ) | ||||
290 | { | ||||
291 | pPageFrame = mpFrame->FindPageFrame(); | ||||
292 | } | ||||
293 | if ( pPageFrame != pFlyPageFrame ) | ||||
294 | { | ||||
295 | OSL_ENSURE( pFlyPageFrame, "~SwFrameNotify: Fly from Nowhere" )do { if (true && (!(pFlyPageFrame))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "295" ": "), "%s", "~SwFrameNotify: Fly from Nowhere"); } } while (false); | ||||
296 | if( pFlyPageFrame ) | ||||
297 | pFlyPageFrame->MoveFly( pFlyFrame, pPageFrame ); | ||||
298 | else | ||||
299 | pPageFrame->AppendFlyToPage( pFlyFrame ); | ||||
300 | } | ||||
301 | } | ||||
302 | } | ||||
303 | // otherwise the objects are notified in dependence to | ||||
304 | // its positioning and alignment | ||||
305 | else | ||||
306 | { | ||||
307 | const SwFormatVertOrient& rVert = | ||||
308 | pContact->GetFormat()->GetVertOrient(); | ||||
309 | if ( ( rVert.GetVertOrient() == text::VertOrientation::CENTER || | ||||
310 | rVert.GetVertOrient() == text::VertOrientation::BOTTOM || | ||||
311 | rVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA ) && | ||||
312 | ( bChgHeight || bPrtHeight ) ) | ||||
313 | { | ||||
314 | bNotify = true; | ||||
315 | } | ||||
316 | if ( !bNotify ) | ||||
317 | { | ||||
318 | const SwFormatHoriOrient& rHori = | ||||
319 | pContact->GetFormat()->GetHoriOrient(); | ||||
320 | if ( ( rHori.GetHoriOrient() != text::HoriOrientation::NONE || | ||||
321 | rHori.GetRelationOrient()== text::RelOrientation::PRINT_AREA || | ||||
322 | rHori.GetRelationOrient()== text::RelOrientation::FRAME ) && | ||||
323 | ( bChgWidth || bPrtWidth || bChgFlyBasePos ) ) | ||||
324 | { | ||||
325 | bNotify = true; | ||||
326 | } | ||||
327 | } | ||||
328 | } | ||||
329 | } | ||||
330 | else if ( bPrtWidth ) | ||||
331 | { | ||||
332 | // Notify as-character anchored objects, if printing area | ||||
333 | // width has changed. | ||||
334 | bNotify = true; | ||||
335 | bNotifySize = true; | ||||
336 | } | ||||
337 | |||||
338 | // perform notification via the corresponding invalidations | ||||
339 | if ( bNotify ) | ||||
340 | { | ||||
341 | if ( dynamic_cast<const SwFlyFrame*>( pObj) != nullptr ) | ||||
342 | { | ||||
343 | SwFlyFrame* pFlyFrame = static_cast<SwFlyFrame*>(pObj); | ||||
344 | if ( bNotifySize ) | ||||
345 | pFlyFrame->InvalidateSize_(); | ||||
346 | // #115759# - no invalidation of | ||||
347 | // position for as-character anchored objects. | ||||
348 | if ( !bAnchoredAsChar ) | ||||
349 | { | ||||
350 | pFlyFrame->InvalidatePos_(); | ||||
351 | } | ||||
352 | pFlyFrame->Invalidate_(); | ||||
353 | } | ||||
354 | else if ( dynamic_cast<const SwAnchoredDrawObject*>( pObj) != nullptr ) | ||||
355 | { | ||||
356 | // #115759# - no invalidation of | ||||
357 | // position for as-character anchored objects. | ||||
358 | if ( !bAnchoredAsChar ) | ||||
359 | { | ||||
360 | pObj->InvalidateObjPos(); | ||||
361 | } | ||||
362 | } | ||||
363 | else | ||||
364 | { | ||||
365 | OSL_FAIL( "<SwContentNotify::~SwContentNotify()> - unknown anchored object type." )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/frmtool.cxx" ":" "365" ": "), "%s", "<SwContentNotify::~SwContentNotify()> - unknown anchored object type." ); } } while (false); | ||||
366 | } | ||||
367 | } | ||||
368 | } | ||||
369 | } | ||||
370 | } | ||||
371 | else if( mpFrame->IsTextFrame() && mbValidSize != mpFrame->isFrameAreaSizeValid() ) | ||||
372 | { | ||||
373 | SwRootFrame *pRootFrame = mpFrame->getRootFrame(); | ||||
374 | if( pRootFrame && pRootFrame->IsAnyShellAccessible() && | ||||
375 | pRootFrame->GetCurrShell() ) | ||||
376 | { | ||||
377 | pRootFrame->GetCurrShell()->Imp()->InvalidateAccessibleFrameContent( mpFrame ); | ||||
378 | } | ||||
379 | } | ||||
380 | |||||
381 | // #i9046# Automatic frame width | ||||
382 | SwFlyFrame* pFly = nullptr; | ||||
383 | // #i35879# Do not trust the inf flags. pFrame does not | ||||
384 | // necessarily have to have an upper! | ||||
385 | if ( mpFrame->IsFlyFrame() || nullptr == ( pFly = mpFrame->ImplFindFlyFrame() )) | ||||
386 | return; | ||||
387 | |||||
388 | // #i61999# | ||||
389 | // no invalidation of columned Writer fly frames, because automatic | ||||
390 | // width doesn't make sense for such Writer fly frames. | ||||
391 | if ( !pFly->Lower() || pFly->Lower()->IsColumnFrame() ) | ||||
392 | return; | ||||
393 | |||||
394 | const SwFormatFrameSize &rFrameSz = pFly->GetFormat()->GetFrameSize(); | ||||
395 | |||||
396 | // This could be optimized. Basically the fly frame only has to | ||||
397 | // be invalidated, if the first line of pFrame (if pFrame is a content | ||||
398 | // frame, for other frame types it's the print area) has changed its | ||||
399 | // size and pFrame was responsible for the current width of pFly. On | ||||
400 | // the other hand, this is only rarely used and re-calculation of | ||||
401 | // the fly frame does not cause too much trouble. So we keep it this | ||||
402 | // way: | ||||
403 | if ( SwFrameSize::Fixed != rFrameSz.GetWidthSizeType() ) | ||||
404 | { | ||||
405 | // #i50668#, #i50998# - invalidation of position | ||||
406 | // of as-character anchored fly frames not needed and can cause | ||||
407 | // layout loops | ||||
408 | if ( dynamic_cast<const SwFlyInContentFrame*>( pFly) == nullptr ) | ||||
409 | { | ||||
410 | pFly->InvalidatePos(); | ||||
411 | } | ||||
412 | pFly->InvalidateSize(); | ||||
413 | } | ||||
414 | } | ||||
415 | |||||
416 | SwLayNotify::SwLayNotify( SwLayoutFrame *pLayFrame ) : | ||||
417 | SwFrameNotify( pLayFrame ), | ||||
418 | m_bLowersComplete( false ) | ||||
419 | { | ||||
420 | } | ||||
421 | |||||
422 | // OD 2004-05-11 #i28701# - local method to invalidate the position of all | ||||
423 | // frames inclusive its floating screen objects, which are lowers of the given | ||||
424 | // layout frame | ||||
425 | static void lcl_InvalidatePosOfLowers( SwLayoutFrame& _rLayoutFrame ) | ||||
426 | { | ||||
427 | if( _rLayoutFrame.IsFlyFrame() && _rLayoutFrame.GetDrawObjs() ) | ||||
428 | { | ||||
429 | _rLayoutFrame.InvalidateObjs( false ); | ||||
430 | } | ||||
431 | |||||
432 | SwFrame* pLowerFrame = _rLayoutFrame.Lower(); | ||||
433 | while ( pLowerFrame ) | ||||
434 | { | ||||
435 | pLowerFrame->InvalidatePos(); | ||||
436 | if ( pLowerFrame->IsTextFrame() ) | ||||
437 | { | ||||
438 | static_cast<SwTextFrame*>(pLowerFrame)->Prepare( PrepareHint::FramePositionChanged ); | ||||
439 | } | ||||
440 | else if ( pLowerFrame->IsTabFrame() ) | ||||
441 | { | ||||
442 | pLowerFrame->InvalidatePrt(); | ||||
443 | } | ||||
444 | |||||
445 | pLowerFrame->InvalidateObjs( false ); | ||||
446 | |||||
447 | pLowerFrame = pLowerFrame->GetNext(); | ||||
448 | } | ||||
449 | } | ||||
450 | |||||
451 | SwLayNotify::~SwLayNotify() | ||||
452 | { | ||||
453 | SwLayoutFrame *pLay = static_cast<SwLayoutFrame*>(mpFrame); | ||||
454 | SwRectFnSet aRectFnSet(pLay); | ||||
455 | bool bNotify = false; | ||||
456 | if ( pLay->getFramePrintArea().SSize() != maPrt.SSize() ) | ||||
457 | { | ||||
458 | if ( !IsLowersComplete() ) | ||||
459 | { | ||||
460 | bool bInvaPercent; | ||||
461 | |||||
462 | if ( pLay->IsRowFrame() ) | ||||
463 | { | ||||
464 | bInvaPercent = true; | ||||
465 | long nNew = aRectFnSet.GetHeight(pLay->getFramePrintArea()); | ||||
466 | if( nNew != aRectFnSet.GetHeight(maPrt) ) | ||||
467 | static_cast<SwRowFrame*>(pLay)->AdjustCells( nNew, true); | ||||
468 | if( aRectFnSet.GetWidth(pLay->getFramePrintArea()) | ||||
469 | != aRectFnSet.GetWidth(maPrt) ) | ||||
470 | static_cast<SwRowFrame*>(pLay)->AdjustCells( 0, false ); | ||||
471 | } | ||||
472 | else | ||||
473 | { | ||||
474 | //Proportional adoption of the internal. | ||||
475 | //1. If the formatted is no Fly | ||||
476 | //2. If he contains no columns | ||||
477 | //3. If the Fly has a fixed height and the columns | ||||
478 | // are next to be. | ||||
479 | // Hoehe danebenliegen. | ||||
480 | //4. Never at SectionFrames. | ||||
481 | bool bLow; | ||||
482 | if( pLay->IsFlyFrame() ) | ||||
483 | { | ||||
484 | if ( pLay->Lower() ) | ||||
485 | { | ||||
486 | bLow = !pLay->Lower()->IsColumnFrame() || | ||||
487 | aRectFnSet.GetHeight(pLay->Lower()->getFrameArea()) | ||||
488 | != aRectFnSet.GetHeight(pLay->getFramePrintArea()); | ||||
489 | } | ||||
490 | else | ||||
491 | bLow = false; | ||||
492 | } | ||||
493 | else if( pLay->IsSctFrame() ) | ||||
494 | { | ||||
495 | if ( pLay->Lower() ) | ||||
496 | { | ||||
497 | if( pLay->Lower()->IsColumnFrame() && pLay->Lower()->GetNext() ) | ||||
498 | bLow = pLay->Lower()->getFrameArea().Height() != pLay->getFramePrintArea().Height(); | ||||
499 | else | ||||
500 | bLow = pLay->getFramePrintArea().Width() != maPrt.Width(); | ||||
501 | } | ||||
502 | else | ||||
503 | bLow = false; | ||||
504 | } | ||||
505 | else if( pLay->IsFooterFrame() && !pLay->HasFixSize() ) | ||||
506 | bLow = pLay->getFramePrintArea().Width() != maPrt.Width(); | ||||
507 | else | ||||
508 | bLow = true; | ||||
509 | bInvaPercent = bLow; | ||||
510 | if ( bLow ) | ||||
511 | { | ||||
512 | pLay->ChgLowersProp( maPrt.SSize() ); | ||||
513 | } | ||||
514 | // If the PrtArea has been extended, it might be possible that the chain of parts | ||||
515 | // can take another frame. As a result, the "possible right one" needs to be | ||||
516 | // invalidated. This only pays off if this or its Uppers are moveable sections. | ||||
517 | // A PrtArea has been extended if width or height are larger than before. | ||||
518 | if ( (pLay->getFramePrintArea().Height() > maPrt.Height() || | ||||
519 | pLay->getFramePrintArea().Width() > maPrt.Width()) && | ||||
520 | (pLay->IsMoveable() || pLay->IsFlyFrame()) ) | ||||
521 | { | ||||
522 | SwFrame *pTmpFrame = pLay->Lower(); | ||||
523 | if ( pTmpFrame && pTmpFrame->IsFlowFrame() ) | ||||
524 | { | ||||
525 | while ( pTmpFrame->GetNext() ) | ||||
526 | pTmpFrame = pTmpFrame->GetNext(); | ||||
527 | pTmpFrame->InvalidateNextPos(); | ||||
528 | } | ||||
529 | } | ||||
530 | } | ||||
531 | bNotify = true; | ||||
532 | //EXPENSIVE!! But how we do it more elegant? | ||||
533 | if( bInvaPercent ) | ||||
534 | pLay->InvaPercentLowers( pLay->getFramePrintArea().Height() - maPrt.Height() ); | ||||
535 | } | ||||
536 | if ( pLay->IsTabFrame() ) | ||||
537 | //So that _only_ the shadow is drawn while resizing. | ||||
538 | static_cast<SwTabFrame*>(pLay)->SetComplete(); | ||||
539 | else | ||||
540 | { | ||||
541 | const SwViewShell *pSh = pLay->getRootFrame()->GetCurrShell(); | ||||
542 | if( !( pSh && pSh->GetViewOptions()->getBrowseMode() ) || | ||||
543 | !(pLay->GetType() & (SwFrameType::Body | SwFrameType::Page)) ) | ||||
544 | //Thereby the subordinates are retouched clean. | ||||
545 | //Example problem: Take the Flys with the handles and downsize. | ||||
546 | //Not for body and page, otherwise it flickers when loading HTML. | ||||
547 | pLay->SetCompletePaint(); | ||||
548 | } | ||||
549 | } | ||||
550 | //Notify Lower if the position has changed. | ||||
551 | const bool bPrtPos = aRectFnSet.PosDiff( maPrt, pLay->getFramePrintArea() ); | ||||
552 | const bool bPos = bPrtPos || aRectFnSet.PosDiff( maFrame, pLay->getFrameArea() ); | ||||
553 | const bool bSize = pLay->getFrameArea().SSize() != maFrame.SSize(); | ||||
554 | |||||
555 | if ( bPos && pLay->Lower() && !IsLowersComplete() ) | ||||
556 | { | ||||
557 | pLay->Lower()->InvalidatePos(); | ||||
558 | SwFootnoteFrame* pFtnFrame = pLay->Lower()->IsFootnoteFrame() ? | ||||
559 | static_cast<SwFootnoteFrame*>(pLay->Lower()) : nullptr; | ||||
560 | SwFrame* pFtnLower = pFtnFrame ? pFtnFrame->Lower() : nullptr; | ||||
561 | if (pFtnLower) | ||||
562 | pFtnLower->InvalidatePos(); | ||||
563 | } | ||||
564 | |||||
565 | if ( bPrtPos ) | ||||
566 | pLay->SetCompletePaint(); | ||||
567 | |||||
568 | //Inform the Follower if the SSize has changed. | ||||
569 | if ( bSize ) | ||||
570 | { | ||||
571 | if( pLay->GetNext() ) | ||||
572 | { | ||||
573 | if ( pLay->GetNext()->IsLayoutFrame() ) | ||||
574 | pLay->GetNext()->InvalidatePos_(); | ||||
575 | else | ||||
576 | pLay->GetNext()->InvalidatePos(); | ||||
577 | } | ||||
578 | else if( pLay->IsSctFrame() ) | ||||
579 | pLay->InvalidateNextPos(); | ||||
580 | } | ||||
581 | if ( !IsLowersComplete() && | ||||
582 | !(pLay->GetType()&(SwFrameType::Fly|SwFrameType::Section) && | ||||
583 | pLay->Lower() && pLay->Lower()->IsColumnFrame()) && | ||||
584 | (bPos || bNotify) && | ||||
585 | !(pLay->GetType() & (SwFrameType::Row|SwFrameType::Tab|SwFrameType::FtnCont|SwFrameType::Page|SwFrameType::Root))) | ||||
586 | { | ||||
587 | // #i44016# - force unlock of position of lower objects. | ||||
588 | // #i43913# - no unlock of position of objects, | ||||
589 | // if <pLay> is a cell frame, and its table frame resp. its parent table | ||||
590 | // frame is locked. | ||||
591 | // #i47458# - force unlock of position of lower objects, | ||||
592 | // only if position of layout frame has changed. | ||||
593 | bool bUnlockPosOfObjs( bPos ); | ||||
594 | if ( bUnlockPosOfObjs && pLay->IsCellFrame() ) | ||||
595 | { | ||||
596 | SwTabFrame* pTabFrame( pLay->FindTabFrame() ); | ||||
597 | if ( pTabFrame && | ||||
598 | ( pTabFrame->IsJoinLocked() || | ||||
599 | ( pTabFrame->IsFollow() && | ||||
600 | pTabFrame->FindMaster()->IsJoinLocked() ) ) ) | ||||
601 | { | ||||
602 | bUnlockPosOfObjs = false; | ||||
603 | } | ||||
604 | } | ||||
605 | // #i49383# - check for footnote frame, if unlock | ||||
606 | // of position of lower objects is allowed. | ||||
607 | else if ( bUnlockPosOfObjs && pLay->IsFootnoteFrame() ) | ||||
608 | { | ||||
609 | bUnlockPosOfObjs = static_cast<SwFootnoteFrame*>(pLay)->IsUnlockPosOfLowerObjs(); | ||||
610 | } | ||||
611 | // #i51303# - no unlock of object positions for sections | ||||
612 | else if ( bUnlockPosOfObjs && pLay->IsSctFrame() ) | ||||
613 | { | ||||
614 | bUnlockPosOfObjs = false; | ||||
615 | } | ||||
616 | pLay->NotifyLowerObjs( bUnlockPosOfObjs ); | ||||
617 | } | ||||
618 | if ( bPos && pLay->IsFootnoteFrame() && pLay->Lower() ) | ||||
619 | { | ||||
620 | // OD 2004-05-11 #i28701# | ||||
621 | ::lcl_InvalidatePosOfLowers( *pLay ); | ||||
622 | } | ||||
623 | if( ( bPos || bSize ) && pLay->IsFlyFrame() && static_cast<SwFlyFrame*>(pLay)->GetAnchorFrame() | ||||
624 | && static_cast<SwFlyFrame*>(pLay)->GetAnchorFrame()->IsFlyFrame() ) | ||||
625 | static_cast<SwFlyFrame*>(pLay)->AnchorFrame()->InvalidateSize(); | ||||
626 | } | ||||
627 | |||||
628 | SwFlyNotify::SwFlyNotify( SwFlyFrame *pFlyFrame ) : | ||||
629 | SwLayNotify( pFlyFrame ), | ||||
630 | // #115759# - keep correct page frame - the page frame | ||||
631 | // the Writer fly frame is currently registered at. | ||||
632 | pOldPage( pFlyFrame->GetPageFrame() ), | ||||
633 | aFrameAndSpace( pFlyFrame->GetObjRectWithSpaces() ) | ||||
634 | { | ||||
635 | } | ||||
636 | |||||
637 | SwFlyNotify::~SwFlyNotify() | ||||
638 | { | ||||
639 | SwFlyFrame *pFly = static_cast<SwFlyFrame*>(mpFrame); | ||||
640 | if ( pFly->IsNotifyBack() ) | ||||
641 | { | ||||
642 | SwViewShell *pSh = pFly->getRootFrame()->GetCurrShell(); | ||||
643 | SwViewShellImp *pImp = pSh ? pSh->Imp() : nullptr; | ||||
644 | if ( !pImp || !pImp->IsAction() || !pImp->GetLayAction().IsAgain() ) | ||||
645 | { | ||||
646 | //If in the LayAction the IsAgain is set it can be | ||||
647 | //that the old page is destroyed in the meantime! | ||||
648 | ::Notify( pFly, pOldPage, aFrameAndSpace, &maPrt ); | ||||
649 | // #i35640# - additional notify anchor text frame, | ||||
650 | // if Writer fly frame has changed its page | ||||
651 | if ( pFly->GetAnchorFrame()->IsTextFrame() && | ||||
652 | pFly->GetPageFrame() != pOldPage ) | ||||
653 | { | ||||
654 | pFly->AnchorFrame()->Prepare( PrepareHint::FlyFrameLeave ); | ||||
655 | } | ||||
656 | } | ||||
657 | pFly->ResetNotifyBack(); | ||||
658 | } | ||||
659 | |||||
660 | //Have the size or the position changed, | ||||
661 | //so should the view know this. | ||||
662 | SwRectFnSet aRectFnSet(pFly); | ||||
663 | const bool bPosChgd = aRectFnSet.PosDiff( maFrame, pFly->getFrameArea() ); | ||||
664 | const bool bFrameChgd = pFly->getFrameArea().SSize() != maFrame.SSize(); | ||||
665 | const bool bPrtChgd = maPrt != pFly->getFramePrintArea(); | ||||
666 | if ( bPosChgd || bFrameChgd || bPrtChgd ) | ||||
667 | { | ||||
668 | pFly->NotifyDrawObj(); | ||||
669 | } | ||||
670 | if ( bPosChgd && maFrame.Pos().X() != FAR_AWAY(((sal_Int32) 0x7FFFFFFF) - 20000) ) | ||||
671 | { | ||||
672 | // OD 2004-05-10 #i28701# - no direct move of lower Writer fly frames. | ||||
673 | // reason: New positioning and alignment (e.g. to-paragraph anchored, | ||||
674 | // but aligned at page) are introduced. | ||||
675 | // <SwLayNotify::~SwLayNotify()> takes care of invalidation of lower | ||||
676 | // floating screen objects by calling method <SwLayoutFrame::NotifyLowerObjs()>. | ||||
677 | |||||
678 | if ( pFly->IsFlyAtContentFrame() ) | ||||
679 | { | ||||
680 | SwFrame *pNxt = pFly->AnchorFrame()->FindNext(); | ||||
681 | if ( pNxt ) | ||||
682 | { | ||||
683 | pNxt->InvalidatePos(); | ||||
684 | } | ||||
685 | } | ||||
686 | |||||
687 | // #i26945# - notify anchor. | ||||
688 | // Needed for negative positioned Writer fly frames | ||||
689 | if ( pFly->GetAnchorFrame()->IsTextFrame() ) | ||||
690 | { | ||||
691 | pFly->AnchorFrame()->Prepare( PrepareHint::FlyFrameLeave ); | ||||
692 | } | ||||
693 | } | ||||
694 | |||||
695 | // OD 2004-05-13 #i28701# | ||||
696 | // #i45180# - no adjustment of layout process flags and | ||||
697 | // further notifications/invalidations, if format is called by grow/shrink | ||||
698 | if ( !(pFly->ConsiderObjWrapInfluenceOnObjPos() && | ||||
699 | ( dynamic_cast<const SwFlyFreeFrame*>( pFly) == nullptr || | ||||
700 | !static_cast<SwFlyFreeFrame*>(pFly)->IsNoMoveOnCheckClip() )) ) | ||||
701 | return; | ||||
702 | |||||
703 | // #i54138# - suppress restart of the layout process | ||||
704 | // on changed frame height. | ||||
705 | // Note: It doesn't seem to be necessary and can cause layout loops. | ||||
706 | if ( bPosChgd ) | ||||
707 | { | ||||
708 | // indicate a restart of the layout process | ||||
709 | pFly->SetRestartLayoutProcess( true ); | ||||
710 | } | ||||
711 | else | ||||
712 | { | ||||
713 | // lock position | ||||
714 | pFly->LockPosition(); | ||||
715 | } | ||||
716 | |||||
717 | if ( pFly->ConsiderForTextWrap() ) | ||||
718 | return; | ||||
719 | |||||
720 | // indicate that object has to be considered for text wrap | ||||
721 | pFly->SetConsiderForTextWrap( true ); | ||||
722 | // invalidate 'background' in order to allow its 'background' | ||||
723 | // to wrap around it. | ||||
724 | pFly->NotifyBackground( pFly->GetPageFrame(), | ||||
725 | pFly->GetObjRectWithSpaces(), | ||||
726 | PrepareHint::FlyFrameArrive ); | ||||
727 | // invalidate position of anchor frame in order to force | ||||
728 | // a re-format of the anchor frame, which also causes a | ||||
729 | // re-format of the invalid previous frames of the anchor frame. | ||||
730 | pFly->AnchorFrame()->InvalidatePos(); | ||||
731 | } | ||||
732 | |||||
733 | SwContentNotify::SwContentNotify( SwContentFrame *pContentFrame ) : | ||||
734 | SwFrameNotify( pContentFrame ), | ||||
735 | // OD 08.01.2004 #i11859# | ||||
736 | mbChkHeightOfLastLine( false ), | ||||
737 | mnHeightOfLastLine( 0 ), | ||||
738 | // OD 2004-02-26 #i25029# | ||||
739 | mbInvalidatePrevPrtArea( false ), | ||||
740 | mbBordersJoinedWithPrev( false ) | ||||
741 | { | ||||
742 | // OD 08.01.2004 #i11859# | ||||
743 | if ( !pContentFrame->IsTextFrame() ) | ||||
744 | return; | ||||
745 | |||||
746 | SwTextFrame* pTextFrame = static_cast<SwTextFrame*>(pContentFrame); | ||||
747 | if (!pTextFrame->GetDoc().getIDocumentSettingAccess().get(DocumentSettingId::OLD_LINE_SPACING)) | ||||
748 | { | ||||
749 | const SvxLineSpacingItem &rSpace = pTextFrame->GetAttrSet()->GetLineSpacing(); | ||||
750 | if ( rSpace.GetInterLineSpaceRule() == SvxInterLineSpaceRule::Prop ) | ||||
751 | { | ||||
752 | mbChkHeightOfLastLine = true; | ||||
753 | mnHeightOfLastLine = pTextFrame->GetHeightOfLastLine(); | ||||
754 | } | ||||
755 | } | ||||
756 | } | ||||
757 | |||||
758 | SwContentNotify::~SwContentNotify() | ||||
759 | { | ||||
760 | SwContentFrame *pCnt = static_cast<SwContentFrame*>(mpFrame); | ||||
761 | if ( bSetCompletePaintOnInvalidate ) | ||||
762 | pCnt->SetCompletePaint(); | ||||
763 | |||||
764 | SwRectFnSet aRectFnSet(pCnt); | ||||
765 | if ( pCnt->IsInTab() && ( aRectFnSet.PosDiff( pCnt->getFrameArea(), maFrame ) || | ||||
766 | pCnt->getFrameArea().SSize() != maFrame.SSize())) | ||||
767 | { | ||||
768 | SwLayoutFrame* pCell = pCnt->GetUpper(); | ||||
769 | while( !pCell->IsCellFrame() && pCell->GetUpper() ) | ||||
770 | pCell = pCell->GetUpper(); | ||||
771 | OSL_ENSURE( pCell->IsCellFrame(), "Where's my cell?" )do { if (true && (!(pCell->IsCellFrame()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "771" ": "), "%s", "Where's my cell?"); } } while (false ); | ||||
772 | if ( text::VertOrientation::NONE != pCell->GetFormat()->GetVertOrient().GetVertOrient() ) | ||||
773 | pCell->InvalidatePrt(); //for the vertical align. | ||||
774 | } | ||||
775 | |||||
776 | // OD 2004-02-26 #i25029# | ||||
777 | if ( mbInvalidatePrevPrtArea && mbBordersJoinedWithPrev && | ||||
778 | pCnt->IsTextFrame() && | ||||
779 | !pCnt->IsFollow() && !pCnt->GetIndPrev() ) | ||||
780 | { | ||||
781 | // determine previous frame | ||||
782 | SwFrame* pPrevFrame = pCnt->FindPrev(); | ||||
783 | // skip empty section frames and hidden text frames | ||||
784 | { | ||||
785 | while ( pPrevFrame && | ||||
786 | ( ( pPrevFrame->IsSctFrame() && | ||||
787 | !static_cast<SwSectionFrame*>(pPrevFrame)->GetSection() ) || | ||||
788 | ( pPrevFrame->IsTextFrame() && | ||||
789 | static_cast<SwTextFrame*>(pPrevFrame)->IsHiddenNow() ) ) ) | ||||
790 | { | ||||
791 | pPrevFrame = pPrevFrame->FindPrev(); | ||||
792 | } | ||||
793 | } | ||||
794 | |||||
795 | // Invalidate printing area of found previous frame | ||||
796 | if ( pPrevFrame ) | ||||
797 | { | ||||
798 | if ( pPrevFrame->IsSctFrame() ) | ||||
799 | { | ||||
800 | if ( pCnt->IsInSct() ) | ||||
801 | { | ||||
802 | // Note: found previous frame is a section frame and | ||||
803 | // <pCnt> is also inside a section. | ||||
804 | // Thus due to <mbBordersJoinedWithPrev>, | ||||
805 | // <pCnt> had joined its borders/shadow with the | ||||
806 | // last content of the found section. | ||||
807 | // Invalidate printing area of last content in found section. | ||||
808 | SwFrame* pLstContentOfSctFrame = | ||||
809 | static_cast<SwSectionFrame*>(pPrevFrame)->FindLastContent(); | ||||
810 | if ( pLstContentOfSctFrame ) | ||||
811 | { | ||||
812 | pLstContentOfSctFrame->InvalidatePrt(); | ||||
813 | } | ||||
814 | } | ||||
815 | } | ||||
816 | else | ||||
817 | { | ||||
818 | pPrevFrame->InvalidatePrt(); | ||||
819 | } | ||||
820 | } | ||||
821 | } | ||||
822 | |||||
823 | const bool bFirst = aRectFnSet.GetWidth(maFrame) == 0; | ||||
824 | |||||
825 | if ( pCnt->IsNoTextFrame() ) | ||||
826 | { | ||||
827 | //Active PlugIn's or OLE-Objects should know something of the change | ||||
828 | //thereby they move their window appropriate. | ||||
829 | SwViewShell *pSh = pCnt->getRootFrame()->GetCurrShell(); | ||||
830 | if ( pSh ) | ||||
831 | { | ||||
832 | SwOLENode *const pNd(static_cast<SwNoTextFrame*>(pCnt)->GetNode()->GetOLENode()); | ||||
833 | if (nullptr != pNd && | ||||
834 | (pNd->GetOLEObj().IsOleRef() || | ||||
835 | pNd->IsOLESizeInvalid()) ) | ||||
836 | { | ||||
837 | const bool bNoTextFramePrtAreaChanged = | ||||
838 | ( maPrt.SSize().Width() != 0 && | ||||
839 | maPrt.SSize().Height() != 0 ) && | ||||
840 | maPrt.SSize() != pCnt->getFramePrintArea().SSize(); | ||||
841 | OSL_ENSURE( pCnt->IsInFly(), "OLE not in FlyFrame" )do { if (true && (!(pCnt->IsInFly()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "841" ": "), "%s", "OLE not in FlyFrame"); } } while (false ); | ||||
842 | SwFlyFrame *pFly = pCnt->FindFlyFrame(); | ||||
843 | svt::EmbeddedObjectRef& xObj = pNd->GetOLEObj().GetObject(); | ||||
844 | SwFEShell *pFESh = nullptr; | ||||
845 | for(SwViewShell& rCurrentShell : pSh->GetRingContainer()) | ||||
846 | { if ( dynamic_cast<const SwCursorShell*>( &rCurrentShell) != nullptr ) | ||||
847 | { | ||||
848 | pFESh = static_cast<SwFEShell*>(&rCurrentShell); | ||||
849 | // #108369#: Here used to be the condition if (!bFirst). | ||||
850 | // I think this should mean "do not call CalcAndSetScale" | ||||
851 | // if the frame is formatted for the first time. | ||||
852 | // Unfortunately this is not valid anymore since the | ||||
853 | // SwNoTextFrame already gets a width during CalcLowerPreps. | ||||
854 | // Nevertheless, the indention of !bFirst seemed to be | ||||
855 | // to assure that the OLE objects have already been notified | ||||
856 | // if necessary before calling CalcAndSetScale. | ||||
857 | // So I replaced !bFirst by !IsOLESizeInvalid. There is | ||||
858 | // one additional problem specific to the word import: | ||||
859 | // The layout is calculated _before_ calling PrtOLENotify, | ||||
860 | // and the OLE objects are not invalidated during import. | ||||
861 | // Therefore I added the condition !IsUpdateExpField, | ||||
862 | // have a look at the occurrence of CalcLayout in | ||||
863 | // uiview/view.cxx. | ||||
864 | if ( !pNd->IsOLESizeInvalid() && | ||||
865 | !pSh->GetDoc()->getIDocumentState().IsUpdateExpField() ) | ||||
866 | pFESh->CalcAndSetScale( xObj, | ||||
867 | &pFly->getFramePrintArea(), &pFly->getFrameArea(), | ||||
868 | bNoTextFramePrtAreaChanged ); | ||||
869 | } | ||||
870 | } | ||||
871 | |||||
872 | if ( pFESh && pNd->IsOLESizeInvalid() ) | ||||
873 | { | ||||
874 | pNd->SetOLESizeInvalid( false ); | ||||
875 | pFESh->CalcAndSetScale( xObj ); // create client | ||||
876 | } | ||||
877 | } | ||||
878 | // ditto animated graphics | ||||
879 | if ( getFrameArea().HasArea() && static_cast<SwNoTextFrame*>(pCnt)->HasAnimation() ) | ||||
880 | { | ||||
881 | static_cast<SwNoTextFrame*>(pCnt)->StopAnimation(); | ||||
882 | pSh->InvalidateWindows( getFrameArea() ); | ||||
883 | } | ||||
884 | } | ||||
885 | } | ||||
886 | |||||
887 | if ( bFirst ) | ||||
888 | { | ||||
889 | pCnt->SetRetouche(); //fix(13870) | ||||
890 | |||||
891 | SwDoc& rDoc = pCnt->IsTextFrame() | ||||
892 | ? static_cast<SwTextFrame*>(pCnt)->GetDoc() | ||||
893 | : static_cast<SwNoTextFrame*>(pCnt)->GetNode()->GetDoc(); | ||||
894 | if ( !rDoc.GetSpzFrameFormats()->empty() && | ||||
895 | rDoc.DoesContainAtPageObjWithContentAnchor() && !rDoc.getIDocumentState().IsNewDoc() ) | ||||
896 | { | ||||
897 | // If certain import filters for foreign file format import | ||||
898 | // AT_PAGE anchored objects, the corresponding page number is | ||||
899 | // typically not known. In this case the content position is | ||||
900 | // stored at which the anchored object is found in the | ||||
901 | // imported document. | ||||
902 | // When this content is formatted it is the time at which | ||||
903 | // the page is known. Thus, this data can be corrected now. | ||||
904 | |||||
905 | const SwPageFrame *pPage = nullptr; | ||||
906 | SwFrameFormats *pTable = rDoc.GetSpzFrameFormats(); | ||||
907 | |||||
908 | for ( size_t i = 0; i < pTable->size(); ++i ) | ||||
909 | { | ||||
910 | SwFrameFormat *pFormat = (*pTable)[i]; | ||||
911 | const SwFormatAnchor &rAnch = pFormat->GetAnchor(); | ||||
912 | if ( RndStdIds::FLY_AT_PAGE != rAnch.GetAnchorId() || | ||||
913 | rAnch.GetContentAnchor() == nullptr ) | ||||
914 | { | ||||
915 | continue; | ||||
916 | } | ||||
917 | |||||
918 | if (FrameContainsNode(*pCnt, rAnch.GetContentAnchor()->nNode.GetIndex())) | ||||
919 | { | ||||
920 | OSL_FAIL( "<SwContentNotify::~SwContentNotify()> - to page anchored object with content position." )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/frmtool.cxx" ":" "920" ": "), "%s", "<SwContentNotify::~SwContentNotify()> - to page anchored object with content position." ); } } while (false); | ||||
921 | if ( !pPage ) | ||||
922 | { | ||||
923 | pPage = pCnt->FindPageFrame(); | ||||
924 | } | ||||
925 | SwFormatAnchor aAnch( rAnch ); | ||||
926 | aAnch.SetAnchor( nullptr ); | ||||
927 | aAnch.SetPageNum( pPage->GetPhyPageNum() ); | ||||
928 | pFormat->SetFormatAttr( aAnch ); | ||||
929 | if ( RES_DRAWFRMFMT != pFormat->Which() ) | ||||
930 | { | ||||
931 | pFormat->MakeFrames(); | ||||
932 | } | ||||
933 | } | ||||
934 | } | ||||
935 | } | ||||
936 | } | ||||
937 | |||||
938 | // OD 12.01.2004 #i11859# - invalidate printing area of following frame, | ||||
939 | // if height of last line has changed. | ||||
940 | if ( pCnt->IsTextFrame() && mbChkHeightOfLastLine ) | ||||
941 | { | ||||
942 | if ( mnHeightOfLastLine != static_cast<SwTextFrame*>(pCnt)->GetHeightOfLastLine() ) | ||||
943 | { | ||||
944 | pCnt->InvalidateNextPrtArea(); | ||||
945 | } | ||||
946 | } | ||||
947 | |||||
948 | // #i44049# | ||||
949 | if ( pCnt->IsTextFrame() && aRectFnSet.PosDiff( maFrame, pCnt->getFrameArea() ) ) | ||||
950 | { | ||||
951 | pCnt->InvalidateObjs(); | ||||
952 | } | ||||
953 | |||||
954 | // #i43255# - move code to invalidate at-character | ||||
955 | // anchored objects due to a change of its anchor character from | ||||
956 | // method <SwTextFrame::Format(..)>. | ||||
957 | if ( !pCnt->IsTextFrame() ) | ||||
958 | return; | ||||
959 | |||||
960 | SwTextFrame* pMasterFrame = pCnt->IsFollow() | ||||
961 | ? static_cast<SwTextFrame*>(pCnt)->FindMaster() | ||||
962 | : static_cast<SwTextFrame*>(pCnt); | ||||
963 | if ( pMasterFrame && !pMasterFrame->IsFlyLock() && | ||||
964 | pMasterFrame->GetDrawObjs() ) | ||||
965 | { | ||||
966 | SwSortedObjs* pObjs = pMasterFrame->GetDrawObjs(); | ||||
967 | for (SwAnchoredObject* pAnchoredObj : *pObjs) | ||||
968 | { | ||||
969 | if ( pAnchoredObj->GetFrameFormat().GetAnchor().GetAnchorId() | ||||
970 | == RndStdIds::FLY_AT_CHAR ) | ||||
971 | { | ||||
972 | pAnchoredObj->CheckCharRectAndTopOfLine( !pMasterFrame->IsEmpty() ); | ||||
973 | } | ||||
974 | } | ||||
975 | } | ||||
976 | } | ||||
977 | |||||
978 | // note this *cannot* be static because it's a friend | ||||
979 | void AppendObj(SwFrame *const pFrame, SwPageFrame *const pPage, SwFrameFormat *const pFormat, const SwFormatAnchor & rAnch) | ||||
980 | { | ||||
981 | const bool bFlyAtFly = rAnch.GetAnchorId() == RndStdIds::FLY_AT_FLY; // LAYER_IMPL | ||||
982 | //Is a frame or a SdrObject described? | ||||
983 | const bool bSdrObj = RES_DRAWFRMFMT == pFormat->Which(); | ||||
984 | // OD 23.06.2003 #108784# - append also drawing objects anchored | ||||
985 | // as character. | ||||
986 | const bool bDrawObjInContent = bSdrObj && | ||||
987 | (rAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR); | ||||
988 | |||||
989 | if( !(bFlyAtFly || | ||||
990 | (rAnch.GetAnchorId() == RndStdIds::FLY_AT_PARA) || | ||||
991 | (rAnch.GetAnchorId() == RndStdIds::FLY_AT_CHAR) || | ||||
992 | bDrawObjInContent) ) | ||||
993 | return; | ||||
994 | |||||
995 | SdrObject* pSdrObj = nullptr; | ||||
996 | if ( bSdrObj && nullptr == (pSdrObj = pFormat->FindSdrObject()) ) | ||||
997 | { | ||||
998 | OSL_ENSURE( !bSdrObj, "DrawObject not found." )do { if (true && (!(!bSdrObj))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "998" ": "), "%s", "DrawObject not found."); } } while ( false); | ||||
999 | pFormat->GetDoc()->DelFrameFormat( pFormat ); | ||||
1000 | return; | ||||
1001 | } | ||||
1002 | if ( pSdrObj ) | ||||
1003 | { | ||||
1004 | if ( !pSdrObj->getSdrPageFromSdrObject() ) | ||||
1005 | { | ||||
1006 | pFormat->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0)-> | ||||
1007 | InsertObject(pSdrObj, pSdrObj->GetOrdNumDirect()); | ||||
1008 | } | ||||
1009 | |||||
1010 | SwDrawContact* pNew = | ||||
1011 | static_cast<SwDrawContact*>(GetUserCall( pSdrObj )); | ||||
1012 | if ( !pNew->GetAnchorFrame() ) | ||||
1013 | { | ||||
1014 | pFrame->AppendDrawObj( *(pNew->GetAnchoredObj( nullptr )) ); | ||||
1015 | } | ||||
1016 | // OD 19.06.2003 #108784# - add 'virtual' drawing object, | ||||
1017 | // if necessary. But control objects have to be excluded. | ||||
1018 | else if ( !::CheckControlLayer( pSdrObj ) && | ||||
1019 | pNew->GetAnchorFrame() != pFrame && | ||||
1020 | !pNew->GetDrawObjectByAnchorFrame( *pFrame ) ) | ||||
1021 | { | ||||
1022 | SwDrawVirtObj* pDrawVirtObj = pNew->AddVirtObj(); | ||||
1023 | pFrame->AppendDrawObj( *(pNew->GetAnchoredObj( pDrawVirtObj )) ); | ||||
1024 | |||||
1025 | pDrawVirtObj->ActionChanged(); | ||||
1026 | } | ||||
1027 | } | ||||
1028 | else | ||||
1029 | { | ||||
1030 | SwFlyFrame *pFly; | ||||
1031 | if( bFlyAtFly ) | ||||
1032 | pFly = new SwFlyLayFrame( static_cast<SwFlyFrameFormat*>(pFormat), pFrame, pFrame ); | ||||
1033 | else | ||||
1034 | pFly = new SwFlyAtContentFrame( static_cast<SwFlyFrameFormat*>(pFormat), pFrame, pFrame ); | ||||
1035 | pFly->Lock(); | ||||
1036 | pFrame->AppendFly( pFly ); | ||||
1037 | pFly->Unlock(); | ||||
1038 | if ( pPage ) | ||||
1039 | ::RegistFlys( pPage, pFly ); | ||||
1040 | } | ||||
1041 | } | ||||
1042 | |||||
1043 | static bool IsShown(sal_uLong const nIndex, | ||||
1044 | const SwFormatAnchor & rAnch, | ||||
1045 | std::vector<sw::Extent>::const_iterator const*const pIter, | ||||
1046 | std::vector<sw::Extent>::const_iterator const*const pEnd, | ||||
1047 | SwTextNode const*const pFirstNode, SwTextNode const*const pLastNode) | ||||
1048 | { | ||||
1049 | assert(!pIter || *pIter == *pEnd || (*pIter)->pNode->GetIndex() == nIndex)(static_cast <bool> (!pIter || *pIter == *pEnd || (*pIter )->pNode->GetIndex() == nIndex) ? void (0) : __assert_fail ("!pIter || *pIter == *pEnd || (*pIter)->pNode->GetIndex() == nIndex" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1049, __extension__ __PRETTY_FUNCTION__)); | ||||
1050 | SwPosition const& rAnchor(*rAnch.GetContentAnchor()); | ||||
1051 | if (rAnchor.nNode.GetIndex() != nIndex) | ||||
1052 | { | ||||
1053 | return false; | ||||
1054 | } | ||||
1055 | if (rAnch.GetAnchorId() == RndStdIds::FLY_AT_PARA) | ||||
1056 | { | ||||
1057 | return pIter == nullptr // not merged | ||||
1058 | || pIter != pEnd // at least one char visible in node | ||||
1059 | || !IsSelectFrameAnchoredAtPara(rAnchor, | ||||
1060 | SwPosition(const_cast<SwTextNode&>(*pFirstNode), 0), | ||||
1061 | SwPosition(const_cast<SwTextNode&>(*pLastNode), pLastNode->Len())); | ||||
1062 | } | ||||
1063 | if (pIter) | ||||
1064 | { | ||||
1065 | // note: frames are not sorted by anchor position. | ||||
1066 | assert(pEnd)(static_cast <bool> (pEnd) ? void (0) : __assert_fail ( "pEnd", "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1066, __extension__ __PRETTY_FUNCTION__)); | ||||
1067 | assert(pFirstNode)(static_cast <bool> (pFirstNode) ? void (0) : __assert_fail ("pFirstNode", "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1067, __extension__ __PRETTY_FUNCTION__)); | ||||
1068 | assert(pLastNode)(static_cast <bool> (pLastNode) ? void (0) : __assert_fail ("pLastNode", "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1068, __extension__ __PRETTY_FUNCTION__)); | ||||
1069 | assert(rAnch.GetAnchorId() != RndStdIds::FLY_AT_FLY)(static_cast <bool> (rAnch.GetAnchorId() != RndStdIds:: FLY_AT_FLY) ? void (0) : __assert_fail ("rAnch.GetAnchorId() != RndStdIds::FLY_AT_FLY" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1069, __extension__ __PRETTY_FUNCTION__)); | ||||
1070 | for (auto iter = *pIter; iter != *pEnd; ++iter) | ||||
1071 | { | ||||
1072 | assert(iter->nStart != iter->nEnd)(static_cast <bool> (iter->nStart != iter->nEnd) ? void (0) : __assert_fail ("iter->nStart != iter->nEnd" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1072, __extension__ __PRETTY_FUNCTION__)); // TODO possible? | ||||
1073 | assert(iter->pNode->GetIndex() == nIndex)(static_cast <bool> (iter->pNode->GetIndex() == nIndex ) ? void (0) : __assert_fail ("iter->pNode->GetIndex() == nIndex" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1073, __extension__ __PRETTY_FUNCTION__)); | ||||
1074 | if (rAnchor.nContent.GetIndex() < iter->nStart) | ||||
1075 | { | ||||
1076 | return false; | ||||
1077 | } | ||||
1078 | if (rAnch.GetAnchorId() == RndStdIds::FLY_AT_CHAR) | ||||
1079 | { | ||||
1080 | // if there is an extent then obviously the node was not | ||||
1081 | // deleted fully... | ||||
1082 | // show if start <= pos <= end | ||||
1083 | // *or* if first-node/0 *and* not StartOfSection | ||||
1084 | // *or* if last-node/Len *and* not EndOfSection | ||||
1085 | |||||
1086 | // first determine the extent to compare to, then | ||||
1087 | // construct start/end positions for the deletion *before* the | ||||
1088 | // extent and compare once. | ||||
1089 | // the interesting corner cases are on the edge of the extent! | ||||
1090 | // no need to check for > the last extent because those | ||||
1091 | // are never visible. | ||||
1092 | if (rAnchor.nContent.GetIndex() <= iter->nEnd) | ||||
1093 | { | ||||
1094 | if (iter->nStart == 0) | ||||
1095 | { | ||||
1096 | return true; | ||||
1097 | } | ||||
1098 | else | ||||
1099 | { | ||||
1100 | SwPosition const start( | ||||
1101 | const_cast<SwTextNode&>( | ||||
1102 | iter == *pIter | ||||
1103 | ? *pFirstNode // simplification | ||||
1104 | : *iter->pNode), | ||||
1105 | iter == *pIter // first extent? | ||||
1106 | ? iter->pNode == pFirstNode | ||||
1107 | ? 0 // at start of 1st node | ||||
1108 | : pFirstNode->Len() // previous node; simplification but should get right result | ||||
1109 | : (iter-1)->nEnd); // previous extent | ||||
1110 | SwPosition const end(*iter->pNode, iter->nStart); | ||||
1111 | return !IsDestroyFrameAnchoredAtChar(rAnchor, start, end); | ||||
1112 | } | ||||
1113 | } | ||||
1114 | else if (iter == *pEnd - 1) // special case: after last extent | ||||
1115 | { | ||||
1116 | if (iter->nEnd == iter->pNode->Len()) | ||||
1117 | { | ||||
1118 | return true; // special case: end of node | ||||
1119 | } | ||||
1120 | else | ||||
1121 | { | ||||
1122 | SwPosition const start(*iter->pNode, iter->nEnd); | ||||
1123 | SwPosition const end( | ||||
1124 | const_cast<SwTextNode&>(*pLastNode), // simplification | ||||
1125 | iter->pNode == pLastNode | ||||
1126 | ? iter->pNode->Len() | ||||
1127 | : 0); | ||||
1128 | return !IsDestroyFrameAnchoredAtChar(rAnchor, start, end); | ||||
1129 | } | ||||
1130 | } | ||||
1131 | } | ||||
1132 | else | ||||
1133 | { | ||||
1134 | assert(rAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR)(static_cast <bool> (rAnch.GetAnchorId() == RndStdIds:: FLY_AS_CHAR) ? void (0) : __assert_fail ("rAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1134, __extension__ __PRETTY_FUNCTION__)); | ||||
1135 | // for AS_CHAR obviously must be < | ||||
1136 | if (rAnchor.nContent.GetIndex() < iter->nEnd) | ||||
1137 | { | ||||
1138 | return true; | ||||
1139 | } | ||||
1140 | } | ||||
1141 | } | ||||
1142 | return false; | ||||
1143 | } | ||||
1144 | else | ||||
1145 | { | ||||
1146 | return true; | ||||
1147 | } | ||||
1148 | } | ||||
1149 | |||||
1150 | void RemoveHiddenObjsOfNode(SwTextNode const& rNode, | ||||
1151 | std::vector<sw::Extent>::const_iterator const*const pIter, | ||||
1152 | std::vector<sw::Extent>::const_iterator const*const pEnd, | ||||
1153 | SwTextNode const*const pFirstNode, SwTextNode const*const pLastNode) | ||||
1154 | { | ||||
1155 | std::vector<SwFrameFormat*> const*const pFlys(rNode.GetAnchoredFlys()); | ||||
1156 | if (!pFlys) | ||||
1157 | { | ||||
1158 | return; | ||||
1159 | } | ||||
1160 | for (SwFrameFormat * pFrameFormat : *pFlys) | ||||
1161 | { | ||||
1162 | SwFormatAnchor const& rAnchor = pFrameFormat->GetAnchor(); | ||||
1163 | if (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR | ||||
1164 | || (rAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR | ||||
1165 | && RES_DRAWFRMFMT == pFrameFormat->Which())) | ||||
1166 | { | ||||
1167 | assert(rAnchor.GetContentAnchor()->nNode.GetIndex() == rNode.GetIndex())(static_cast <bool> (rAnchor.GetContentAnchor()->nNode .GetIndex() == rNode.GetIndex()) ? void (0) : __assert_fail ( "rAnchor.GetContentAnchor()->nNode.GetIndex() == rNode.GetIndex()" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1167, __extension__ __PRETTY_FUNCTION__)); | ||||
1168 | if (!IsShown(rNode.GetIndex(), rAnchor, pIter, pEnd, pFirstNode, pLastNode)) | ||||
1169 | { | ||||
1170 | pFrameFormat->DelFrames(); | ||||
1171 | } | ||||
1172 | } | ||||
1173 | } | ||||
1174 | } | ||||
1175 | |||||
1176 | void AppendObjsOfNode(SwFrameFormats const*const pTable, sal_uLong const nIndex, | ||||
1177 | SwFrame *const pFrame, SwPageFrame *const pPage, SwDoc *const pDoc, | ||||
1178 | std::vector<sw::Extent>::const_iterator const*const pIter, | ||||
1179 | std::vector<sw::Extent>::const_iterator const*const pEnd, | ||||
1180 | SwTextNode const*const pFirstNode, SwTextNode const*const pLastNode) | ||||
1181 | { | ||||
1182 | #if OSL_DEBUG_LEVEL1 > 0 | ||||
1183 | std::vector<SwFrameFormat*> checkFormats; | ||||
1184 | for ( size_t i = 0; i < pTable->size(); ++i ) | ||||
1185 | { | ||||
1186 | SwFrameFormat *pFormat = (*pTable)[i]; | ||||
1187 | const SwFormatAnchor &rAnch = pFormat->GetAnchor(); | ||||
1188 | if ( rAnch.GetContentAnchor() && | ||||
1189 | IsShown(nIndex, rAnch, pIter, pEnd, pFirstNode, pLastNode)) | ||||
1190 | { | ||||
1191 | checkFormats.push_back( pFormat ); | ||||
1192 | } | ||||
1193 | } | ||||
1194 | #else | ||||
1195 | (void)pTable; | ||||
1196 | #endif | ||||
1197 | |||||
1198 | SwNode const& rNode(*pDoc->GetNodes()[nIndex]); | ||||
1199 | std::vector<SwFrameFormat*> const*const pFlys(rNode.GetAnchoredFlys()); | ||||
1200 | for (size_t it = 0; pFlys && it != pFlys->size(); ) | ||||
1201 | { | ||||
1202 | SwFrameFormat *const pFormat = (*pFlys)[it]; | ||||
1203 | const SwFormatAnchor &rAnch = pFormat->GetAnchor(); | ||||
1204 | if ( rAnch.GetContentAnchor() && | ||||
1205 | IsShown(nIndex, rAnch, pIter, pEnd, pFirstNode, pLastNode)) | ||||
1206 | { | ||||
1207 | #if OSL_DEBUG_LEVEL1 > 0 | ||||
1208 | std::vector<SwFrameFormat*>::iterator checkPos = std::find( checkFormats.begin(), checkFormats.end(), pFormat ); | ||||
1209 | assert( checkPos != checkFormats.end())(static_cast <bool> (checkPos != checkFormats.end()) ? void (0) : __assert_fail ("checkPos != checkFormats.end()", "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1209, __extension__ __PRETTY_FUNCTION__)); | ||||
1210 | checkFormats.erase( checkPos ); | ||||
1211 | #endif | ||||
1212 | AppendObj(pFrame, pPage, pFormat, rAnch); | ||||
1213 | } | ||||
1214 | ++it; | ||||
1215 | } | ||||
1216 | |||||
1217 | #if OSL_DEBUG_LEVEL1 > 0 | ||||
1218 | assert( checkFormats.empty())(static_cast <bool> (checkFormats.empty()) ? void (0) : __assert_fail ("checkFormats.empty()", "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1218, __extension__ __PRETTY_FUNCTION__)); | ||||
1219 | #endif | ||||
1220 | } | ||||
1221 | |||||
1222 | |||||
1223 | void AppendObjs(const SwFrameFormats *const pTable, sal_uLong const nIndex, | ||||
1224 | SwFrame *const pFrame, SwPageFrame *const pPage, SwDoc *const pDoc) | ||||
1225 | { | ||||
1226 | if (pFrame->IsTextFrame()) | ||||
1227 | { | ||||
1228 | SwTextFrame const*const pTextFrame(static_cast<SwTextFrame const*>(pFrame)); | ||||
1229 | if (sw::MergedPara const*const pMerged = pTextFrame->GetMergedPara()) | ||||
1230 | { | ||||
1231 | std::vector<sw::Extent>::const_iterator iterFirst(pMerged->extents.begin()); | ||||
1232 | std::vector<sw::Extent>::const_iterator iter(iterFirst); | ||||
1233 | SwTextNode const* pNode(pMerged->pFirstNode); | ||||
1234 | for ( ; ; ++iter) | ||||
1235 | { | ||||
1236 | if (iter == pMerged->extents.end() | ||||
1237 | || iter->pNode != pNode) | ||||
1238 | { | ||||
1239 | AppendObjsOfNode(pTable, pNode->GetIndex(), pFrame, pPage, pDoc, | ||||
1240 | &iterFirst, &iter, pMerged->pFirstNode, pMerged->pLastNode); | ||||
1241 | sal_uLong const until = iter == pMerged->extents.end() | ||||
1242 | ? pMerged->pLastNode->GetIndex() + 1 | ||||
1243 | : iter->pNode->GetIndex(); | ||||
1244 | for (sal_uLong i = pNode->GetIndex() + 1; i < until; ++i) | ||||
1245 | { | ||||
1246 | // let's show at-para flys on nodes that contain start/end of | ||||
1247 | // redline too, even if there's no text there | ||||
1248 | SwNode const*const pTmp(pNode->GetNodes()[i]); | ||||
1249 | if (pTmp->GetRedlineMergeFlag() == SwNode::Merge::NonFirst) | ||||
1250 | { | ||||
1251 | AppendObjsOfNode(pTable, pTmp->GetIndex(), pFrame, pPage, pDoc, &iter, &iter, pMerged->pFirstNode, pMerged->pLastNode); | ||||
1252 | } | ||||
1253 | } | ||||
1254 | if (iter == pMerged->extents.end()) | ||||
1255 | { | ||||
1256 | break; | ||||
1257 | } | ||||
1258 | pNode = iter->pNode; | ||||
1259 | iterFirst = iter; | ||||
1260 | } | ||||
1261 | } | ||||
1262 | } | ||||
1263 | else | ||||
1264 | { | ||||
1265 | return AppendObjsOfNode(pTable, nIndex, pFrame, pPage, pDoc, nullptr, nullptr, nullptr, nullptr); | ||||
1266 | } | ||||
1267 | } | ||||
1268 | else | ||||
1269 | { | ||||
1270 | return AppendObjsOfNode(pTable, nIndex, pFrame, pPage, pDoc, nullptr, nullptr, nullptr, nullptr); | ||||
1271 | } | ||||
1272 | } | ||||
1273 | |||||
1274 | bool IsAnchoredObjShown(SwTextFrame const& rFrame, SwFormatAnchor const& rAnchor) | ||||
1275 | { | ||||
1276 | assert(rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA ||(static_cast <bool> (rAnchor.GetAnchorId() == RndStdIds ::FLY_AT_PARA || rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR || rAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR) ? void ( 0) : __assert_fail ("rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA || rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR || rAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1278, __extension__ __PRETTY_FUNCTION__)) | ||||
1277 | rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR ||(static_cast <bool> (rAnchor.GetAnchorId() == RndStdIds ::FLY_AT_PARA || rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR || rAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR) ? void ( 0) : __assert_fail ("rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA || rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR || rAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1278, __extension__ __PRETTY_FUNCTION__)) | ||||
1278 | rAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR)(static_cast <bool> (rAnchor.GetAnchorId() == RndStdIds ::FLY_AT_PARA || rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR || rAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR) ? void ( 0) : __assert_fail ("rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA || rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR || rAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1278, __extension__ __PRETTY_FUNCTION__)); | ||||
1279 | bool ret(true); | ||||
1280 | if (auto const pMergedPara = rFrame.GetMergedPara()) | ||||
1281 | { | ||||
1282 | ret = false; | ||||
1283 | auto const pAnchor(rAnchor.GetContentAnchor()); | ||||
1284 | auto iterFirst(pMergedPara->extents.cbegin()); | ||||
1285 | if (iterFirst == pMergedPara->extents.end() | ||||
1286 | && (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA | ||||
1287 | || rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR)) | ||||
1288 | { | ||||
1289 | ret = (&pAnchor->nNode.GetNode() == pMergedPara->pFirstNode | ||||
1290 | && (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA | ||||
1291 | || pAnchor->nContent == 0)) | ||||
1292 | || (&pAnchor->nNode.GetNode() == pMergedPara->pLastNode | ||||
1293 | && (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA | ||||
1294 | || pAnchor->nContent == pMergedPara->pLastNode->Len())); | ||||
1295 | } | ||||
1296 | auto iter(iterFirst); | ||||
1297 | SwTextNode const* pNode(pMergedPara->pFirstNode); | ||||
1298 | for ( ; ; ++iter) | ||||
1299 | { | ||||
1300 | if (iter == pMergedPara->extents.end() | ||||
1301 | || iter->pNode != pNode) | ||||
1302 | { | ||||
1303 | assert(pNode->GetRedlineMergeFlag() != SwNode::Merge::Hidden)(static_cast <bool> (pNode->GetRedlineMergeFlag() != SwNode::Merge::Hidden) ? void (0) : __assert_fail ("pNode->GetRedlineMergeFlag() != SwNode::Merge::Hidden" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1303, __extension__ __PRETTY_FUNCTION__)); | ||||
1304 | if (pNode == &pAnchor->nNode.GetNode()) | ||||
1305 | { | ||||
1306 | ret = IsShown(pNode->GetIndex(), rAnchor, &iterFirst, &iter, | ||||
1307 | pMergedPara->pFirstNode, pMergedPara->pLastNode); | ||||
1308 | break; | ||||
1309 | } | ||||
1310 | if (iter == pMergedPara->extents.end()) | ||||
1311 | { | ||||
1312 | break; | ||||
1313 | } | ||||
1314 | pNode = iter->pNode; | ||||
1315 | if (pAnchor->nNode.GetIndex() < pNode->GetIndex()) | ||||
1316 | { | ||||
1317 | break; | ||||
1318 | } | ||||
1319 | iterFirst = iter; | ||||
1320 | } | ||||
1321 | } | ||||
1322 | } | ||||
1323 | return ret; | ||||
1324 | } | ||||
1325 | |||||
1326 | void AppendAllObjs(const SwFrameFormats* pTable, const SwFrame* pSib) | ||||
1327 | { | ||||
1328 | //Connecting of all Objects, which are described in the SpzTable with the | ||||
1329 | //layout. | ||||
1330 | |||||
1331 | boost::circular_buffer<SwFrameFormat*> vFormatsToConnect(pTable->size()); | ||||
1332 | for(const auto& pFormat : *pTable) | ||||
1333 | { | ||||
1334 | const auto& rAnch = pFormat->GetAnchor(); | ||||
1335 | // Formats can still remain, because we neither use character bound | ||||
1336 | // frames nor objects which are anchored to character bounds. | ||||
1337 | if ((rAnch.GetAnchorId() != RndStdIds::FLY_AT_PAGE) && (rAnch.GetAnchorId() != RndStdIds::FLY_AS_CHAR)) | ||||
1338 | { | ||||
1339 | auto pContentAnchor = rAnch.GetContentAnchor(); | ||||
1340 | // formats in header/footer have no dependencies | ||||
1341 | if(pContentAnchor && pFormat->GetDoc()->IsInHeaderFooter(pContentAnchor->nNode)) | ||||
1342 | pFormat->MakeFrames(); | ||||
1343 | else | ||||
1344 | vFormatsToConnect.push_back(pFormat); | ||||
1345 | } | ||||
1346 | } | ||||
1347 | const SwRootFrame* pRoot = pSib ? pSib->getRootFrame() : nullptr; | ||||
1348 | const SwFrameFormat* pFirstRequeued(nullptr); | ||||
1349 | while(!vFormatsToConnect.empty()) | ||||
1350 | { | ||||
1351 | auto& pFormat = vFormatsToConnect.front(); | ||||
1352 | bool isConnected(false); | ||||
1353 | pFormat->CallSwClientNotify(sw::GetObjectConnectedHint(isConnected, pRoot)); | ||||
1354 | if(!isConnected) | ||||
1355 | { | ||||
1356 | pFormat->MakeFrames(); | ||||
1357 | pFormat->CallSwClientNotify(sw::GetObjectConnectedHint(isConnected, pRoot)); | ||||
1358 | } | ||||
1359 | // do this *before* push_back! the circular_buffer can be "full"! | ||||
1360 | vFormatsToConnect.pop_front(); | ||||
1361 | if (!isConnected) | ||||
1362 | { | ||||
1363 | if(pFirstRequeued == pFormat) | ||||
1364 | // If nothing happens anymore we can stop. | ||||
1365 | break; | ||||
1366 | if(!pFirstRequeued) | ||||
1367 | pFirstRequeued = pFormat; | ||||
1368 | assert(!vFormatsToConnect.full())(static_cast <bool> (!vFormatsToConnect.full()) ? void ( 0) : __assert_fail ("!vFormatsToConnect.full()", "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1368, __extension__ __PRETTY_FUNCTION__)); | ||||
1369 | vFormatsToConnect.push_back(pFormat); | ||||
1370 | } | ||||
1371 | else | ||||
1372 | { | ||||
1373 | pFirstRequeued = nullptr; | ||||
1374 | } | ||||
1375 | } | ||||
1376 | } | ||||
1377 | |||||
1378 | namespace sw { | ||||
1379 | |||||
1380 | void RecreateStartTextFrames(SwTextNode & rNode) | ||||
1381 | { | ||||
1382 | std::vector<SwTextFrame*> frames; | ||||
1383 | SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> aIter(rNode); | ||||
1384 | for (SwTextFrame* pFrame = aIter.First(); pFrame; pFrame = aIter.Next()) | ||||
1385 | { | ||||
1386 | if (pFrame->getRootFrame()->IsHideRedlines()) | ||||
1387 | { | ||||
1388 | frames.push_back(pFrame); | ||||
1389 | } | ||||
1390 | } | ||||
1391 | auto eMode(sw::FrameMode::Existing); | ||||
1392 | for (SwTextFrame * pFrame : frames) | ||||
1393 | { | ||||
1394 | // SplitNode could have moved the original frame to the start node | ||||
1395 | // & created a new one on end, or could have created new frame on | ||||
1396 | // start node... grab start node's frame and recreate MergedPara. | ||||
1397 | SwTextNode & rFirstNode(pFrame->GetMergedPara() | ||||
1398 | ? *pFrame->GetMergedPara()->pFirstNode | ||||
1399 | : rNode); | ||||
1400 | assert(rFirstNode.GetIndex() <= rNode.GetIndex())(static_cast <bool> (rFirstNode.GetIndex() <= rNode. GetIndex()) ? void (0) : __assert_fail ("rFirstNode.GetIndex() <= rNode.GetIndex()" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1400, __extension__ __PRETTY_FUNCTION__)); | ||||
1401 | // clear old one first to avoid DelFrames confusing updates & asserts... | ||||
1402 | pFrame->SetMergedPara(nullptr); | ||||
1403 | pFrame->SetMergedPara(sw::CheckParaRedlineMerge( | ||||
1404 | *pFrame, rFirstNode, eMode)); | ||||
1405 | eMode = sw::FrameMode::New; // Existing is not idempotent! | ||||
1406 | // note: this may or may not delete frames on the end node | ||||
1407 | } | ||||
1408 | } | ||||
1409 | |||||
1410 | } // namespace sw | ||||
1411 | |||||
1412 | /** local method to set 'working' position for newly inserted frames | ||||
1413 | |||||
1414 | OD 12.08.2003 #i17969# | ||||
1415 | */ | ||||
1416 | static void lcl_SetPos( SwFrame& _rNewFrame, | ||||
1417 | const SwLayoutFrame& _rLayFrame ) | ||||
1418 | { | ||||
1419 | SwRectFnSet aRectFnSet(&_rLayFrame); | ||||
1420 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(_rNewFrame); | ||||
1421 | aRectFnSet.SetPos( aFrm, aRectFnSet.GetPos(_rLayFrame.getFrameArea()) ); | ||||
1422 | |||||
1423 | // move position by one SwTwip in text flow direction in order to get | ||||
1424 | // notifications for a new calculated position after its formatting. | ||||
1425 | if ( aRectFnSet.IsVert() ) | ||||
1426 | { | ||||
1427 | aFrm.Pos().AdjustX( -1 ); | ||||
1428 | } | ||||
1429 | else | ||||
1430 | { | ||||
1431 | aFrm.Pos().AdjustY(1 ); | ||||
1432 | } | ||||
1433 | } | ||||
1434 | |||||
1435 | void InsertCnt_( SwLayoutFrame *pLay, SwDoc *pDoc, | ||||
1436 | sal_uLong nIndex, bool bPages, sal_uLong nEndIndex, | ||||
1437 | SwFrame *pPrv, sw::FrameMode const eMode ) | ||||
1438 | { | ||||
1439 | pDoc->getIDocumentTimerAccess().BlockIdling(); | ||||
1440 | SwRootFrame* pLayout = pLay->getRootFrame(); | ||||
1441 | const bool bOldCallbackActionEnabled = pLayout && pLayout->IsCallbackActionEnabled(); | ||||
1442 | if( bOldCallbackActionEnabled ) | ||||
1443 | pLayout->SetCallbackActionEnabled( false ); | ||||
1444 | |||||
1445 | //In the generation of the Layout bPages=true will be handed over. | ||||
1446 | //Then will be new pages generated all x paragraphs already times in advance. | ||||
1447 | //On breaks and/or pagedescriptorchanges the corresponding will be generated | ||||
1448 | //immediately. | ||||
1449 | //The advantage is, that on one hand already a nearly realistic number of | ||||
1450 | //pages are created, but above all there are no almost endless long chain | ||||
1451 | //of paragraphs, which must be moved expensively until it reaches a tolerable | ||||
1452 | //reduced level. | ||||
1453 | //We'd like to think that 20 Paragraphs fit on one page. | ||||
1454 | //So that it does not become in extreme situations so violent we calculate depending | ||||
1455 | //on the node something to it. | ||||
1456 | //If in the DocStatistic a usable given pagenumber | ||||
1457 | //(Will be cared for while writing), so it will be presumed that this will be | ||||
1458 | //number of pages. | ||||
1459 | const bool bStartPercent = bPages && !nEndIndex; | ||||
1460 | |||||
1461 | SwPageFrame *pPage = pLay->FindPageFrame(); | ||||
1462 | const SwFrameFormats *pTable = pDoc->GetSpzFrameFormats(); | ||||
1463 | SwFrame *pFrame = nullptr; | ||||
1464 | std::unique_ptr<SwActualSection> pActualSection; | ||||
1465 | std::unique_ptr<SwLayHelper> pPageMaker; | ||||
1466 | |||||
1467 | //If the layout will be created (bPages == true) we do head on the progress | ||||
1468 | //Flys and DrawObjects are not connected immediately, this | ||||
1469 | //happens only at the end of the function. | ||||
1470 | if ( bPages ) | ||||
1471 | { | ||||
1472 | // Attention: the SwLayHelper class uses references to the content-, | ||||
1473 | // page-, layout-frame etc. and may change them! | ||||
1474 | pPageMaker.reset(new SwLayHelper( pDoc, pFrame, pPrv, pPage, pLay, | ||||
1475 | pActualSection, nIndex, 0 == nEndIndex )); | ||||
1476 | if( bStartPercent ) | ||||
1477 | { | ||||
1478 | const sal_uLong nPageCount = pPageMaker->CalcPageCount(); | ||||
1479 | if( nPageCount ) | ||||
1480 | bObjsDirect = false; | ||||
1481 | } | ||||
1482 | } | ||||
1483 | else | ||||
1484 | pPageMaker = nullptr; | ||||
1485 | |||||
1486 | if( pLay->IsInSct() && | ||||
1487 | ( pLay->IsSctFrame() || pLay->GetUpper() ) ) // Hereby will newbies | ||||
1488 | // be intercepted, of which flags could not determined yet, | ||||
1489 | // for e.g. while inserting a table | ||||
1490 | { | ||||
1491 | SwSectionFrame* pSct = pLay->FindSctFrame(); | ||||
1492 | // If content will be inserted in a footnote, which in a column area, | ||||
1493 | // the column area it is not allowed to be broken up. | ||||
1494 | // Only if in the inner of the footnote lies an area, is this a candidate | ||||
1495 | // for pActualSection. | ||||
1496 | // The same applies for areas in tables, if inside the table will be | ||||
1497 | // something inserted, it's only allowed to break up areas, which | ||||
1498 | // lies in the inside also. | ||||
1499 | if( ( !pLay->IsInFootnote() || pSct->IsInFootnote() ) && | ||||
1500 | ( !pLay->IsInTab() || pSct->IsInTab() ) ) | ||||
1501 | { | ||||
1502 | pActualSection.reset(new SwActualSection(nullptr, pSct, pSct->GetSection()->GetFormat()->GetSectionNode())); | ||||
1503 | // tdf#132236 for SwUndoDelete: find outer sections whose start | ||||
1504 | // nodes aren't contained in the range but whose end nodes are, | ||||
1505 | // because section frames may need to be created for them | ||||
1506 | SwActualSection * pUpperSection(pActualSection.get()); | ||||
1507 | while (pUpperSection->GetSectionNode()->EndOfSectionIndex() < nEndIndex) | ||||
1508 | { | ||||
1509 | SwStartNode *const pStart(pUpperSection->GetSectionNode()->StartOfSectionNode()); | ||||
1510 | if (!pStart->IsSectionNode()) | ||||
1511 | { | ||||
1512 | break; | ||||
1513 | } | ||||
1514 | // note: these don't have a section frame, check it in EndNode case! | ||||
1515 | auto const pTmp(new SwActualSection(nullptr, nullptr, static_cast<SwSectionNode*>(pStart))); | ||||
1516 | pUpperSection->SetUpper(pTmp); | ||||
1517 | pUpperSection = pTmp; | ||||
1518 | } | ||||
1519 | OSL_ENSURE( !pLay->Lower() || !pLay->Lower()->IsColumnFrame(),do { if (true && (!(!pLay->Lower() || !pLay->Lower ()->IsColumnFrame()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "1520" ": "), "%s", "InsertCnt_: Wrong Call"); } } while (false) | ||||
1520 | "InsertCnt_: Wrong Call" )do { if (true && (!(!pLay->Lower() || !pLay->Lower ()->IsColumnFrame()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "1520" ": "), "%s", "InsertCnt_: Wrong Call"); } } while (false); | ||||
1521 | } | ||||
1522 | } | ||||
1523 | |||||
1524 | //If a section is "open", the pActualSection points to an SwActualSection. | ||||
1525 | //If the page breaks, for "open" sections a follow will created. | ||||
1526 | //For nested sections (which have, however, not a nested layout), | ||||
1527 | //the SwActualSection class has a member, which points to an upper(section). | ||||
1528 | //When the "inner" section finishes, the upper will used instead. | ||||
1529 | |||||
1530 | // Do not consider the end node. The caller (Section/MakeFrames()) has to | ||||
1531 | // ensure that the end of this range is positioned before EndIndex! | ||||
1532 | for ( ; nEndIndex == 0 || nIndex < nEndIndex; ++nIndex) | ||||
1533 | { | ||||
1534 | SwNode *pNd = pDoc->GetNodes()[nIndex]; | ||||
1535 | if ( pNd->IsContentNode() ) | ||||
1536 | { | ||||
1537 | SwContentNode* pNode = static_cast<SwContentNode*>(pNd); | ||||
1538 | if (pLayout->IsHideRedlines() && !pNd->IsCreateFrameWhenHidingRedlines()) | ||||
1539 | { | ||||
1540 | if (pNd->IsTextNode() | ||||
1541 | && pNd->GetRedlineMergeFlag() == SwNode::Merge::NonFirst) | ||||
1542 | { // must have a frame already | ||||
1543 | assert(static_cast<SwTextFrame*>(pNode->getLayoutFrame(pLayout))->GetMergedPara())(static_cast <bool> (static_cast<SwTextFrame*>(pNode ->getLayoutFrame(pLayout))->GetMergedPara()) ? void (0) : __assert_fail ("static_cast<SwTextFrame*>(pNode->getLayoutFrame(pLayout))->GetMergedPara()" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1543, __extension__ __PRETTY_FUNCTION__)); | ||||
1544 | } | ||||
1545 | continue; // skip it | ||||
1546 | } | ||||
1547 | pFrame = pNode->IsTextNode() | ||||
1548 | ? sw::MakeTextFrame(*pNode->GetTextNode(), pLay, eMode) | ||||
1549 | : pNode->MakeFrame(pLay); | ||||
1550 | if( pPageMaker ) | ||||
1551 | pPageMaker->CheckInsert( nIndex ); | ||||
1552 | |||||
1553 | pFrame->InsertBehind( pLay, pPrv ); | ||||
1554 | // #i27138# | ||||
1555 | // notify accessibility paragraphs objects about changed | ||||
1556 | // CONTENT_FLOWS_FROM/_TO relation. | ||||
1557 | // Relation CONTENT_FLOWS_FROM for next paragraph will change | ||||
1558 | // and relation CONTENT_FLOWS_TO for previous paragraph will change. | ||||
1559 | if ( pFrame->IsTextFrame() ) | ||||
1560 | { | ||||
1561 | SwViewShell* pViewShell( pFrame->getRootFrame()->GetCurrShell() ); | ||||
1562 | // no notification, if <SwViewShell> is in construction | ||||
1563 | if ( pViewShell && !pViewShell->IsInConstructor() && | ||||
1564 | pViewShell->GetLayout() && | ||||
1565 | pViewShell->GetLayout()->IsAnyShellAccessible() && | ||||
1566 | pFrame->FindPageFrame() != nullptr) | ||||
1567 | { | ||||
1568 | pViewShell->InvalidateAccessibleParaFlowRelation( | ||||
1569 | dynamic_cast<SwTextFrame*>(pFrame->FindNextCnt( true )), | ||||
1570 | dynamic_cast<SwTextFrame*>(pFrame->FindPrevCnt()) ); | ||||
1571 | // #i68958# | ||||
1572 | // The information flags of the text frame are validated | ||||
1573 | // in methods <FindNextCnt(..)> and <FindPrevCnt(..)>. | ||||
1574 | // The information flags have to be invalidated, because | ||||
1575 | // it is possible, that the one of its upper frames | ||||
1576 | // isn't inserted into the layout. | ||||
1577 | pFrame->InvalidateInfFlags(); | ||||
1578 | } | ||||
1579 | } | ||||
1580 | // OD 12.08.2003 #i17969# - consider horizontal/vertical layout | ||||
1581 | // for setting position at newly inserted frame | ||||
1582 | lcl_SetPos( *pFrame, *pLay ); | ||||
1583 | pPrv = pFrame; | ||||
1584 | |||||
1585 | if ( !pTable->empty() && bObjsDirect && !bDontCreateObjects ) | ||||
1586 | AppendObjs( pTable, nIndex, pFrame, pPage, pDoc ); | ||||
1587 | } | ||||
1588 | else if ( pNd->IsTableNode() ) | ||||
1589 | { //Should we have encountered a table? | ||||
1590 | SwTableNode *pTableNode = static_cast<SwTableNode*>(pNd); | ||||
1591 | if (pLayout->IsHideRedlines()) | ||||
1592 | { | ||||
1593 | // in the problematic case, there can be only 1 redline... | ||||
1594 | SwPosition const tmp(*pNd); | ||||
1595 | SwRangeRedline const*const pRedline( | ||||
1596 | pDoc->getIDocumentRedlineAccess().GetRedline(tmp, nullptr)); | ||||
1597 | // pathology: redline that starts on a TableNode; cannot | ||||
1598 | // be created in UI but by import filters... | ||||
1599 | if (pRedline | ||||
1600 | && pRedline->GetType() == RedlineType::Delete | ||||
1601 | && &pRedline->Start()->nNode.GetNode() == pNd) | ||||
1602 | { | ||||
1603 | SAL_WARN("sw.pageframe", "skipping table frame creation on bizarre redline")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.pageframe")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "skipping table frame creation on bizarre redline" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.pageframe" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "1603" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "skipping table frame creation on bizarre redline" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "skipping table frame creation on bizarre redline"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.pageframe" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "1603" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "skipping table frame creation on bizarre redline" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.pageframe" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "1603" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "skipping table frame creation on bizarre redline" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "skipping table frame creation on bizarre redline"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.pageframe" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "1603" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||
1604 | while (true) | ||||
1605 | { | ||||
1606 | pTableNode->GetNodes()[nIndex]->SetRedlineMergeFlag(SwNode::Merge::Hidden); | ||||
1607 | if (nIndex == pTableNode->EndOfSectionIndex()) | ||||
1608 | { | ||||
1609 | break; | ||||
1610 | } | ||||
1611 | ++nIndex; | ||||
1612 | } | ||||
1613 | continue; | ||||
1614 | } | ||||
1615 | } | ||||
1616 | if (pLayout->IsHideRedlines() && !pNd->IsCreateFrameWhenHidingRedlines()) | ||||
1617 | { | ||||
1618 | assert(pNd->GetRedlineMergeFlag() == SwNode::Merge::Hidden)(static_cast <bool> (pNd->GetRedlineMergeFlag() == SwNode ::Merge::Hidden) ? void (0) : __assert_fail ("pNd->GetRedlineMergeFlag() == SwNode::Merge::Hidden" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1618, __extension__ __PRETTY_FUNCTION__)); | ||||
1619 | nIndex = pTableNode->EndOfSectionIndex(); | ||||
1620 | continue; // skip it | ||||
1621 | } | ||||
1622 | |||||
1623 | // #108116# loading may produce table structures that GCLines | ||||
1624 | // needs to clean up. To keep table formulas correct, change | ||||
1625 | // all table formulas to internal (BOXPTR) representation. | ||||
1626 | SwTableFormulaUpdate aMsgHint( &pTableNode->GetTable() ); | ||||
1627 | aMsgHint.m_eFlags = TBL_BOXPTR; | ||||
1628 | pDoc->getIDocumentFieldsAccess().UpdateTableFields( &aMsgHint ); | ||||
1629 | pTableNode->GetTable().GCLines(); | ||||
1630 | |||||
1631 | pFrame = pTableNode->MakeFrame( pLay ); | ||||
1632 | |||||
1633 | if( pPageMaker ) | ||||
1634 | pPageMaker->CheckInsert( nIndex ); | ||||
1635 | |||||
1636 | pFrame->InsertBehind( pLay, pPrv ); | ||||
1637 | if (pPage) // would null in SwCellFrame ctor | ||||
1638 | { // tdf#134931 call ResetTurbo(); not sure if Paste() would be | ||||
1639 | pFrame->InvalidatePage(pPage); // better than InsertBehind()? | ||||
1640 | } | ||||
1641 | // #i27138# | ||||
1642 | // notify accessibility paragraphs objects about changed | ||||
1643 | // CONTENT_FLOWS_FROM/_TO relation. | ||||
1644 | // Relation CONTENT_FLOWS_FROM for next paragraph will change | ||||
1645 | // and relation CONTENT_FLOWS_TO for previous paragraph will change. | ||||
1646 | { | ||||
1647 | SwViewShell* pViewShell( pFrame->getRootFrame()->GetCurrShell() ); | ||||
1648 | // no notification, if <SwViewShell> is in construction | ||||
1649 | if ( pViewShell && !pViewShell->IsInConstructor() && | ||||
1650 | pViewShell->GetLayout() && | ||||
1651 | pViewShell->GetLayout()->IsAnyShellAccessible() && | ||||
1652 | pFrame->FindPageFrame() != nullptr) | ||||
1653 | { | ||||
1654 | pViewShell->InvalidateAccessibleParaFlowRelation( | ||||
1655 | dynamic_cast<SwTextFrame*>(pFrame->FindNextCnt( true )), | ||||
1656 | dynamic_cast<SwTextFrame*>(pFrame->FindPrevCnt()) ); | ||||
1657 | } | ||||
1658 | } | ||||
1659 | if ( bObjsDirect && !pTable->empty() ) | ||||
1660 | static_cast<SwTabFrame*>(pFrame)->RegistFlys(); | ||||
1661 | // OD 12.08.2003 #i17969# - consider horizontal/vertical layout | ||||
1662 | // for setting position at newly inserted frame | ||||
1663 | lcl_SetPos( *pFrame, *pLay ); | ||||
1664 | |||||
1665 | pPrv = pFrame; | ||||
1666 | //Set the index to the endnode of the table section. | ||||
1667 | nIndex = pTableNode->EndOfSectionIndex(); | ||||
1668 | |||||
1669 | SwTabFrame* pTmpFrame = static_cast<SwTabFrame*>(pFrame); | ||||
1670 | while ( pTmpFrame ) | ||||
1671 | { | ||||
1672 | pTmpFrame->CheckDirChange(); | ||||
1673 | pTmpFrame = pTmpFrame->IsFollow() ? pTmpFrame->FindMaster() : nullptr; | ||||
1674 | } | ||||
1675 | |||||
1676 | } | ||||
1677 | else if ( pNd->IsSectionNode() ) | ||||
1678 | { | ||||
1679 | if (pLayout->IsHideRedlines() && !pNd->IsCreateFrameWhenHidingRedlines()) | ||||
1680 | { | ||||
1681 | assert(pNd->GetRedlineMergeFlag() == SwNode::Merge::Hidden)(static_cast <bool> (pNd->GetRedlineMergeFlag() == SwNode ::Merge::Hidden) ? void (0) : __assert_fail ("pNd->GetRedlineMergeFlag() == SwNode::Merge::Hidden" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1681, __extension__ __PRETTY_FUNCTION__)); | ||||
1682 | continue; // skip it | ||||
1683 | } | ||||
1684 | SwSectionNode *pNode = static_cast<SwSectionNode*>(pNd); | ||||
1685 | if( pNode->GetSection().CalcHiddenFlag() ) | ||||
1686 | // is hidden, skip the area | ||||
1687 | nIndex = pNode->EndOfSectionIndex(); | ||||
1688 | else | ||||
1689 | { | ||||
1690 | pFrame = pNode->MakeFrame( pLay ); | ||||
1691 | pActualSection.reset( new SwActualSection( pActualSection.release(), | ||||
1692 | static_cast<SwSectionFrame*>(pFrame), pNode ) ); | ||||
1693 | if ( pActualSection->GetUpper() ) | ||||
1694 | { | ||||
1695 | //Insert behind the Upper, the "Follow" of the Upper will be | ||||
1696 | //generated at the EndNode. | ||||
1697 | SwSectionFrame *pTmp = pActualSection->GetUpper()->GetSectionFrame(); | ||||
1698 | pFrame->InsertBehind( pTmp->GetUpper(), pTmp ); | ||||
1699 | // OD 25.03.2003 #108339# - direct initialization of section | ||||
1700 | // after insertion in the layout | ||||
1701 | static_cast<SwSectionFrame*>(pFrame)->Init(); | ||||
1702 | } | ||||
1703 | else | ||||
1704 | { | ||||
1705 | pFrame->InsertBehind( pLay, pPrv ); | ||||
1706 | // OD 25.03.2003 #108339# - direct initialization of section | ||||
1707 | // after insertion in the layout | ||||
1708 | static_cast<SwSectionFrame*>(pFrame)->Init(); | ||||
1709 | |||||
1710 | // #i33963# | ||||
1711 | // Do not trust the IsInFootnote flag. If we are currently | ||||
1712 | // building up a table, the upper of pPrv may be a cell | ||||
1713 | // frame, but the cell frame does not have an upper yet. | ||||
1714 | if( pPrv && nullptr != pPrv->ImplFindFootnoteFrame() ) | ||||
1715 | { | ||||
1716 | if( pPrv->IsSctFrame() ) | ||||
1717 | pPrv = static_cast<SwSectionFrame*>(pPrv)->ContainsContent(); | ||||
1718 | if( pPrv && pPrv->IsTextFrame() ) | ||||
1719 | static_cast<SwTextFrame*>(pPrv)->Prepare( PrepareHint::QuoVadis, nullptr, false ); | ||||
1720 | } | ||||
1721 | } | ||||
1722 | if (nIndex + 1 == nEndIndex) | ||||
1723 | { // tdf#131684 tdf#132236 fix upper of frame moved in | ||||
1724 | // SwUndoDelete; can't be done there unfortunately | ||||
1725 | // because empty section frames are deleted here | ||||
1726 | SwFrame *const pNext( | ||||
1727 | // if there's a parent section, it has been split | ||||
1728 | // into 2 SwSectionFrame already :( | ||||
1729 | ( pFrame->GetNext() | ||||
1730 | && pFrame->GetNext()->IsSctFrame() | ||||
1731 | && pActualSection->GetUpper() | ||||
1732 | && pActualSection->GetUpper()->GetSectionNode() == | ||||
1733 | static_cast<SwSectionFrame const*>(pFrame->GetNext())->GetSection()->GetFormat()->GetSectionNode()) | ||||
1734 | ? static_cast<SwSectionFrame *>(pFrame->GetNext())->ContainsContent() | ||||
1735 | : pFrame->GetNext()); | ||||
1736 | if (pNext | ||||
1737 | && pNext->IsTextFrame() | ||||
1738 | && static_cast<SwTextFrame*>(pNext)->GetTextNodeFirst() == pDoc->GetNodes()[nEndIndex] | ||||
1739 | && (pNext->GetUpper() == pFrame->GetUpper() | ||||
1740 | || pFrame->GetNext()->IsSctFrame())) // checked above | ||||
1741 | { | ||||
1742 | pNext->Cut(); | ||||
1743 | pNext->InvalidateInfFlags(); // mbInfSct changed | ||||
1744 | // could have columns | ||||
1745 | SwSectionFrame *const pSection(static_cast<SwSectionFrame*>(pFrame)); | ||||
1746 | assert(!pSection->Lower() || pSection->Lower()->IsLayoutFrame())(static_cast <bool> (!pSection->Lower() || pSection-> Lower()->IsLayoutFrame()) ? void (0) : __assert_fail ("!pSection->Lower() || pSection->Lower()->IsLayoutFrame()" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1746, __extension__ __PRETTY_FUNCTION__)); | ||||
1747 | SwLayoutFrame *const pParent(pSection->Lower() ? pSection->GetNextLayoutLeaf() : pSection); | ||||
1748 | assert(!pParent->Lower())(static_cast <bool> (!pParent->Lower()) ? void (0) : __assert_fail ("!pParent->Lower()", "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1748, __extension__ __PRETTY_FUNCTION__)); | ||||
1749 | // paste invalidates, section could have indent... | ||||
1750 | pNext->Paste(pParent, nullptr); | ||||
1751 | } | ||||
1752 | } | ||||
1753 | // #i27138# | ||||
1754 | // notify accessibility paragraphs objects about changed | ||||
1755 | // CONTENT_FLOWS_FROM/_TO relation. | ||||
1756 | // Relation CONTENT_FLOWS_FROM for next paragraph will change | ||||
1757 | // and relation CONTENT_FLOWS_TO for previous paragraph will change. | ||||
1758 | { | ||||
1759 | SwViewShell* pViewShell( pFrame->getRootFrame()->GetCurrShell() ); | ||||
1760 | // no notification, if <SwViewShell> is in construction | ||||
1761 | if ( pViewShell && !pViewShell->IsInConstructor() && | ||||
1762 | pViewShell->GetLayout() && | ||||
1763 | pViewShell->GetLayout()->IsAnyShellAccessible() && | ||||
1764 | pFrame->FindPageFrame() != nullptr) | ||||
1765 | { | ||||
1766 | pViewShell->InvalidateAccessibleParaFlowRelation( | ||||
1767 | dynamic_cast<SwTextFrame*>(pFrame->FindNextCnt( true )), | ||||
1768 | dynamic_cast<SwTextFrame*>(pFrame->FindPrevCnt()) ); | ||||
1769 | } | ||||
1770 | } | ||||
1771 | pFrame->CheckDirChange(); | ||||
1772 | |||||
1773 | // OD 12.08.2003 #i17969# - consider horizontal/vertical layout | ||||
1774 | // for setting position at newly inserted frame | ||||
1775 | lcl_SetPos( *pFrame, *pLay ); | ||||
1776 | |||||
1777 | // OD 20.11.2002 #105405# - no page, no invalidate. | ||||
1778 | if ( pPage ) | ||||
1779 | { | ||||
1780 | // OD 18.09.2002 #100522# | ||||
1781 | // invalidate page in order to force format and paint of | ||||
1782 | // inserted section frame | ||||
1783 | pFrame->InvalidatePage( pPage ); | ||||
1784 | |||||
1785 | // FME 10.11.2003 #112243# | ||||
1786 | // Invalidate fly content flag: | ||||
1787 | if ( pFrame->IsInFly() ) | ||||
1788 | pPage->InvalidateFlyContent(); | ||||
1789 | |||||
1790 | // OD 14.11.2002 #104684# - invalidate page content in order to | ||||
1791 | // force format and paint of section content. | ||||
1792 | pPage->InvalidateContent(); | ||||
1793 | } | ||||
1794 | |||||
1795 | pLay = static_cast<SwLayoutFrame*>(pFrame); | ||||
1796 | if ( pLay->Lower() && pLay->Lower()->IsLayoutFrame() ) | ||||
1797 | pLay = pLay->GetNextLayoutLeaf(); | ||||
1798 | pPrv = nullptr; | ||||
1799 | } | ||||
1800 | } | ||||
1801 | else if ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() ) | ||||
1802 | { | ||||
1803 | if (pLayout->IsHideRedlines() && !pNd->IsCreateFrameWhenHidingRedlines()) | ||||
1804 | { | ||||
1805 | assert(pNd->GetRedlineMergeFlag() == SwNode::Merge::Hidden)(static_cast <bool> (pNd->GetRedlineMergeFlag() == SwNode ::Merge::Hidden) ? void (0) : __assert_fail ("pNd->GetRedlineMergeFlag() == SwNode::Merge::Hidden" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1805, __extension__ __PRETTY_FUNCTION__)); | ||||
1806 | continue; // skip it | ||||
1807 | } | ||||
1808 | assert(pActualSection && "Section end without section start?")(static_cast <bool> (pActualSection && "Section end without section start?" ) ? void (0) : __assert_fail ("pActualSection && \"Section end without section start?\"" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1808, __extension__ __PRETTY_FUNCTION__)); | ||||
1809 | assert(pActualSection->GetSectionNode() == pNd->StartOfSectionNode())(static_cast <bool> (pActualSection->GetSectionNode( ) == pNd->StartOfSectionNode()) ? void (0) : __assert_fail ("pActualSection->GetSectionNode() == pNd->StartOfSectionNode()" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1809, __extension__ __PRETTY_FUNCTION__)); | ||||
1810 | |||||
1811 | //Close the section, where appropriate activate the surrounding | ||||
1812 | //section again. | ||||
1813 | pActualSection.reset(pActualSection->GetUpper()); | ||||
1814 | pLay = pLay->FindSctFrame(); | ||||
1815 | if ( pActualSection ) | ||||
1816 | { | ||||
1817 | //Could be, that the last SectionFrame remains empty. | ||||
1818 | //Then now is the time to remove them. | ||||
1819 | if ( !pLay->ContainsContent() ) | ||||
1820 | { | ||||
1821 | SwFrame *pTmpFrame = pLay; | ||||
1822 | pLay = pTmpFrame->GetUpper(); | ||||
1823 | pPrv = pTmpFrame->GetPrev(); | ||||
1824 | pTmpFrame->RemoveFromLayout(); | ||||
1825 | SwFrame::DestroyFrame(pTmpFrame); | ||||
1826 | } | ||||
1827 | else | ||||
1828 | { | ||||
1829 | pPrv = pLay; | ||||
1830 | pLay = pLay->GetUpper(); | ||||
1831 | } | ||||
1832 | |||||
1833 | // new section frame | ||||
1834 | pFrame = pActualSection->GetSectionNode()->MakeFrame( pLay ); | ||||
1835 | pFrame->InsertBehind( pLay, pPrv ); | ||||
1836 | static_cast<SwSectionFrame*>(pFrame)->Init(); | ||||
1837 | |||||
1838 | // OD 12.08.2003 #i17969# - consider horizontal/vertical layout | ||||
1839 | // for setting position at newly inserted frame | ||||
1840 | lcl_SetPos( *pFrame, *pLay ); | ||||
1841 | |||||
1842 | SwSectionFrame* pOuterSectionFrame = pActualSection->GetSectionFrame(); | ||||
1843 | |||||
1844 | // a follow has to be appended to the new section frame | ||||
1845 | SwSectionFrame* pFollow = pOuterSectionFrame ? pOuterSectionFrame->GetFollow() : nullptr; | ||||
1846 | if ( pFollow ) | ||||
1847 | { | ||||
1848 | pOuterSectionFrame->SetFollow( nullptr ); | ||||
1849 | pOuterSectionFrame->InvalidateSize(); | ||||
1850 | static_cast<SwSectionFrame*>(pFrame)->SetFollow( pFollow ); | ||||
1851 | } | ||||
1852 | |||||
1853 | // We don't want to leave empty parts back. | ||||
1854 | if (pOuterSectionFrame && | ||||
1855 | ! pOuterSectionFrame->IsColLocked() && | ||||
1856 | ! pOuterSectionFrame->ContainsContent() ) | ||||
1857 | { | ||||
1858 | pOuterSectionFrame->DelEmpty( true ); | ||||
1859 | SwFrame::DestroyFrame(pOuterSectionFrame); | ||||
1860 | } | ||||
1861 | pActualSection->SetSectionFrame( static_cast<SwSectionFrame*>(pFrame) ); | ||||
1862 | |||||
1863 | pLay = static_cast<SwLayoutFrame*>(pFrame); | ||||
1864 | if ( pLay->Lower() && pLay->Lower()->IsLayoutFrame() ) | ||||
1865 | pLay = pLay->GetNextLayoutLeaf(); | ||||
1866 | pPrv = nullptr; | ||||
1867 | } | ||||
1868 | else | ||||
1869 | { | ||||
1870 | //Nothing more with sections, it goes on right behind | ||||
1871 | //the SectionFrame. | ||||
1872 | pPrv = pLay; | ||||
1873 | pLay = pLay->GetUpper(); | ||||
1874 | } | ||||
1875 | } | ||||
1876 | else if( pNd->IsStartNode() && | ||||
1877 | SwFlyStartNode == static_cast<SwStartNode*>(pNd)->GetStartNodeType() ) | ||||
1878 | { | ||||
1879 | if (pLayout->IsHideRedlines() && !pNd->IsCreateFrameWhenHidingRedlines()) | ||||
1880 | { | ||||
1881 | assert(pNd->GetRedlineMergeFlag() == SwNode::Merge::Hidden)(static_cast <bool> (pNd->GetRedlineMergeFlag() == SwNode ::Merge::Hidden) ? void (0) : __assert_fail ("pNd->GetRedlineMergeFlag() == SwNode::Merge::Hidden" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1881, __extension__ __PRETTY_FUNCTION__)); | ||||
1882 | assert(false)(static_cast <bool> (false) ? void (0) : __assert_fail ( "false", "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1882, __extension__ __PRETTY_FUNCTION__)); // actually a fly-section can't be deleted? | ||||
1883 | continue; // skip it | ||||
1884 | } | ||||
1885 | if ( !pTable->empty() && bObjsDirect && !bDontCreateObjects ) | ||||
1886 | { | ||||
1887 | SwFlyFrame* pFly = pLay->FindFlyFrame(); | ||||
1888 | if( pFly ) | ||||
1889 | AppendObjs( pTable, nIndex, pFly, pPage, pDoc ); | ||||
1890 | } | ||||
1891 | } | ||||
1892 | else | ||||
1893 | { | ||||
1894 | assert(!pLayout->IsHideRedlines()(static_cast <bool> (!pLayout->IsHideRedlines() || pNd ->GetRedlineMergeFlag() != SwNode::Merge::Hidden) ? void ( 0) : __assert_fail ("!pLayout->IsHideRedlines() || pNd->GetRedlineMergeFlag() != SwNode::Merge::Hidden" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1895, __extension__ __PRETTY_FUNCTION__)) | ||||
1895 | || pNd->GetRedlineMergeFlag() != SwNode::Merge::Hidden)(static_cast <bool> (!pLayout->IsHideRedlines() || pNd ->GetRedlineMergeFlag() != SwNode::Merge::Hidden) ? void ( 0) : __assert_fail ("!pLayout->IsHideRedlines() || pNd->GetRedlineMergeFlag() != SwNode::Merge::Hidden" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1895, __extension__ __PRETTY_FUNCTION__)); | ||||
1896 | // Neither Content nor table nor section, so we are done. | ||||
1897 | break; | ||||
1898 | } | ||||
1899 | } | ||||
1900 | |||||
1901 | if ( pActualSection ) | ||||
1902 | { | ||||
1903 | // Might happen that an empty (Follow-)Section is left over. | ||||
1904 | if ( !(pLay = pActualSection->GetSectionFrame())->ContainsContent() ) | ||||
1905 | { | ||||
1906 | pLay->RemoveFromLayout(); | ||||
1907 | SwFrame::DestroyFrame(pLay); | ||||
1908 | } | ||||
1909 | pActualSection.reset(); | ||||
1910 | } | ||||
1911 | |||||
1912 | if ( bPages ) // let the Flys connect to each other | ||||
1913 | { | ||||
1914 | if ( !bDontCreateObjects ) | ||||
1915 | AppendAllObjs( pTable, pLayout ); | ||||
1916 | bObjsDirect = true; | ||||
1917 | } | ||||
1918 | |||||
1919 | if( pPageMaker ) | ||||
1920 | { | ||||
1921 | pPageMaker->CheckFlyCache( pPage ); | ||||
1922 | pPageMaker.reset(); | ||||
1923 | if( pDoc->GetLayoutCache() ) | ||||
1924 | { | ||||
1925 | #ifdef DBG_UTIL | ||||
1926 | pDoc->GetLayoutCache()->CompareLayout( *pDoc ); | ||||
1927 | #endif | ||||
1928 | pDoc->GetLayoutCache()->ClearImpl(); | ||||
1929 | } | ||||
1930 | } | ||||
1931 | |||||
1932 | pDoc->getIDocumentTimerAccess().UnblockIdling(); | ||||
1933 | if( bOldCallbackActionEnabled ) | ||||
1934 | pLayout->SetCallbackActionEnabled( bOldCallbackActionEnabled ); | ||||
1935 | } | ||||
1936 | |||||
1937 | void MakeFrames( SwDoc *pDoc, const SwNodeIndex &rSttIdx, | ||||
1938 | const SwNodeIndex &rEndIdx ) | ||||
1939 | { | ||||
1940 | bObjsDirect = false; | ||||
1941 | |||||
1942 | SwNodeIndex aTmp( rSttIdx ); | ||||
1943 | sal_uLong nEndIdx = rEndIdx.GetIndex(); | ||||
1944 | SwNode* pNd = pDoc->GetNodes().FindPrvNxtFrameNode( aTmp, | ||||
1945 | pDoc->GetNodes()[ nEndIdx-1 ]); | ||||
1946 | if ( pNd ) | ||||
1947 | { | ||||
1948 | bool bApres = aTmp < rSttIdx; | ||||
1949 | SwNode2Layout aNode2Layout( *pNd, rSttIdx.GetIndex() ); | ||||
1950 | SwFrame* pFrame; | ||||
1951 | sw::FrameMode eMode = sw::FrameMode::Existing; | ||||
1952 | while( nullptr != (pFrame = aNode2Layout.NextFrame()) ) | ||||
1953 | { | ||||
1954 | SwLayoutFrame *pUpper = pFrame->GetUpper(); | ||||
1955 | SwFootnoteFrame* pFootnoteFrame = pUpper->FindFootnoteFrame(); | ||||
1956 | bool bOldLock, bOldFootnote; | ||||
1957 | if( pFootnoteFrame ) | ||||
1958 | { | ||||
1959 | bOldFootnote = pFootnoteFrame->IsColLocked(); | ||||
1960 | pFootnoteFrame->ColLock(); | ||||
1961 | } | ||||
1962 | else | ||||
1963 | bOldFootnote = true; | ||||
1964 | SwSectionFrame* pSct = pUpper->FindSctFrame(); | ||||
1965 | // Inside of footnotes only those areas are interesting that are inside of them. But | ||||
1966 | // not the ones (e.g. column areas) in which are the footnote containers positioned. | ||||
1967 | // #109767# Table frame is in section, insert section in cell frame. | ||||
1968 | if( pSct && ((pFootnoteFrame && !pSct->IsInFootnote()) || pUpper->IsCellFrame()) ) | ||||
1969 | pSct = nullptr; | ||||
1970 | if( pSct ) | ||||
1971 | { // to prevent pTmp->MoveFwd from destroying the SectionFrame | ||||
1972 | bOldLock = pSct->IsColLocked(); | ||||
1973 | pSct->ColLock(); | ||||
1974 | } | ||||
1975 | else | ||||
1976 | bOldLock = true; | ||||
1977 | |||||
1978 | // If pFrame cannot be moved, it is not possible to move it to the next page. This applies | ||||
1979 | // also for frames (in the first column of a frame pFrame is moveable) and column | ||||
1980 | // sections of tables (also here pFrame is moveable). | ||||
1981 | bool bMoveNext = nEndIdx - rSttIdx.GetIndex() > 120; | ||||
1982 | bool bAllowMove = !pFrame->IsInFly() && pFrame->IsMoveable() && | ||||
1983 | (!pFrame->IsInTab() || pFrame->IsTabFrame() ); | ||||
1984 | if ( bMoveNext && bAllowMove ) | ||||
1985 | { | ||||
1986 | SwFrame *pMove = pFrame; | ||||
1987 | SwFrame *pPrev = pFrame->GetPrev(); | ||||
1988 | SwFlowFrame *pTmp = SwFlowFrame::CastFlowFrame( pMove ); | ||||
1989 | assert(pTmp)(static_cast <bool> (pTmp) ? void (0) : __assert_fail ( "pTmp", "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1989, __extension__ __PRETTY_FUNCTION__)); | ||||
1990 | |||||
1991 | if ( bApres ) | ||||
1992 | { | ||||
1993 | // The rest of this page should be empty. Thus, the following one has to move to | ||||
1994 | // the next page (it might also be located in the following column). | ||||
1995 | assert(!pTmp->HasFollow() && "prev. node's frame is not last")(static_cast <bool> (!pTmp->HasFollow() && "prev. node's frame is not last" ) ? void (0) : __assert_fail ("!pTmp->HasFollow() && \"prev. node's frame is not last\"" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1995, __extension__ __PRETTY_FUNCTION__)); | ||||
1996 | pPrev = pFrame; | ||||
1997 | // If the surrounding SectionFrame has a "next" one, | ||||
1998 | // so this one needs to be moved as well. | ||||
1999 | pMove = pFrame->GetIndNext(); | ||||
2000 | SwColumnFrame* pCol = static_cast<SwColumnFrame*>(pFrame->FindColFrame()); | ||||
2001 | if( pCol ) | ||||
2002 | pCol = static_cast<SwColumnFrame*>(pCol->GetNext()); | ||||
2003 | do | ||||
2004 | { | ||||
2005 | if( pCol && !pMove ) | ||||
2006 | { // No successor so far, look into the next column | ||||
2007 | pMove = pCol->ContainsAny(); | ||||
2008 | if( pCol->GetNext() ) | ||||
2009 | pCol = static_cast<SwColumnFrame*>(pCol->GetNext()); | ||||
2010 | else if( pCol->IsInSct() ) | ||||
2011 | { // If there is no following column but we are in a column frame, | ||||
2012 | // there might be (page) columns outside of it. | ||||
2013 | pCol = static_cast<SwColumnFrame*>(pCol->FindSctFrame()->FindColFrame()); | ||||
2014 | if( pCol ) | ||||
2015 | pCol = static_cast<SwColumnFrame*>(pCol->GetNext()); | ||||
2016 | } | ||||
2017 | else | ||||
2018 | pCol = nullptr; | ||||
2019 | } | ||||
2020 | // skip invalid SectionFrames | ||||
2021 | while( pMove && pMove->IsSctFrame() && | ||||
2022 | !static_cast<SwSectionFrame*>(pMove)->GetSection() ) | ||||
2023 | pMove = pMove->GetNext(); | ||||
2024 | } while( !pMove && pCol ); | ||||
2025 | |||||
2026 | if( pMove ) | ||||
2027 | { | ||||
2028 | if ( pMove->IsContentFrame() ) | ||||
2029 | pTmp = static_cast<SwContentFrame*>(pMove); | ||||
2030 | else if ( pMove->IsTabFrame() ) | ||||
2031 | pTmp = static_cast<SwTabFrame*>(pMove); | ||||
2032 | else if ( pMove->IsSctFrame() ) | ||||
2033 | { | ||||
2034 | pMove = static_cast<SwSectionFrame*>(pMove)->ContainsAny(); | ||||
2035 | if( pMove ) | ||||
2036 | pTmp = SwFlowFrame::CastFlowFrame( pMove ); | ||||
2037 | else | ||||
2038 | pTmp = nullptr; | ||||
2039 | } | ||||
2040 | } | ||||
2041 | else | ||||
2042 | pTmp = nullptr; | ||||
2043 | } | ||||
2044 | else | ||||
2045 | { | ||||
2046 | assert(!pTmp->IsFollow() && "next node's frame is not master")(static_cast <bool> (!pTmp->IsFollow() && "next node's frame is not master" ) ? void (0) : __assert_fail ("!pTmp->IsFollow() && \"next node's frame is not master\"" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 2046, __extension__ __PRETTY_FUNCTION__)); | ||||
2047 | // move the _content_ of a section frame | ||||
2048 | if( pMove->IsSctFrame() ) | ||||
2049 | { | ||||
2050 | while( pMove && pMove->IsSctFrame() && | ||||
2051 | !static_cast<SwSectionFrame*>(pMove)->GetSection() ) | ||||
2052 | pMove = pMove->GetNext(); | ||||
2053 | if( pMove && pMove->IsSctFrame() ) | ||||
2054 | pMove = static_cast<SwSectionFrame*>(pMove)->ContainsAny(); | ||||
2055 | if( pMove ) | ||||
2056 | pTmp = SwFlowFrame::CastFlowFrame( pMove ); | ||||
2057 | else | ||||
2058 | pTmp = nullptr; | ||||
2059 | } | ||||
2060 | } | ||||
2061 | |||||
2062 | if( pTmp ) | ||||
2063 | { | ||||
2064 | SwFrame* pOldUp = pTmp->GetFrame().GetUpper(); | ||||
2065 | // MoveFwd==true means that we are still on the same page. | ||||
2066 | // But since we want to move if possible! | ||||
2067 | bool bTmpOldLock = pTmp->IsJoinLocked(); | ||||
2068 | pTmp->LockJoin(); | ||||
2069 | while( pTmp->MoveFwd( true, false, true ) ) | ||||
2070 | { | ||||
2071 | if( pOldUp == pTmp->GetFrame().GetUpper() ) | ||||
2072 | break; | ||||
2073 | pOldUp = pTmp->GetFrame().GetUpper(); | ||||
2074 | } | ||||
2075 | if( !bTmpOldLock ) | ||||
2076 | pTmp->UnlockJoin(); | ||||
2077 | } | ||||
2078 | ::InsertCnt_( pUpper, pDoc, rSttIdx.GetIndex(), | ||||
2079 | pFrame->IsInDocBody(), nEndIdx, pPrev, eMode ); | ||||
2080 | } | ||||
2081 | else | ||||
2082 | { | ||||
2083 | bool bSplit; | ||||
2084 | SwFrame* pPrv = bApres ? pFrame : pFrame->GetPrev(); | ||||
2085 | // If the section frame is inserted into another one, it must be split. | ||||
2086 | if( pSct && rSttIdx.GetNode().IsSectionNode() ) | ||||
2087 | { | ||||
2088 | bSplit = pSct->SplitSect( pFrame, bApres ); | ||||
2089 | if( !bSplit && !bApres ) | ||||
2090 | { | ||||
2091 | pUpper = pSct->GetUpper(); | ||||
2092 | pPrv = pSct->GetPrev(); | ||||
2093 | } | ||||
2094 | } | ||||
2095 | else | ||||
2096 | bSplit = false; | ||||
2097 | |||||
2098 | ::InsertCnt_( pUpper, pDoc, rSttIdx.GetIndex(), false, | ||||
2099 | nEndIdx, pPrv, eMode ); | ||||
2100 | // OD 23.06.2003 #108784# - correction: append objects doesn't | ||||
2101 | // depend on value of <bAllowMove> | ||||
2102 | if( !bDontCreateObjects ) | ||||
2103 | { | ||||
2104 | const SwFrameFormats *pTable = pDoc->GetSpzFrameFormats(); | ||||
2105 | if( !pTable->empty() ) | ||||
2106 | AppendAllObjs( pTable, pUpper ); | ||||
2107 | } | ||||
2108 | |||||
2109 | // If nothing was added (e.g. a hidden section), the split must be reversed. | ||||
2110 | if( bSplit && pSct && pSct->GetNext() | ||||
2111 | && pSct->GetNext()->IsSctFrame() ) | ||||
2112 | pSct->MergeNext( static_cast<SwSectionFrame*>(pSct->GetNext()) ); | ||||
2113 | if( pFrame->IsInFly() ) | ||||
2114 | pFrame->FindFlyFrame()->Invalidate_(); | ||||
2115 | if( pFrame->IsInTab() ) | ||||
2116 | pFrame->InvalidateSize(); | ||||
2117 | } | ||||
2118 | |||||
2119 | SwPageFrame *pPage = pUpper->FindPageFrame(); | ||||
2120 | SwFrame::CheckPageDescs( pPage, false ); | ||||
2121 | if( !bOldFootnote ) | ||||
2122 | pFootnoteFrame->ColUnlock(); | ||||
2123 | if( !bOldLock ) | ||||
2124 | { | ||||
2125 | pSct->ColUnlock(); | ||||
2126 | // pSct might be empty (e.g. when inserting linked section containing further | ||||
2127 | // sections) and can be destroyed in such cases. | ||||
2128 | if( !pSct->ContainsContent() ) | ||||
2129 | { | ||||
2130 | pSct->DelEmpty( true ); | ||||
2131 | pUpper->getRootFrame()->RemoveFromList( pSct ); | ||||
2132 | SwFrame::DestroyFrame(pSct); | ||||
2133 | } | ||||
2134 | } | ||||
2135 | eMode = sw::FrameMode::New; // use Existing only once! | ||||
2136 | } | ||||
2137 | } | ||||
2138 | |||||
2139 | bObjsDirect = true; | ||||
2140 | } | ||||
2141 | |||||
2142 | SwBorderAttrs::SwBorderAttrs(const SwModify *pMod, const SwFrame *pConstructor) | ||||
2143 | : SwCacheObj(pMod) | ||||
2144 | , m_rAttrSet(pConstructor->IsContentFrame() | ||||
2145 | ? pConstructor->IsTextFrame() | ||||
2146 | ? static_cast<const SwTextFrame*>(pConstructor)->GetTextNodeForParaProps()->GetSwAttrSet() | ||||
2147 | : static_cast<const SwNoTextFrame*>(pConstructor)->GetNode()->GetSwAttrSet() | ||||
2148 | : static_cast<const SwLayoutFrame*>(pConstructor)->GetFormat()->GetAttrSet()) | ||||
2149 | , m_rUL(m_rAttrSet.GetULSpace()) | ||||
2150 | // #i96772# | ||||
2151 | // LRSpaceItem is copied due to the possibility that it is adjusted - see below | ||||
2152 | , m_rLR(m_rAttrSet.GetLRSpace().Clone()) | ||||
2153 | , m_rBox(m_rAttrSet.GetBox()) | ||||
2154 | , m_rShadow(m_rAttrSet.GetShadow()) | ||||
2155 | , m_aFrameSize(m_rAttrSet.GetFrameSize().GetSize()) | ||||
2156 | , m_bIsLine(false) | ||||
2157 | , m_bJoinedWithPrev(false) | ||||
2158 | , m_bJoinedWithNext(false) | ||||
2159 | , m_nTopLine(0) | ||||
2160 | , m_nBottomLine(0) | ||||
2161 | , m_nLeftLine(0) | ||||
2162 | , m_nRightLine(0) | ||||
2163 | , m_nTop(0) | ||||
2164 | , m_nBottom(0) | ||||
2165 | , m_nGetTopLine(0) | ||||
2166 | , m_nGetBottomLine(0) | ||||
2167 | , m_nLineSpacing(0) | ||||
2168 | { | ||||
2169 | // #i96772# | ||||
2170 | const SwTextFrame* pTextFrame = dynamic_cast<const SwTextFrame*>(pConstructor); | ||||
2171 | if ( pTextFrame ) | ||||
2172 | { | ||||
2173 | pTextFrame->GetTextNodeForParaProps()->ClearLRSpaceItemDueToListLevelIndents( m_rLR ); | ||||
2174 | } | ||||
2175 | else if ( pConstructor->IsNoTextFrame() ) | ||||
2176 | { | ||||
2177 | m_rLR = std::make_shared<SvxLRSpaceItem>(RES_LR_SPACE); | ||||
2178 | } | ||||
2179 | |||||
2180 | // Caution: The USHORTs for the cached values are not initialized by intention! | ||||
2181 | |||||
2182 | // everything needs to be calculated at least once: | ||||
2183 | m_bTopLine = m_bBottomLine = m_bLeftLine = m_bRightLine = | ||||
2184 | m_bTop = m_bBottom = m_bLine = true; | ||||
2185 | |||||
2186 | // except this one: calculate line spacing before cell border only for text frames | ||||
2187 | m_bLineSpacing = bool(pTextFrame); | ||||
2188 | |||||
2189 | m_bCacheGetLine = m_bCachedGetTopLine = m_bCachedGetBottomLine = false; | ||||
2190 | // OD 21.05.2003 #108789# - init cache status for values <m_bJoinedWithPrev> | ||||
2191 | // and <m_bJoinedWithNext>, which aren't initialized by default. | ||||
2192 | m_bCachedJoinedWithPrev = false; | ||||
2193 | m_bCachedJoinedWithNext = false; | ||||
2194 | } | ||||
2195 | |||||
2196 | SwBorderAttrs::~SwBorderAttrs() | ||||
2197 | { | ||||
2198 | const_cast<SwModify *>(static_cast<SwModify const *>(m_pOwner))->SetInCache( false ); | ||||
2199 | } | ||||
2200 | |||||
2201 | /* All calc methods calculate a safety distance in addition to the values given by the attributes. | ||||
2202 | * This safety distance is only added when working with borders and/or shadows to prevent that | ||||
2203 | * e.g. borders are painted over. | ||||
2204 | */ | ||||
2205 | |||||
2206 | void SwBorderAttrs::CalcTop_() | ||||
2207 | { | ||||
2208 | m_nTop = CalcTopLine() + m_rUL.GetUpper(); | ||||
2209 | m_bTop = false; | ||||
2210 | } | ||||
2211 | |||||
2212 | void SwBorderAttrs::CalcBottom_() | ||||
2213 | { | ||||
2214 | m_nBottom = CalcBottomLine() + m_rUL.GetLower(); | ||||
2215 | m_bBottom = false; | ||||
2216 | } | ||||
2217 | |||||
2218 | long SwBorderAttrs::CalcRight( const SwFrame* pCaller ) const | ||||
2219 | { | ||||
2220 | long nRight=0; | ||||
2221 | |||||
2222 | if (!pCaller->IsTextFrame() || !static_cast<const SwTextFrame*>(pCaller)->GetDoc().GetDocumentSettingManager().get(DocumentSettingId::INVERT_BORDER_SPACING)) { | ||||
2223 | // OD 23.01.2003 #106895# - for cell frame in R2L text direction the left | ||||
2224 | // and right border are painted on the right respectively left. | ||||
2225 | if ( pCaller->IsCellFrame() && pCaller->IsRightToLeft() ) | ||||
2226 | nRight = CalcLeftLine(); | ||||
2227 | else | ||||
2228 | nRight = CalcRightLine(); | ||||
2229 | |||||
2230 | } | ||||
2231 | // for paragraphs, "left" is "before text" and "right" is "after text" | ||||
2232 | if ( pCaller->IsTextFrame() && pCaller->IsRightToLeft() ) | ||||
2233 | nRight += m_rLR->GetLeft(); | ||||
2234 | else | ||||
2235 | nRight += m_rLR->GetRight(); | ||||
2236 | |||||
2237 | // correction: retrieve left margin for numbering in R2L-layout | ||||
2238 | if ( pCaller->IsTextFrame() && pCaller->IsRightToLeft() ) | ||||
2239 | { | ||||
2240 | nRight += static_cast<const SwTextFrame*>(pCaller)->GetTextNodeForParaProps()->GetLeftMarginWithNum(); | ||||
2241 | } | ||||
2242 | |||||
2243 | return nRight; | ||||
2244 | } | ||||
2245 | |||||
2246 | /// Tries to detect if this paragraph has a floating table attached. | ||||
2247 | static bool lcl_hasTabFrame(const SwTextFrame* pTextFrame) | ||||
2248 | { | ||||
2249 | if (pTextFrame->GetDrawObjs()) | ||||
2250 | { | ||||
2251 | const SwSortedObjs* pSortedObjs = pTextFrame->GetDrawObjs(); | ||||
2252 | if (pSortedObjs->size() > 0) | ||||
2253 | { | ||||
2254 | SwAnchoredObject* pObject = (*pSortedObjs)[0]; | ||||
2255 | if (dynamic_cast<const SwFlyFrame*>(pObject) != nullptr) | ||||
2256 | { | ||||
2257 | SwFlyFrame* pFly = static_cast<SwFlyFrame*>(pObject); | ||||
2258 | if (pFly->Lower() && pFly->Lower()->IsTabFrame()) | ||||
2259 | return true; | ||||
2260 | } | ||||
2261 | } | ||||
2262 | } | ||||
2263 | return false; | ||||
2264 | } | ||||
2265 | |||||
2266 | long SwBorderAttrs::CalcLeft( const SwFrame *pCaller ) const | ||||
2267 | { | ||||
2268 | long nLeft=0; | ||||
2269 | |||||
2270 | if (!pCaller->IsTextFrame() || !static_cast<const SwTextFrame*>(pCaller)->GetDoc().GetDocumentSettingManager().get(DocumentSettingId::INVERT_BORDER_SPACING)) | ||||
2271 | { | ||||
2272 | // OD 23.01.2003 #106895# - for cell frame in R2L text direction the left | ||||
2273 | // and right border are painted on the right respectively left. | ||||
2274 | if ( pCaller->IsCellFrame() && pCaller->IsRightToLeft() ) | ||||
2275 | nLeft = CalcRightLine(); | ||||
2276 | else | ||||
2277 | nLeft = CalcLeftLine(); | ||||
2278 | } | ||||
2279 | |||||
2280 | // for paragraphs, "left" is "before text" and "right" is "after text" | ||||
2281 | if ( pCaller->IsTextFrame() && pCaller->IsRightToLeft() ) | ||||
2282 | nLeft += m_rLR->GetRight(); | ||||
2283 | else | ||||
2284 | { | ||||
2285 | bool bIgnoreMargin = false; | ||||
2286 | if (pCaller->IsTextFrame()) | ||||
2287 | { | ||||
2288 | const SwTextFrame* pTextFrame = static_cast<const SwTextFrame*>(pCaller); | ||||
2289 | if (pTextFrame->GetDoc().GetDocumentSettingManager().get(DocumentSettingId::FLOATTABLE_NOMARGINS)) | ||||
2290 | { | ||||
2291 | // If this is explicitly requested, ignore the margins next to the floating table. | ||||
2292 | if (lcl_hasTabFrame(pTextFrame)) | ||||
2293 | bIgnoreMargin = true; | ||||
2294 | // TODO here we only handle the first two paragraphs, would be nice to generalize this. | ||||
2295 | else if (pTextFrame->FindPrev() && pTextFrame->FindPrev()->IsTextFrame() && lcl_hasTabFrame(static_cast<const SwTextFrame*>(pTextFrame->FindPrev()))) | ||||
2296 | bIgnoreMargin = true; | ||||
2297 | } | ||||
2298 | } | ||||
2299 | if (!bIgnoreMargin) | ||||
2300 | nLeft += m_rLR->GetLeft(); | ||||
2301 | } | ||||
2302 | |||||
2303 | // correction: do not retrieve left margin for numbering in R2L-layout | ||||
2304 | if ( pCaller->IsTextFrame() && !pCaller->IsRightToLeft() ) | ||||
2305 | { | ||||
2306 | nLeft += static_cast<const SwTextFrame*>(pCaller)->GetTextNodeForParaProps()->GetLeftMarginWithNum(); | ||||
2307 | } | ||||
2308 | |||||
2309 | return nLeft; | ||||
2310 | } | ||||
2311 | |||||
2312 | /* Calculated values for borders and shadows. | ||||
2313 | * It might be that a distance is wanted even without lines. This will be | ||||
2314 | * considered here and not by the attribute (e.g. bBorderDist for cells). | ||||
2315 | */ | ||||
2316 | |||||
2317 | void SwBorderAttrs::CalcTopLine_() | ||||
2318 | { | ||||
2319 | m_nTopLine = m_rBox.CalcLineSpace( SvxBoxItemLine::TOP, /*bEvenIfNoLine*/true ); | ||||
2320 | m_nTopLine = m_nTopLine + m_rShadow.CalcShadowSpace(SvxShadowItemSide::TOP); | ||||
2321 | m_bTopLine = false; | ||||
2322 | } | ||||
2323 | |||||
2324 | void SwBorderAttrs::CalcBottomLine_() | ||||
2325 | { | ||||
2326 | m_nBottomLine = m_rBox.CalcLineSpace( SvxBoxItemLine::BOTTOM, true ); | ||||
2327 | m_nBottomLine = m_nBottomLine + m_rShadow.CalcShadowSpace(SvxShadowItemSide::BOTTOM); | ||||
2328 | m_bBottomLine = false; | ||||
2329 | } | ||||
2330 | |||||
2331 | void SwBorderAttrs::CalcLeftLine_() | ||||
2332 | { | ||||
2333 | m_nLeftLine = m_rBox.CalcLineSpace( SvxBoxItemLine::LEFT, true); | ||||
2334 | m_nLeftLine = m_nLeftLine + m_rShadow.CalcShadowSpace(SvxShadowItemSide::LEFT); | ||||
2335 | m_bLeftLine = false; | ||||
2336 | } | ||||
2337 | |||||
2338 | void SwBorderAttrs::CalcRightLine_() | ||||
2339 | { | ||||
2340 | m_nRightLine = m_rBox.CalcLineSpace( SvxBoxItemLine::RIGHT, true ); | ||||
2341 | m_nRightLine = m_nRightLine + m_rShadow.CalcShadowSpace(SvxShadowItemSide::RIGHT); | ||||
2342 | m_bRightLine = false; | ||||
2343 | } | ||||
2344 | |||||
2345 | void SwBorderAttrs::IsLine_() | ||||
2346 | { | ||||
2347 | m_bIsLine = m_rBox.GetTop() || m_rBox.GetBottom() || | ||||
2348 | m_rBox.GetLeft()|| m_rBox.GetRight(); | ||||
2349 | m_bLine = false; | ||||
2350 | } | ||||
2351 | |||||
2352 | /* The borders of neighboring paragraphs are condensed by following algorithm: | ||||
2353 | * | ||||
2354 | * 1. No top border if the predecessor has the same top border and (3) applies. | ||||
2355 | * In addition, the paragraph needs to have a border at least one side (left/right/bottom). | ||||
2356 | * 2. No bottom border if the successor has the same bottom border and (3) applies. | ||||
2357 | * In addition, the paragraph needs to have a border at least one side (left/right/top). | ||||
2358 | * 3. The borders on the left and right side are identical between the current and the | ||||
2359 | * pre-/succeeding paragraph. | ||||
2360 | */ | ||||
2361 | |||||
2362 | static bool CmpLines( const editeng::SvxBorderLine *pL1, const editeng::SvxBorderLine *pL2 ) | ||||
2363 | { | ||||
2364 | return ( ((pL1 && pL2) && (*pL1 == *pL2)) || (!pL1 && !pL2) ); | ||||
2365 | } | ||||
2366 | |||||
2367 | // OD 21.05.2003 #108789# - change name of 1st parameter - "rAttrs" -> "rCmpAttrs" | ||||
2368 | // OD 21.05.2003 #108789# - compare <CalcRight()> and <rCmpAttrs.CalcRight()> | ||||
2369 | // instead of only the right LR-spacing, because R2L-layout has to be | ||||
2370 | // considered. | ||||
2371 | bool SwBorderAttrs::CmpLeftRight( const SwBorderAttrs &rCmpAttrs, | ||||
2372 | const SwFrame *pCaller, | ||||
2373 | const SwFrame *pCmp ) const | ||||
2374 | { | ||||
2375 | return ( CmpLines( rCmpAttrs.GetBox().GetLeft(), GetBox().GetLeft() ) && | ||||
2376 | CmpLines( rCmpAttrs.GetBox().GetRight(),GetBox().GetRight() ) && | ||||
2377 | CalcLeft( pCaller ) == rCmpAttrs.CalcLeft( pCmp ) && | ||||
2378 | // OD 21.05.2003 #108789# - compare <CalcRight> with <rCmpAttrs.CalcRight>. | ||||
2379 | CalcRight( pCaller ) == rCmpAttrs.CalcRight( pCmp ) ); | ||||
2380 | } | ||||
2381 | |||||
2382 | bool SwBorderAttrs::JoinWithCmp( const SwFrame& _rCallerFrame, | ||||
2383 | const SwFrame& _rCmpFrame ) const | ||||
2384 | { | ||||
2385 | bool bReturnVal = false; | ||||
2386 | |||||
2387 | SwBorderAttrAccess aCmpAccess( SwFrame::GetCache(), &_rCmpFrame ); | ||||
2388 | const SwBorderAttrs &rCmpAttrs = *aCmpAccess.Get(); | ||||
2389 | if ( m_rShadow == rCmpAttrs.GetShadow() && | ||||
2390 | CmpLines( m_rBox.GetTop(), rCmpAttrs.GetBox().GetTop() ) && | ||||
2391 | CmpLines( m_rBox.GetBottom(), rCmpAttrs.GetBox().GetBottom() ) && | ||||
2392 | CmpLeftRight( rCmpAttrs, &_rCallerFrame, &_rCmpFrame ) | ||||
2393 | ) | ||||
2394 | { | ||||
2395 | bReturnVal = true; | ||||
2396 | } | ||||
2397 | |||||
2398 | return bReturnVal; | ||||
2399 | } | ||||
2400 | |||||
2401 | // OD 21.05.2003 #108789# - method to determine, if borders are joined with | ||||
2402 | // previous frame. Calculated value saved in cached value <m_bJoinedWithPrev> | ||||
2403 | // OD 2004-02-26 #i25029# - add 2nd parameter <_pPrevFrame> | ||||
2404 | void SwBorderAttrs::CalcJoinedWithPrev( const SwFrame& _rFrame, | ||||
2405 | const SwFrame* _pPrevFrame ) | ||||
2406 | { | ||||
2407 | // set default | ||||
2408 | m_bJoinedWithPrev = false; | ||||
2409 | |||||
2410 | if ( _rFrame.IsTextFrame() ) | ||||
2411 | { | ||||
2412 | // text frame can potentially join with previous text frame, if | ||||
2413 | // corresponding attribute set is set at previous text frame. | ||||
2414 | // OD 2004-02-26 #i25029# - If parameter <_pPrevFrame> is set, take this | ||||
2415 | // one as previous frame. | ||||
2416 | const SwFrame* pPrevFrame = _pPrevFrame ? _pPrevFrame : _rFrame.GetPrev(); | ||||
2417 | // OD 2004-02-13 #i25029# - skip hidden text frames. | ||||
2418 | while ( pPrevFrame && pPrevFrame->IsTextFrame() && | ||||
2419 | static_cast<const SwTextFrame*>(pPrevFrame)->IsHiddenNow() ) | ||||
2420 | { | ||||
2421 | pPrevFrame = pPrevFrame->GetPrev(); | ||||
2422 | } | ||||
2423 | if ( pPrevFrame && pPrevFrame->IsTextFrame() && | ||||
2424 | pPrevFrame->GetAttrSet()->GetParaConnectBorder().GetValue() | ||||
2425 | ) | ||||
2426 | { | ||||
2427 | m_bJoinedWithPrev = JoinWithCmp( _rFrame, *pPrevFrame ); | ||||
2428 | } | ||||
2429 | } | ||||
2430 | |||||
2431 | // valid cache status, if demanded | ||||
2432 | // OD 2004-02-26 #i25029# - Do not validate cache, if parameter <_pPrevFrame> | ||||
2433 | // is set. | ||||
2434 | m_bCachedJoinedWithPrev = m_bCacheGetLine && !_pPrevFrame; | ||||
2435 | } | ||||
2436 | |||||
2437 | // OD 21.05.2003 #108789# - method to determine, if borders are joined with | ||||
2438 | // next frame. Calculated value saved in cached value <m_bJoinedWithNext> | ||||
2439 | void SwBorderAttrs::CalcJoinedWithNext( const SwFrame& _rFrame ) | ||||
2440 | { | ||||
2441 | // set default | ||||
2442 | m_bJoinedWithNext = false; | ||||
2443 | |||||
2444 | if ( _rFrame.IsTextFrame() ) | ||||
2445 | { | ||||
2446 | // text frame can potentially join with next text frame, if | ||||
2447 | // corresponding attribute set is set at current text frame. | ||||
2448 | // OD 2004-02-13 #i25029# - get next frame, but skip hidden text frames. | ||||
2449 | const SwFrame* pNextFrame = _rFrame.GetNext(); | ||||
2450 | while ( pNextFrame && pNextFrame->IsTextFrame() && | ||||
2451 | static_cast<const SwTextFrame*>(pNextFrame)->IsHiddenNow() ) | ||||
2452 | { | ||||
2453 | pNextFrame = pNextFrame->GetNext(); | ||||
2454 | } | ||||
2455 | if ( pNextFrame && pNextFrame->IsTextFrame() && | ||||
2456 | _rFrame.GetAttrSet()->GetParaConnectBorder().GetValue() | ||||
2457 | ) | ||||
2458 | { | ||||
2459 | m_bJoinedWithNext = JoinWithCmp( _rFrame, *pNextFrame ); | ||||
2460 | } | ||||
2461 | } | ||||
2462 | |||||
2463 | // valid cache status, if demanded | ||||
2464 | m_bCachedJoinedWithNext = m_bCacheGetLine; | ||||
2465 | } | ||||
2466 | |||||
2467 | // OD 21.05.2003 #108789# - accessor for cached values <m_bJoinedWithPrev> | ||||
2468 | // OD 2004-02-26 #i25029# - add 2nd parameter <_pPrevFrame>, which is passed to | ||||
2469 | // method <_CalcJoindWithPrev(..)>. | ||||
2470 | bool SwBorderAttrs::JoinedWithPrev( const SwFrame& _rFrame, | ||||
2471 | const SwFrame* _pPrevFrame ) const | ||||
2472 | { | ||||
2473 | if ( !m_bCachedJoinedWithPrev || _pPrevFrame ) | ||||
2474 | { | ||||
2475 | // OD 2004-02-26 #i25029# - pass <_pPrevFrame> as 2nd parameter | ||||
2476 | const_cast<SwBorderAttrs*>(this)->CalcJoinedWithPrev( _rFrame, _pPrevFrame ); | ||||
2477 | } | ||||
2478 | |||||
2479 | return m_bJoinedWithPrev; | ||||
2480 | } | ||||
2481 | |||||
2482 | bool SwBorderAttrs::JoinedWithNext( const SwFrame& _rFrame ) const | ||||
2483 | { | ||||
2484 | if ( !m_bCachedJoinedWithNext ) | ||||
2485 | { | ||||
2486 | const_cast<SwBorderAttrs*>(this)->CalcJoinedWithNext( _rFrame ); | ||||
2487 | } | ||||
2488 | |||||
2489 | return m_bJoinedWithNext; | ||||
2490 | } | ||||
2491 | |||||
2492 | // OD 2004-02-26 #i25029# - added 2nd parameter <_pPrevFrame>, which is passed to | ||||
2493 | // method <JoinedWithPrev> | ||||
2494 | void SwBorderAttrs::GetTopLine_( const SwFrame& _rFrame, | ||||
2495 | const SwFrame* _pPrevFrame ) | ||||
2496 | { | ||||
2497 | sal_uInt16 nRet = CalcTopLine(); | ||||
2498 | |||||
2499 | // OD 21.05.2003 #108789# - use new method <JoinWithPrev()> | ||||
2500 | // OD 2004-02-26 #i25029# - add 2nd parameter | ||||
2501 | if ( JoinedWithPrev( _rFrame, _pPrevFrame ) ) | ||||
2502 | { | ||||
2503 | nRet = 0; | ||||
2504 | } | ||||
2505 | |||||
2506 | m_bCachedGetTopLine = m_bCacheGetLine; | ||||
2507 | |||||
2508 | m_nGetTopLine = nRet; | ||||
2509 | } | ||||
2510 | |||||
2511 | void SwBorderAttrs::GetBottomLine_( const SwFrame& _rFrame ) | ||||
2512 | { | ||||
2513 | sal_uInt16 nRet = CalcBottomLine(); | ||||
2514 | |||||
2515 | // OD 21.05.2003 #108789# - use new method <JoinWithPrev()> | ||||
2516 | if ( JoinedWithNext( _rFrame ) ) | ||||
2517 | { | ||||
2518 | nRet = 0; | ||||
2519 | } | ||||
2520 | |||||
2521 | m_bCachedGetBottomLine = m_bCacheGetLine; | ||||
2522 | |||||
2523 | m_nGetBottomLine = nRet; | ||||
2524 | } | ||||
2525 | |||||
2526 | void SwBorderAttrs::CalcLineSpacing_() | ||||
2527 | { | ||||
2528 | // tdf#125300 compatibility option AddParaLineSpacingToTableCells needs also line spacing | ||||
2529 | const SvxLineSpacingItem &rSpace = m_rAttrSet.GetLineSpacing(); | ||||
2530 | if ( rSpace.GetInterLineSpaceRule() == SvxInterLineSpaceRule::Prop && rSpace.GetPropLineSpace() > 100 ) | ||||
2531 | { | ||||
2532 | sal_Int32 nFontSize = m_rAttrSet.Get(RES_CHRATR_FONTSIZE).GetHeight(); | ||||
2533 | m_nLineSpacing = nFontSize * (rSpace.GetPropLineSpace() - 100) * 1.15 / 100; | ||||
2534 | } | ||||
2535 | m_bLineSpacing = false; | ||||
2536 | } | ||||
2537 | |||||
2538 | static SwModify const* GetCacheOwner(SwFrame const& rFrame) | ||||
2539 | { | ||||
2540 | return rFrame.IsContentFrame() | ||||
2541 | ? static_cast<SwModify const*>(rFrame.IsTextFrame() | ||||
2542 | // sw_redlinehide: presumably this caches the border attrs at the model level and can be shared across different layouts so we want the ParaProps node here | ||||
2543 | ? static_cast<const SwTextFrame&>(rFrame).GetTextNodeForParaProps() | ||||
2544 | : static_cast<const SwNoTextFrame&>(rFrame).GetNode()) | ||||
2545 | : static_cast<SwModify const*>(static_cast<const SwLayoutFrame&>(rFrame).GetFormat()); | ||||
2546 | } | ||||
2547 | |||||
2548 | SwBorderAttrAccess::SwBorderAttrAccess( SwCache &rCach, const SwFrame *pFrame ) : | ||||
2549 | SwCacheAccess( rCach, | ||||
2550 | static_cast<void const *>(GetCacheOwner(*pFrame)), | ||||
2551 | GetCacheOwner(*pFrame)->IsInCache()), | ||||
2552 | m_pConstructor( pFrame ) | ||||
2553 | { | ||||
2554 | } | ||||
2555 | |||||
2556 | SwCacheObj *SwBorderAttrAccess::NewObj() | ||||
2557 | { | ||||
2558 | const_cast<SwModify *>(static_cast<SwModify const *>(m_pOwner))->SetInCache( true ); | ||||
2559 | return new SwBorderAttrs( static_cast<SwModify const *>(m_pOwner), m_pConstructor ); | ||||
2560 | } | ||||
2561 | |||||
2562 | SwBorderAttrs *SwBorderAttrAccess::Get() | ||||
2563 | { | ||||
2564 | return static_cast<SwBorderAttrs*>(SwCacheAccess::Get()); | ||||
2565 | } | ||||
2566 | |||||
2567 | SwOrderIter::SwOrderIter( const SwPageFrame *pPg ) : | ||||
2568 | m_pPage( pPg ), | ||||
2569 | m_pCurrent( nullptr ) | ||||
2570 | { | ||||
2571 | } | ||||
2572 | |||||
2573 | void SwOrderIter::Top() | ||||
2574 | { | ||||
2575 | m_pCurrent = nullptr; | ||||
2576 | if ( !m_pPage->GetSortedObjs() ) | ||||
2577 | return; | ||||
2578 | |||||
2579 | const SwSortedObjs *pObjs = m_pPage->GetSortedObjs(); | ||||
2580 | if ( !pObjs->size() ) | ||||
2581 | return; | ||||
2582 | |||||
2583 | sal_uInt32 nTopOrd = 0; | ||||
2584 | (*pObjs)[0]->GetDrawObj()->GetOrdNum(); // force updating | ||||
2585 | for (SwAnchoredObject* i : *pObjs) | ||||
2586 | { | ||||
2587 | const SdrObject* pObj = i->GetDrawObj(); | ||||
2588 | if ( dynamic_cast<const SwVirtFlyDrawObj*>( pObj) == nullptr ) | ||||
2589 | continue; | ||||
2590 | sal_uInt32 nTmp = pObj->GetOrdNumDirect(); | ||||
2591 | if ( nTmp >= nTopOrd ) | ||||
2592 | { | ||||
2593 | nTopOrd = nTmp; | ||||
2594 | m_pCurrent = pObj; | ||||
2595 | } | ||||
2596 | } | ||||
2597 | } | ||||
2598 | |||||
2599 | const SdrObject *SwOrderIter::Bottom() | ||||
2600 | { | ||||
2601 | m_pCurrent = nullptr; | ||||
2602 | if ( m_pPage->GetSortedObjs() ) | ||||
2603 | { | ||||
2604 | sal_uInt32 nBotOrd = USHRT_MAX(32767 *2 +1); | ||||
2605 | const SwSortedObjs *pObjs = m_pPage->GetSortedObjs(); | ||||
2606 | if ( pObjs->size() ) | ||||
2607 | { | ||||
2608 | (*pObjs)[0]->GetDrawObj()->GetOrdNum(); // force updating | ||||
2609 | for (SwAnchoredObject* i : *pObjs) | ||||
2610 | { | ||||
2611 | const SdrObject* pObj = i->GetDrawObj(); | ||||
2612 | if ( dynamic_cast<const SwVirtFlyDrawObj*>( pObj) == nullptr ) | ||||
2613 | continue; | ||||
2614 | sal_uInt32 nTmp = pObj->GetOrdNumDirect(); | ||||
2615 | if ( nTmp < nBotOrd ) | ||||
2616 | { | ||||
2617 | nBotOrd = nTmp; | ||||
2618 | m_pCurrent = pObj; | ||||
2619 | } | ||||
2620 | } | ||||
2621 | } | ||||
2622 | } | ||||
2623 | return m_pCurrent; | ||||
2624 | } | ||||
2625 | |||||
2626 | const SdrObject *SwOrderIter::Next() | ||||
2627 | { | ||||
2628 | const sal_uInt32 nCurOrd = m_pCurrent ? m_pCurrent->GetOrdNumDirect() : 0; | ||||
2629 | m_pCurrent = nullptr; | ||||
2630 | if ( m_pPage->GetSortedObjs() ) | ||||
2631 | { | ||||
2632 | sal_uInt32 nOrd = USHRT_MAX(32767 *2 +1); | ||||
2633 | const SwSortedObjs *pObjs = m_pPage->GetSortedObjs(); | ||||
2634 | if ( pObjs->size() ) | ||||
2635 | { | ||||
2636 | (*pObjs)[0]->GetDrawObj()->GetOrdNum(); // force updating | ||||
2637 | for (SwAnchoredObject* i : *pObjs) | ||||
2638 | { | ||||
2639 | const SdrObject* pObj = i->GetDrawObj(); | ||||
2640 | if ( dynamic_cast<const SwVirtFlyDrawObj*>( pObj) == nullptr ) | ||||
2641 | continue; | ||||
2642 | sal_uInt32 nTmp = pObj->GetOrdNumDirect(); | ||||
2643 | if ( nTmp > nCurOrd && nTmp < nOrd ) | ||||
2644 | { | ||||
2645 | nOrd = nTmp; | ||||
2646 | m_pCurrent = pObj; | ||||
2647 | } | ||||
2648 | } | ||||
2649 | } | ||||
2650 | } | ||||
2651 | return m_pCurrent; | ||||
2652 | } | ||||
2653 | |||||
2654 | void SwOrderIter::Prev() | ||||
2655 | { | ||||
2656 | const sal_uInt32 nCurOrd = m_pCurrent ? m_pCurrent->GetOrdNumDirect() : 0; | ||||
2657 | m_pCurrent = nullptr; | ||||
2658 | if ( !m_pPage->GetSortedObjs() ) | ||||
2659 | return; | ||||
2660 | |||||
2661 | const SwSortedObjs *pObjs = m_pPage->GetSortedObjs(); | ||||
2662 | if ( !pObjs->size() ) | ||||
2663 | return; | ||||
2664 | |||||
2665 | sal_uInt32 nOrd = 0; | ||||
2666 | (*pObjs)[0]->GetDrawObj()->GetOrdNum(); // force updating | ||||
2667 | for (SwAnchoredObject* i : *pObjs) | ||||
2668 | { | ||||
2669 | const SdrObject* pObj = i->GetDrawObj(); | ||||
2670 | if ( dynamic_cast<const SwVirtFlyDrawObj*>( pObj) == nullptr ) | ||||
2671 | continue; | ||||
2672 | sal_uInt32 nTmp = pObj->GetOrdNumDirect(); | ||||
2673 | if ( nTmp < nCurOrd && nTmp >= nOrd ) | ||||
2674 | { | ||||
2675 | nOrd = nTmp; | ||||
2676 | m_pCurrent = pObj; | ||||
2677 | } | ||||
2678 | } | ||||
2679 | } | ||||
2680 | |||||
2681 | /// Keep and restore the substructure of a layout frame for an action. | ||||
2682 | // New algorithm: | ||||
2683 | // Do not look at each neighbor one by one to set all pointers correctly. | ||||
2684 | // It is sufficient to detach a part of a chain and check if another chain needs to be added | ||||
2685 | // when attaching it again. Only the pointers necessary for the chain connection need to be | ||||
2686 | // adjusted. The correction happens in RestoreContent(). In between all access is restricted. | ||||
2687 | // During this action, the Flys are detached from the page. | ||||
2688 | |||||
2689 | // #115759# - 'remove' also drawing object from page and | ||||
2690 | // at-fly anchored objects from page | ||||
2691 | static void lcl_RemoveObjsFromPage( SwFrame* _pFrame ) | ||||
2692 | { | ||||
2693 | OSL_ENSURE( _pFrame->GetDrawObjs(), "no DrawObjs in lcl_RemoveObjsFromPage." )do { if (true && (!(_pFrame->GetDrawObjs()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "2693" ": "), "%s", "no DrawObjs in lcl_RemoveObjsFromPage." ); } } while (false); | ||||
2694 | SwSortedObjs &rObjs = *_pFrame->GetDrawObjs(); | ||||
2695 | for (SwAnchoredObject* pObj : rObjs) | ||||
2696 | { | ||||
2697 | // #115759# - reset member, at which the anchored | ||||
2698 | // object orients its vertical position | ||||
2699 | pObj->ClearVertPosOrientFrame(); | ||||
2700 | // #i43913# | ||||
2701 | pObj->ResetLayoutProcessBools(); | ||||
2702 | // #115759# - remove also lower objects of as-character | ||||
2703 | // anchored Writer fly frames from page | ||||
2704 | if ( dynamic_cast<const SwFlyFrame*>( pObj) != nullptr ) | ||||
2705 | { | ||||
2706 | SwFlyFrame* pFlyFrame = static_cast<SwFlyFrame*>(pObj); | ||||
2707 | |||||
2708 | // #115759# - remove also direct lowers of Writer | ||||
2709 | // fly frame from page | ||||
2710 | if ( pFlyFrame->GetDrawObjs() ) | ||||
2711 | { | ||||
2712 | ::lcl_RemoveObjsFromPage( pFlyFrame ); | ||||
2713 | } | ||||
2714 | |||||
2715 | SwContentFrame* pCnt = pFlyFrame->ContainsContent(); | ||||
2716 | while ( pCnt ) | ||||
2717 | { | ||||
2718 | if ( pCnt->GetDrawObjs() ) | ||||
2719 | ::lcl_RemoveObjsFromPage( pCnt ); | ||||
2720 | pCnt = pCnt->GetNextContentFrame(); | ||||
2721 | } | ||||
2722 | if ( pFlyFrame->IsFlyFreeFrame() ) | ||||
2723 | { | ||||
2724 | // #i28701# - use new method <GetPageFrame()> | ||||
2725 | if (SwPageFrame *pPg = pFlyFrame->GetPageFrame()) | ||||
2726 | pPg->RemoveFlyFromPage(pFlyFrame); | ||||
2727 | } | ||||
2728 | } | ||||
2729 | // #115759# - remove also drawing objects from page | ||||
2730 | else if ( dynamic_cast<const SwAnchoredDrawObject*>( pObj) != nullptr ) | ||||
2731 | { | ||||
2732 | if (pObj->GetFrameFormat().GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR) | ||||
2733 | { | ||||
2734 | if (SwPageFrame *pPg = pObj->GetPageFrame()) | ||||
2735 | pPg->RemoveDrawObjFromPage( | ||||
2736 | *static_cast<SwAnchoredDrawObject*>(pObj) ); | ||||
2737 | } | ||||
2738 | } | ||||
2739 | } | ||||
2740 | } | ||||
2741 | |||||
2742 | SwFrame *SaveContent( SwLayoutFrame *pLay, SwFrame *pStart ) | ||||
2743 | { | ||||
2744 | if( pLay->IsSctFrame() && pLay->Lower() && pLay->Lower()->IsColumnFrame() ) | ||||
2745 | sw_RemoveFootnotes( static_cast<SwColumnFrame*>(pLay->Lower()), true, true ); | ||||
2746 | |||||
2747 | SwFrame *pSav = pLay->ContainsAny(); | ||||
2748 | if ( nullptr == pSav ) | ||||
2749 | return nullptr; | ||||
2750 | |||||
2751 | if( pSav->IsInFootnote() && !pLay->IsInFootnote() ) | ||||
2752 | { | ||||
2753 | do | ||||
2754 | pSav = pSav->FindNext(); | ||||
2755 | while( pSav && pSav->IsInFootnote() ); | ||||
2756 | if( !pSav || !pLay->IsAnLower( pSav ) ) | ||||
2757 | return nullptr; | ||||
2758 | } | ||||
2759 | |||||
2760 | // Tables should be saved as a whole, exception: | ||||
2761 | // The contents of a section or a cell inside a table should be saved | ||||
2762 | if ( pSav->IsInTab() && !( ( pLay->IsSctFrame() || pLay->IsCellFrame() ) && pLay->IsInTab() ) ) | ||||
2763 | while ( !pSav->IsTabFrame() ) | ||||
2764 | pSav = pSav->GetUpper(); | ||||
2765 | |||||
2766 | if( pSav->IsInSct() ) | ||||
2767 | { // search the upmost section inside of pLay | ||||
2768 | SwFrame* pSect = pLay->FindSctFrame(); | ||||
2769 | SwFrame *pTmp = pSav; | ||||
2770 | do | ||||
2771 | { | ||||
2772 | pSav = pTmp; | ||||
2773 | pTmp = (pSav && pSav->GetUpper()) ? pSav->GetUpper()->FindSctFrame() : nullptr; | ||||
2774 | } while ( pTmp != pSect ); | ||||
2775 | } | ||||
2776 | |||||
2777 | SwFrame *pFloat = pSav; | ||||
2778 | if( !pStart ) | ||||
2779 | pStart = pSav; | ||||
2780 | bool bGo = pStart == pSav; | ||||
2781 | do | ||||
2782 | { | ||||
2783 | if( bGo ) | ||||
2784 | pFloat->GetUpper()->m_pLower = nullptr; // detach the chain part | ||||
2785 | |||||
2786 | // search the end of the chain part, remove Flys on the way | ||||
2787 | do | ||||
2788 | { | ||||
2789 | if( bGo ) | ||||
2790 | { | ||||
2791 | if ( pFloat->IsContentFrame() ) | ||||
2792 | { | ||||
2793 | if ( pFloat->GetDrawObjs() ) | ||||
2794 | ::lcl_RemoveObjsFromPage( static_cast<SwContentFrame*>(pFloat) ); | ||||
2795 | } | ||||
2796 | else if ( pFloat->IsTabFrame() || pFloat->IsSctFrame() ) | ||||
2797 | { | ||||
2798 | SwContentFrame *pCnt = static_cast<SwLayoutFrame*>(pFloat)->ContainsContent(); | ||||
2799 | if( pCnt ) | ||||
2800 | { | ||||
2801 | do | ||||
2802 | { if ( pCnt->GetDrawObjs() ) | ||||
2803 | ::lcl_RemoveObjsFromPage( pCnt ); | ||||
2804 | pCnt = pCnt->GetNextContentFrame(); | ||||
2805 | } while ( pCnt && static_cast<SwLayoutFrame*>(pFloat)->IsAnLower( pCnt ) ); | ||||
2806 | } | ||||
2807 | } | ||||
2808 | else { | ||||
2809 | OSL_ENSURE( !pFloat, "new FloatFrame?" )do { if (true && (!(!pFloat))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "2809" ": "), "%s", "new FloatFrame?"); } } while (false ); | ||||
2810 | } | ||||
2811 | } | ||||
2812 | if ( pFloat->GetNext() ) | ||||
2813 | { | ||||
2814 | if( bGo ) | ||||
2815 | pFloat->mpUpper = nullptr; | ||||
2816 | pFloat = pFloat->GetNext(); | ||||
2817 | if( !bGo && pFloat == pStart ) | ||||
2818 | { | ||||
2819 | bGo = true; | ||||
2820 | pFloat->mpPrev->mpNext = nullptr; | ||||
2821 | pFloat->mpPrev = nullptr; | ||||
2822 | } | ||||
2823 | } | ||||
2824 | else | ||||
2825 | break; | ||||
2826 | |||||
2827 | } while ( pFloat ); | ||||
2828 | |||||
2829 | // search next chain part and connect both chains | ||||
2830 | SwFrame *pTmp = pFloat->FindNext(); | ||||
2831 | if( bGo ) | ||||
2832 | pFloat->mpUpper = nullptr; | ||||
2833 | |||||
2834 | if( !pLay->IsInFootnote() ) | ||||
2835 | while( pTmp && pTmp->IsInFootnote() ) | ||||
2836 | pTmp = pTmp->FindNext(); | ||||
2837 | |||||
2838 | if ( !pLay->IsAnLower( pTmp ) ) | ||||
2839 | pTmp = nullptr; | ||||
2840 | |||||
2841 | if ( pTmp && bGo ) | ||||
2842 | { | ||||
2843 | pFloat->mpNext = pTmp; // connect both chains | ||||
2844 | pFloat->mpNext->mpPrev = pFloat; | ||||
2845 | } | ||||
2846 | pFloat = pTmp; | ||||
2847 | bGo = bGo || ( pStart == pFloat ); | ||||
2848 | } while ( pFloat ); | ||||
2849 | |||||
2850 | return bGo ? pStart : nullptr; | ||||
2851 | } | ||||
2852 | |||||
2853 | // #115759# - add also drawing objects to page and at-fly | ||||
2854 | // anchored objects to page | ||||
2855 | static void lcl_AddObjsToPage( SwFrame* _pFrame, SwPageFrame* _pPage ) | ||||
2856 | { | ||||
2857 | OSL_ENSURE( _pFrame->GetDrawObjs(), "no DrawObjs in lcl_AddObjsToPage." )do { if (true && (!(_pFrame->GetDrawObjs()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "2857" ": "), "%s", "no DrawObjs in lcl_AddObjsToPage.") ; } } while (false); | ||||
2858 | SwSortedObjs &rObjs = *_pFrame->GetDrawObjs(); | ||||
2859 | for (SwAnchoredObject* pObj : rObjs) | ||||
2860 | { | ||||
2861 | // #115759# - unlock position of anchored object | ||||
2862 | // in order to get the object's position calculated. | ||||
2863 | pObj->UnlockPosition(); | ||||
2864 | // #115759# - add also lower objects of as-character | ||||
2865 | // anchored Writer fly frames from page | ||||
2866 | if ( dynamic_cast<const SwFlyFrame*>( pObj) != nullptr ) | ||||
2867 | { | ||||
2868 | SwFlyFrame* pFlyFrame = static_cast<SwFlyFrame*>(pObj); | ||||
2869 | if ( dynamic_cast<const SwFlyFreeFrame*>( pObj) != nullptr ) | ||||
2870 | { | ||||
2871 | _pPage->AppendFlyToPage( pFlyFrame ); | ||||
2872 | } | ||||
2873 | pFlyFrame->InvalidatePos_(); | ||||
2874 | pFlyFrame->InvalidateSize_(); | ||||
2875 | pFlyFrame->InvalidatePage( _pPage ); | ||||
2876 | |||||
2877 | // #115759# - add also at-fly anchored objects | ||||
2878 | // to page | ||||
2879 | if ( pFlyFrame->GetDrawObjs() ) | ||||
2880 | { | ||||
2881 | ::lcl_AddObjsToPage( pFlyFrame, _pPage ); | ||||
2882 | } | ||||
2883 | |||||
2884 | SwContentFrame *pCnt = pFlyFrame->ContainsContent(); | ||||
2885 | while ( pCnt ) | ||||
2886 | { | ||||
2887 | if ( pCnt->GetDrawObjs() ) | ||||
2888 | ::lcl_AddObjsToPage( pCnt, _pPage ); | ||||
2889 | pCnt = pCnt->GetNextContentFrame(); | ||||
2890 | } | ||||
2891 | } | ||||
2892 | // #115759# - remove also drawing objects from page | ||||
2893 | else if ( dynamic_cast<const SwAnchoredDrawObject*>( pObj) != nullptr ) | ||||
2894 | { | ||||
2895 | if (pObj->GetFrameFormat().GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR) | ||||
2896 | { | ||||
2897 | pObj->InvalidateObjPos(); | ||||
2898 | _pPage->AppendDrawObjToPage( | ||||
2899 | *static_cast<SwAnchoredDrawObject*>(pObj) ); | ||||
2900 | } | ||||
2901 | } | ||||
2902 | } | ||||
2903 | } | ||||
2904 | |||||
2905 | void RestoreContent( SwFrame *pSav, SwLayoutFrame *pParent, SwFrame *pSibling ) | ||||
2906 | { | ||||
2907 | OSL_ENSURE( pSav && pParent, "no Save or Parent provided for RestoreContent." )do { if (true && (!(pSav && pParent))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "2907" ": "), "%s", "no Save or Parent provided for RestoreContent." ); } } while (false); | ||||
2908 | SwRectFnSet aRectFnSet(pParent); | ||||
2909 | |||||
2910 | // If there are already FlowFrames below the new parent, so add the chain (starting with pSav) | ||||
2911 | // after the last one. The parts are inserted and invalidated if needed. | ||||
2912 | // On the way, the Flys of the ContentFrames are registered at the page. | ||||
2913 | |||||
2914 | SwPageFrame *pPage = pParent->FindPageFrame(); | ||||
2915 | |||||
2916 | if ( pPage ) | ||||
2917 | pPage->InvalidatePage( pPage ); | ||||
2918 | |||||
2919 | // determine predecessor and establish connection or initialize | ||||
2920 | pSav->mpPrev = pSibling; | ||||
2921 | SwFrame* pNxt; | ||||
2922 | if ( pSibling ) | ||||
2923 | { | ||||
2924 | pNxt = pSibling->mpNext; | ||||
2925 | pSibling->mpNext = pSav; | ||||
2926 | pSibling->InvalidatePrt_(); | ||||
2927 | pSibling->InvalidatePage( pPage ); | ||||
2928 | SwFlowFrame *pFlowFrame = dynamic_cast<SwFlowFrame*>(pSibling); | ||||
2929 | if (pFlowFrame && pFlowFrame->GetFollow()) | ||||
2930 | pSibling->Prepare( PrepareHint::Clear, nullptr, false ); | ||||
2931 | } | ||||
2932 | else | ||||
2933 | { pNxt = pParent->m_pLower; | ||||
2934 | pParent->m_pLower = pSav; | ||||
2935 | pSav->mpUpper = pParent; // set here already, so that it is explicit when invalidating | ||||
2936 | |||||
2937 | if ( pSav->IsContentFrame() ) | ||||
2938 | static_cast<SwContentFrame*>(pSav)->InvalidatePage( pPage ); | ||||
2939 | else | ||||
2940 | { // pSav might be an empty SectFrame | ||||
2941 | SwContentFrame* pCnt = pParent->ContainsContent(); | ||||
2942 | if( pCnt ) | ||||
2943 | pCnt->InvalidatePage( pPage ); | ||||
2944 | } | ||||
2945 | } | ||||
2946 | |||||
2947 | // the parent needs to grow appropriately | ||||
2948 | SwTwips nGrowVal = 0; | ||||
2949 | SwFrame* pLast; | ||||
2950 | do | ||||
2951 | { pSav->mpUpper = pParent; | ||||
2952 | nGrowVal += aRectFnSet.GetHeight(pSav->getFrameArea()); | ||||
2953 | pSav->InvalidateAll_(); | ||||
2954 | |||||
2955 | // register Flys, if TextFrames than also invalidate appropriately | ||||
2956 | if ( pSav->IsContentFrame() ) | ||||
2957 | { | ||||
2958 | if ( pSav->IsTextFrame() && | ||||
2959 | static_cast<SwTextFrame*>(pSav)->GetCacheIdx() != USHRT_MAX(32767 *2 +1) ) | ||||
2960 | static_cast<SwTextFrame*>(pSav)->Init(); // I am its friend | ||||
2961 | |||||
2962 | if ( pPage && pSav->GetDrawObjs() ) | ||||
2963 | ::lcl_AddObjsToPage( static_cast<SwContentFrame*>(pSav), pPage ); | ||||
2964 | } | ||||
2965 | else | ||||
2966 | { SwContentFrame *pBlub = static_cast<SwLayoutFrame*>(pSav)->ContainsContent(); | ||||
2967 | if( pBlub ) | ||||
2968 | { | ||||
2969 | do | ||||
2970 | { if ( pPage && pBlub->GetDrawObjs() ) | ||||
2971 | ::lcl_AddObjsToPage( pBlub, pPage ); | ||||
2972 | if( pBlub->IsTextFrame() && static_cast<SwTextFrame*>(pBlub)->HasFootnote() && | ||||
2973 | static_cast<SwTextFrame*>(pBlub)->GetCacheIdx() != USHRT_MAX(32767 *2 +1) ) | ||||
2974 | static_cast<SwTextFrame*>(pBlub)->Init(); // I am its friend | ||||
2975 | pBlub = pBlub->GetNextContentFrame(); | ||||
2976 | } while ( pBlub && static_cast<SwLayoutFrame*>(pSav)->IsAnLower( pBlub )); | ||||
2977 | } | ||||
2978 | } | ||||
2979 | pLast = pSav; | ||||
2980 | pSav = pSav->GetNext(); | ||||
2981 | |||||
2982 | } while ( pSav ); | ||||
2983 | |||||
2984 | if( pNxt ) | ||||
2985 | { | ||||
2986 | pLast->mpNext = pNxt; | ||||
2987 | pNxt->mpPrev = pLast; | ||||
2988 | } | ||||
2989 | |||||
2990 | pParent->Grow( nGrowVal ); | ||||
2991 | } | ||||
2992 | |||||
2993 | namespace sw { | ||||
2994 | |||||
2995 | bool IsRightPageByNumber(SwRootFrame const& rLayout, sal_uInt16 const nPageNum) | ||||
2996 | { | ||||
2997 | assert(rLayout.GetLower())(static_cast <bool> (rLayout.GetLower()) ? void (0) : __assert_fail ("rLayout.GetLower()", "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 2997, __extension__ __PRETTY_FUNCTION__)); | ||||
2998 | // unfortunately can only get SwPageDesc, not SwFormatPageDesc here... | ||||
2999 | auto const nFirstVirtPageNum(rLayout.GetLower()->GetVirtPageNum()); | ||||
3000 | bool const isFirstPageOfLayoutOdd(nFirstVirtPageNum % 2 == 1); | ||||
3001 | return ((nPageNum % 2) == 1) == isFirstPageOfLayoutOdd; | ||||
3002 | } | ||||
3003 | |||||
3004 | } // namespace sw | ||||
3005 | |||||
3006 | SwPageFrame * InsertNewPage( SwPageDesc &rDesc, SwFrame *pUpper, | ||||
3007 | bool const isRightPage, bool const bFirst, bool bInsertEmpty, | ||||
3008 | bool const bFootnote, | ||||
3009 | SwFrame *pSibling, | ||||
3010 | bool const bVeryFirstPage ) | ||||
3011 | { | ||||
3012 | assert(pUpper)(static_cast <bool> (pUpper) ? void (0) : __assert_fail ("pUpper", "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 3012, __extension__ __PRETTY_FUNCTION__)); | ||||
3013 | assert(pUpper->IsRootFrame())(static_cast <bool> (pUpper->IsRootFrame()) ? void ( 0) : __assert_fail ("pUpper->IsRootFrame()", "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 3013, __extension__ __PRETTY_FUNCTION__)); | ||||
3014 | assert(!pSibling || static_cast<SwLayoutFrame const*>(pUpper)->Lower() != pSibling)(static_cast <bool> (!pSibling || static_cast<SwLayoutFrame const*>(pUpper)->Lower() != pSibling) ? void (0) : __assert_fail ("!pSibling || static_cast<SwLayoutFrame const*>(pUpper)->Lower() != pSibling" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 3014, __extension__ __PRETTY_FUNCTION__)); // currently no insert before 1st page | ||||
3015 | SwPageFrame *pRet; | ||||
3016 | SwDoc *pDoc = static_cast<SwLayoutFrame*>(pUpper)->GetFormat()->GetDoc(); | ||||
3017 | if (bFirst) | ||||
3018 | { | ||||
3019 | if (rDesc.IsFirstShared()) | ||||
3020 | { | ||||
3021 | // We need to fallback to left or right page format, decide it now. | ||||
3022 | // FIXME: is this still needed? | ||||
3023 | if (isRightPage) | ||||
3024 | { | ||||
3025 | rDesc.GetFirstMaster().SetFormatAttr( rDesc.GetMaster().GetHeader() ); | ||||
3026 | rDesc.GetFirstMaster().SetFormatAttr( rDesc.GetMaster().GetFooter() ); | ||||
3027 | // fdo#60250 copy margins for mirrored pages | ||||
3028 | rDesc.GetFirstMaster().SetFormatAttr( rDesc.GetMaster().GetLRSpace() ); | ||||
3029 | } | ||||
3030 | else | ||||
3031 | { | ||||
3032 | rDesc.GetFirstLeft().SetFormatAttr( rDesc.GetLeft().GetHeader() ); | ||||
3033 | rDesc.GetFirstLeft().SetFormatAttr( rDesc.GetLeft().GetFooter() ); | ||||
3034 | rDesc.GetFirstLeft().SetFormatAttr( rDesc.GetLeft().GetLRSpace() ); | ||||
3035 | } | ||||
3036 | } | ||||
3037 | } | ||||
3038 | SwFrameFormat *pFormat(isRightPage ? rDesc.GetRightFormat(bFirst) : rDesc.GetLeftFormat(bFirst)); | ||||
3039 | // If there is no FrameFormat for this page, add an empty page | ||||
3040 | if ( !pFormat ) | ||||
3041 | { | ||||
3042 | pFormat = isRightPage ? rDesc.GetLeftFormat(bVeryFirstPage) : rDesc.GetRightFormat(bVeryFirstPage); | ||||
3043 | OSL_ENSURE( pFormat, "Descriptor without any format?!" )do { if (true && (!(pFormat))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "3043" ": "), "%s", "Descriptor without any format?!"); } } while (false); | ||||
3044 | bInsertEmpty = !bInsertEmpty; | ||||
3045 | } | ||||
3046 | if( bInsertEmpty ) | ||||
3047 | { | ||||
3048 | SwPageDesc *pTmpDesc = pSibling && pSibling->GetPrev() ? | ||||
3049 | static_cast<SwPageFrame*>(pSibling->GetPrev())->GetPageDesc() : &rDesc; | ||||
3050 | pRet = new SwPageFrame( pDoc->GetEmptyPageFormat(), pUpper, pTmpDesc ); | ||||
3051 | SAL_INFO( "sw.pageframe", "InsertNewPage - insert empty p: " << pRet << " d: " << pTmpDesc )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "sw.pageframe")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "InsertNewPage - insert empty p: " << pRet << " d: " << pTmpDesc) == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sw.pageframe"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "3051" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "InsertNewPage - insert empty p: " << pRet << " d: " << pTmpDesc), 0); } else { ::std:: ostringstream sal_detail_stream; sal_detail_stream << "InsertNewPage - insert empty p: " << pRet << " d: " << pTmpDesc; ::sal::detail ::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sw.pageframe"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "3051" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "InsertNewPage - insert empty p: " << pRet << " d: " << pTmpDesc) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("sw.pageframe"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "3051" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "InsertNewPage - insert empty p: " << pRet << " d: " << pTmpDesc), 0); } else { ::std:: ostringstream sal_detail_stream; sal_detail_stream << "InsertNewPage - insert empty p: " << pRet << " d: " << pTmpDesc; ::sal::detail ::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sw.pageframe"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "3051" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||
3052 | pRet->Paste( pUpper, pSibling ); | ||||
3053 | pRet->PreparePage( bFootnote ); | ||||
3054 | } | ||||
3055 | pRet = new SwPageFrame( pFormat, pUpper, &rDesc ); | ||||
3056 | SAL_INFO( "sw.pageframe", "InsertNewPage p: " << pRet << " d: " << &rDesc << " f: " << pFormat )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "sw.pageframe")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "InsertNewPage p: " << pRet << " d: " << &rDesc << " f: " << pFormat) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("sw.pageframe"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "3056" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "InsertNewPage p: " << pRet << " d: " << &rDesc << " f: " << pFormat) , 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "InsertNewPage p: " << pRet << " d: " << &rDesc << " f: " << pFormat; ::sal::detail:: log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sw.pageframe"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "3056" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "InsertNewPage p: " << pRet << " d: " << &rDesc << " f: " << pFormat) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sw.pageframe" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "3056" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "InsertNewPage p: " << pRet << " d: " << &rDesc << " f: " << pFormat) , 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "InsertNewPage p: " << pRet << " d: " << &rDesc << " f: " << pFormat; ::sal::detail:: log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sw.pageframe"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "3056" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||
3057 | pRet->Paste( pUpper, pSibling ); | ||||
3058 | pRet->PreparePage( bFootnote ); | ||||
3059 | if ( pRet->GetNext() ) | ||||
3060 | SwRootFrame::AssertPageFlys( pRet ); | ||||
3061 | return pRet; | ||||
3062 | } | ||||
3063 | |||||
3064 | /* The following two methods search the layout structure recursively and | ||||
3065 | * register all Flys at the page that have a Frame in this structure as an anchor. | ||||
3066 | */ | ||||
3067 | |||||
3068 | static void lcl_Regist( SwPageFrame *pPage, const SwFrame *pAnch ) | ||||
3069 | { | ||||
3070 | SwSortedObjs *pObjs = const_cast<SwSortedObjs*>(pAnch->GetDrawObjs()); | ||||
3071 | for (SwAnchoredObject* pObj : *pObjs) | ||||
3072 | { | ||||
3073 | if (SwFlyFrame* pFly = dynamic_cast<SwFlyFrame*>(pObj)) | ||||
3074 | { | ||||
3075 | // register (not if already known) | ||||
3076 | // #i28701# - use new method <GetPageFrame()> | ||||
3077 | SwPageFrame *pPg = pFly->IsFlyFreeFrame() | ||||
3078 | ? pFly->GetPageFrame() : pFly->FindPageFrame(); | ||||
3079 | if ( pPg != pPage ) | ||||
3080 | { | ||||
3081 | if ( pPg ) | ||||
3082 | pPg->RemoveFlyFromPage( pFly ); | ||||
3083 | pPage->AppendFlyToPage( pFly ); | ||||
3084 | } | ||||
3085 | ::RegistFlys( pPage, pFly ); | ||||
3086 | } | ||||
3087 | else | ||||
3088 | { | ||||
3089 | // #i87493# | ||||
3090 | if ( pPage != pObj->GetPageFrame() ) | ||||
3091 | { | ||||
3092 | // #i28701# | ||||
3093 | if (SwPageFrame *pPg = pObj->GetPageFrame()) | ||||
3094 | pPg->RemoveDrawObjFromPage( *pObj ); | ||||
3095 | pPage->AppendDrawObjToPage( *pObj ); | ||||
3096 | } | ||||
3097 | } | ||||
3098 | |||||
3099 | const SwFlyFrame* pFly = pAnch->FindFlyFrame(); | ||||
3100 | if ( pFly && | ||||
3101 | pObj->GetDrawObj()->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() && | ||||
3102 | pObj->GetDrawObj()->getSdrPageFromSdrObject() ) | ||||
3103 | { | ||||
3104 | //#i119945# set pFly's OrdNum to pObj's. So when pFly is removed by Undo, the original OrdNum will not be changed. | ||||
3105 | pObj->DrawObj()->getSdrPageFromSdrObject()->SetObjectOrdNum( pFly->GetVirtDrawObj()->GetOrdNumDirect(), | ||||
3106 | pObj->GetDrawObj()->GetOrdNumDirect() ); | ||||
3107 | } | ||||
3108 | } | ||||
3109 | } | ||||
3110 | |||||
3111 | void RegistFlys( SwPageFrame *pPage, const SwLayoutFrame *pLay ) | ||||
3112 | { | ||||
3113 | if ( pLay->GetDrawObjs() ) | ||||
3114 | ::lcl_Regist( pPage, pLay ); | ||||
3115 | const SwFrame *pFrame = pLay->Lower(); | ||||
3116 | while ( pFrame ) | ||||
3117 | { | ||||
3118 | if ( pFrame->IsLayoutFrame() ) | ||||
3119 | ::RegistFlys( pPage, static_cast<const SwLayoutFrame*>(pFrame) ); | ||||
3120 | else if ( pFrame->GetDrawObjs() ) | ||||
3121 | ::lcl_Regist( pPage, pFrame ); | ||||
3122 | pFrame = pFrame->GetNext(); | ||||
3123 | } | ||||
3124 | } | ||||
3125 | |||||
3126 | /// Notify the background based on the difference between old and new rectangle | ||||
3127 | void Notify( SwFlyFrame *pFly, SwPageFrame *pOld, const SwRect &rOld, | ||||
3128 | const SwRect* pOldPrt ) | ||||
3129 | { | ||||
3130 | const SwRect aFrame( pFly->GetObjRectWithSpaces() ); | ||||
3131 | if ( rOld.Pos() != aFrame.Pos() ) | ||||
3132 | { // changed position, invalidate old and new area | ||||
3133 | if ( rOld.HasArea() && | ||||
3134 | rOld.Left()+pFly->GetFormat()->GetLRSpace().GetLeft() < FAR_AWAY(((sal_Int32) 0x7FFFFFFF) - 20000) ) | ||||
3135 | { | ||||
3136 | pFly->NotifyBackground( pOld, rOld, PrepareHint::FlyFrameLeave ); | ||||
3137 | } | ||||
3138 | pFly->NotifyBackground( pFly->FindPageFrame(), aFrame, PrepareHint::FlyFrameArrive ); | ||||
3139 | } | ||||
3140 | else if ( rOld.SSize() != aFrame.SSize() ) | ||||
3141 | { // changed size, invalidate the area that was left or is now overlapped | ||||
3142 | // For simplicity, we purposely invalidate a Twip even if not needed. | ||||
3143 | |||||
3144 | SwViewShell *pSh = pFly->getRootFrame()->GetCurrShell(); | ||||
3145 | if( pSh && rOld.HasArea() ) | ||||
3146 | pSh->InvalidateWindows( rOld ); | ||||
3147 | |||||
3148 | // #i51941# - consider case that fly frame isn't | ||||
3149 | // registered at the old page <pOld> | ||||
3150 | SwPageFrame* pPageFrame = pFly->FindPageFrame(); | ||||
3151 | if ( pOld != pPageFrame ) | ||||
3152 | { | ||||
3153 | pFly->NotifyBackground( pPageFrame, aFrame, PrepareHint::FlyFrameArrive ); | ||||
3154 | } | ||||
3155 | |||||
3156 | if ( rOld.Left() != aFrame.Left() ) | ||||
3157 | { | ||||
3158 | SwRect aTmp( rOld ); | ||||
3159 | aTmp.Union( aFrame ); | ||||
3160 | aTmp.Left( std::min(aFrame.Left(), rOld.Left()) ); | ||||
3161 | aTmp.Right( std::max(aFrame.Left(), rOld.Left()) ); | ||||
3162 | pFly->NotifyBackground( pOld, aTmp, PrepareHint::FlyFrameSizeChanged ); | ||||
3163 | } | ||||
3164 | SwTwips nOld = rOld.Right(); | ||||
3165 | SwTwips nNew = aFrame.Right(); | ||||
3166 | if ( nOld != nNew ) | ||||
3167 | { | ||||
3168 | SwRect aTmp( rOld ); | ||||
3169 | aTmp.Union( aFrame ); | ||||
3170 | aTmp.Left( std::min(nNew, nOld) ); | ||||
3171 | aTmp.Right( std::max(nNew, nOld) ); | ||||
3172 | pFly->NotifyBackground( pOld, aTmp, PrepareHint::FlyFrameSizeChanged ); | ||||
3173 | } | ||||
3174 | if ( rOld.Top() != aFrame.Top() ) | ||||
3175 | { | ||||
3176 | SwRect aTmp( rOld ); | ||||
3177 | aTmp.Union( aFrame ); | ||||
3178 | aTmp.Top( std::min(aFrame.Top(), rOld.Top()) ); | ||||
3179 | aTmp.Bottom( std::max(aFrame.Top(), rOld.Top()) ); | ||||
3180 | pFly->NotifyBackground( pOld, aTmp, PrepareHint::FlyFrameSizeChanged ); | ||||
3181 | } | ||||
3182 | nOld = rOld.Bottom(); | ||||
3183 | nNew = aFrame.Bottom(); | ||||
3184 | if ( nOld != nNew ) | ||||
3185 | { | ||||
3186 | SwRect aTmp( rOld ); | ||||
3187 | aTmp.Union( aFrame ); | ||||
3188 | aTmp.Top( std::min(nNew, nOld) ); | ||||
3189 | aTmp.Bottom( std::max(nNew, nOld) ); | ||||
3190 | pFly->NotifyBackground( pOld, aTmp, PrepareHint::FlyFrameSizeChanged ); | ||||
3191 | } | ||||
3192 | } | ||||
3193 | else if(pOldPrt && *pOldPrt != pFly->getFramePrintArea()) | ||||
3194 | { | ||||
3195 | bool bNotifyBackground(pFly->GetFormat()->GetSurround().IsContour()); | ||||
3196 | |||||
3197 | if(!bNotifyBackground && | ||||
3198 | pFly->IsFlyFreeFrame() && | ||||
3199 | static_cast< const SwFlyFreeFrame* >(pFly)->supportsAutoContour()) | ||||
3200 | { | ||||
3201 | // RotateFlyFrame3: Also notify for FlyFrames which allow AutoContour | ||||
3202 | bNotifyBackground = true; | ||||
3203 | } | ||||
3204 | |||||
3205 | if(bNotifyBackground) | ||||
3206 | { | ||||
3207 | // #i24097# | ||||
3208 | pFly->NotifyBackground( pFly->FindPageFrame(), aFrame, PrepareHint::FlyFrameArrive ); | ||||
3209 | } | ||||
3210 | } | ||||
3211 | } | ||||
3212 | |||||
3213 | static void lcl_CheckFlowBack( SwFrame* pFrame, const SwRect &rRect ) | ||||
3214 | { | ||||
3215 | SwTwips nBottom = rRect.Bottom(); | ||||
3216 | while( pFrame ) | ||||
3217 | { | ||||
3218 | if( pFrame->IsLayoutFrame() ) | ||||
3219 | { | ||||
3220 | if( rRect.IsOver( pFrame->getFrameArea() ) ) | ||||
3221 | lcl_CheckFlowBack( static_cast<SwLayoutFrame*>(pFrame)->Lower(), rRect ); | ||||
3222 | } | ||||
3223 | else if( !pFrame->GetNext() && nBottom > pFrame->getFrameArea().Bottom() ) | ||||
3224 | { | ||||
3225 | if( pFrame->IsContentFrame() && static_cast<SwContentFrame*>(pFrame)->HasFollow() ) | ||||
3226 | pFrame->InvalidateSize(); | ||||
3227 | else | ||||
3228 | pFrame->InvalidateNextPos(); | ||||
3229 | } | ||||
3230 | pFrame = pFrame->GetNext(); | ||||
3231 | } | ||||
3232 | } | ||||
3233 | |||||
3234 | static void lcl_NotifyContent( const SdrObject *pThis, SwContentFrame *pCnt, | ||||
3235 | const SwRect &rRect, const PrepareHint eHint ) | ||||
3236 | { | ||||
3237 | if ( !pCnt->IsTextFrame() ) | ||||
3238 | return; | ||||
3239 | |||||
3240 | SwRect aCntPrt( pCnt->getFramePrintArea() ); | ||||
3241 | aCntPrt.Pos() += pCnt->getFrameArea().Pos(); | ||||
3242 | if ( eHint == PrepareHint::FlyFrameAttributesChanged ) | ||||
3243 | { | ||||
3244 | // #i35640# - use given rectangle <rRect> instead | ||||
3245 | // of current bound rectangle | ||||
3246 | if ( aCntPrt.IsOver( rRect ) ) | ||||
3247 | pCnt->Prepare( PrepareHint::FlyFrameAttributesChanged ); | ||||
3248 | } | ||||
3249 | // #i23129# - only invalidate, if the text frame | ||||
3250 | // printing area overlaps with the given rectangle. | ||||
3251 | else if ( aCntPrt.IsOver( rRect ) ) | ||||
3252 | pCnt->Prepare( eHint, static_cast<void*>(&aCntPrt.Intersection_( rRect )) ); | ||||
3253 | if ( !pCnt->GetDrawObjs() ) | ||||
3254 | return; | ||||
3255 | |||||
3256 | const SwSortedObjs &rObjs = *pCnt->GetDrawObjs(); | ||||
3257 | for (SwAnchoredObject* pObj : rObjs) | ||||
3258 | { | ||||
3259 | if ( dynamic_cast<const SwFlyFrame*>( pObj) != nullptr ) | ||||
3260 | { | ||||
3261 | SwFlyFrame *pFly = static_cast<SwFlyFrame*>(pObj); | ||||
3262 | if ( pFly->IsFlyInContentFrame() ) | ||||
3263 | { | ||||
3264 | SwContentFrame *pContent = pFly->ContainsContent(); | ||||
3265 | while ( pContent ) | ||||
3266 | { | ||||
3267 | ::lcl_NotifyContent( pThis, pContent, rRect, eHint ); | ||||
3268 | pContent = pContent->GetNextContentFrame(); | ||||
3269 | } | ||||
3270 | } | ||||
3271 | } | ||||
3272 | } | ||||
3273 | } | ||||
3274 | |||||
3275 | void Notify_Background( const SdrObject* pObj, | ||||
3276 | SwPageFrame* pPage, | ||||
3277 | const SwRect& rRect, | ||||
3278 | const PrepareHint eHint, | ||||
3279 | const bool bInva ) | ||||
3280 | { | ||||
3281 | // If the frame was positioned correctly for the first time, do not inform the old area | ||||
3282 | if ( eHint == PrepareHint::FlyFrameLeave && rRect.Top() == FAR_AWAY(((sal_Int32) 0x7FFFFFFF) - 20000) ) | ||||
| |||||
3283 | return; | ||||
3284 | |||||
3285 | SwLayoutFrame* pArea; | ||||
3286 | SwFlyFrame *pFlyFrame = nullptr; | ||||
3287 | SwFrame* pAnchor; | ||||
3288 | if( auto pVirtFlyDrawObj = dynamic_cast<const SwVirtFlyDrawObj*>( pObj) ) | ||||
3289 | { | ||||
3290 | pFlyFrame = const_cast<SwVirtFlyDrawObj*>(pVirtFlyDrawObj)->GetFlyFrame(); | ||||
3291 | pAnchor = pFlyFrame->AnchorFrame(); | ||||
3292 | } | ||||
3293 | else | ||||
3294 | { | ||||
3295 | pFlyFrame = nullptr; | ||||
3296 | pAnchor = const_cast<SwFrame*>( | ||||
3297 | GetUserCall(pObj)->GetAnchoredObj( pObj )->GetAnchorFrame() ); | ||||
3298 | } | ||||
3299 | if( PrepareHint::FlyFrameLeave != eHint
| ||||
3300 | pArea = pAnchor->FindFlyFrame(); | ||||
3301 | else | ||||
3302 | pArea = pPage; | ||||
3303 | SwContentFrame *pCnt = nullptr; | ||||
3304 | if ( pArea ) | ||||
3305 | { | ||||
3306 | if( PrepareHint::FlyFrameArrive != eHint ) | ||||
3307 | lcl_CheckFlowBack( pArea, rRect ); | ||||
3308 | |||||
3309 | // Only the Flys following this anchor are reacting. Thus, those do not | ||||
3310 | // need to be processed. | ||||
3311 | // An exception is LEAVE, since the Fly might come "from above". | ||||
3312 | // If the anchor is positioned on the previous page, the whole page | ||||
3313 | // needs to be processed (47722). | ||||
3314 | // OD 2004-05-13 #i28701# - If the wrapping style has to be considered | ||||
3315 | // on the object positioning, the complete area has to be processed, | ||||
3316 | // because content frames before the anchor frame also have to consider | ||||
3317 | // the object for the text wrapping. | ||||
3318 | // #i3317# - The complete area has always been | ||||
3319 | // processed. | ||||
3320 | { | ||||
3321 | pCnt = pArea->ContainsContent(); | ||||
3322 | } | ||||
3323 | } | ||||
3324 | SwFrame *pLastTab = nullptr; | ||||
3325 | |||||
3326 | bool isValidTableBeforeAnchor(false); | ||||
3327 | while ( pCnt && pArea
| ||||
3328 | { | ||||
3329 | ::lcl_NotifyContent( pObj, pCnt, rRect, eHint ); | ||||
3330 | if ( pCnt->IsInTab() ) | ||||
3331 | { | ||||
3332 | SwTabFrame *pTab = pCnt->FindTabFrame(); | ||||
3333 | if ( pTab != pLastTab ) | ||||
3334 | { | ||||
3335 | pLastTab = pTab; | ||||
3336 | isValidTableBeforeAnchor = false; | ||||
3337 | if (PrepareHint::FlyFrameArrive == eHint | ||||
3338 | && pFlyFrame // TODO: do it for draw objects too? | ||||
3339 | && pTab->IsFollow() // table starts on previous page? | ||||
3340 | // "through" means they will actually overlap anyway | ||||
3341 | && css::text::WrapTextMode_THROUGH != pFlyFrame->GetFormat()->GetSurround().GetSurround() | ||||
3342 | // if it's anchored in footer it can't move to other page | ||||
3343 | && !pAnchor->FindFooterOrHeader()) | ||||
3344 | { | ||||
3345 | SwFrame * pTmp(pAnchor->GetPrev()); | ||||
3346 | while (pTmp) | ||||
3347 | { | ||||
3348 | if (pTmp == pTab) | ||||
3349 | { | ||||
3350 | // tdf#99460 the table shouldn't be moved by the fly | ||||
3351 | isValidTableBeforeAnchor = true; | ||||
3352 | break; | ||||
3353 | } | ||||
3354 | pTmp = pTmp->GetPrev(); | ||||
3355 | } | ||||
3356 | } | ||||
3357 | // #i40606# - use <GetLastBoundRect()> | ||||
3358 | // instead of <GetCurrentBoundRect()>, because a recalculation | ||||
3359 | // of the bounding rectangle isn't intended here. | ||||
3360 | if (!isValidTableBeforeAnchor | ||||
3361 | && (pTab->getFrameArea().IsOver(pObj->GetLastBoundRect()) || | ||||
3362 | pTab->getFrameArea().IsOver(rRect))) | ||||
3363 | { | ||||
3364 | if ( !pFlyFrame || !pFlyFrame->IsLowerOf( pTab ) ) | ||||
3365 | pTab->InvalidatePrt(); | ||||
3366 | } | ||||
3367 | } | ||||
3368 | SwLayoutFrame* pCell = pCnt->GetUpper(); | ||||
3369 | // #i40606# - use <GetLastBoundRect()> | ||||
3370 | // instead of <GetCurrentBoundRect()>, because a recalculation | ||||
3371 | // of the bounding rectangle isn't intended here. | ||||
3372 | if (!isValidTableBeforeAnchor
| ||||
3373 | ( pCell->getFrameArea().IsOver( pObj->GetLastBoundRect() ) || | ||||
| |||||
3374 | pCell->getFrameArea().IsOver( rRect ) ) ) | ||||
3375 | { | ||||
3376 | const SwFormatVertOrient &rOri = pCell->GetFormat()->GetVertOrient(); | ||||
3377 | if ( text::VertOrientation::NONE != rOri.GetVertOrient() ) | ||||
3378 | pCell->InvalidatePrt(); | ||||
3379 | } | ||||
3380 | } | ||||
3381 | pCnt = pCnt->GetNextContentFrame(); | ||||
3382 | } | ||||
3383 | // #128702# - make code robust | ||||
3384 | if ( pPage && pPage->GetSortedObjs() ) | ||||
3385 | { | ||||
3386 | pObj->GetOrdNum(); | ||||
3387 | const SwSortedObjs &rObjs = *pPage->GetSortedObjs(); | ||||
3388 | for (SwAnchoredObject* pAnchoredObj : rObjs) | ||||
3389 | { | ||||
3390 | if ( dynamic_cast<const SwFlyFrame*>( pAnchoredObj) != nullptr ) | ||||
3391 | { | ||||
3392 | if( pAnchoredObj->GetDrawObj() == pObj ) | ||||
3393 | continue; | ||||
3394 | SwFlyFrame *pFly = static_cast<SwFlyFrame*>(pAnchoredObj); | ||||
3395 | if ( pFly->getFrameArea().Top() == FAR_AWAY(((sal_Int32) 0x7FFFFFFF) - 20000) ) | ||||
3396 | continue; | ||||
3397 | |||||
3398 | if ( !pFlyFrame || | ||||
3399 | (!pFly->IsLowerOf( pFlyFrame ) && | ||||
3400 | pFly->GetVirtDrawObj()->GetOrdNumDirect() < pObj->GetOrdNumDirect())) | ||||
3401 | { | ||||
3402 | pCnt = pFly->ContainsContent(); | ||||
3403 | while ( pCnt ) | ||||
3404 | { | ||||
3405 | ::lcl_NotifyContent( pObj, pCnt, rRect, eHint ); | ||||
3406 | pCnt = pCnt->GetNextContentFrame(); | ||||
3407 | } | ||||
3408 | } | ||||
3409 | if( pFly->IsFlyLayFrame() ) | ||||
3410 | { | ||||
3411 | if( pFly->Lower() && pFly->Lower()->IsColumnFrame() && | ||||
3412 | pFly->getFrameArea().Bottom() >= rRect.Top() && | ||||
3413 | pFly->getFrameArea().Top() <= rRect.Bottom() && | ||||
3414 | pFly->getFrameArea().Right() >= rRect.Left() && | ||||
3415 | pFly->getFrameArea().Left() <= rRect.Right() ) | ||||
3416 | { | ||||
3417 | pFly->InvalidateSize(); | ||||
3418 | } | ||||
3419 | } | ||||
3420 | // Flys above myself might sidestep if they have an automatic | ||||
3421 | // alignment. This happens independently of my attributes since | ||||
3422 | // this might have been changed as well. | ||||
3423 | else if ( pFly->IsFlyAtContentFrame() && | ||||
3424 | pObj->GetOrdNumDirect() < | ||||
3425 | pFly->GetVirtDrawObj()->GetOrdNumDirect() && | ||||
3426 | pFlyFrame && !pFly->IsLowerOf( pFlyFrame ) ) | ||||
3427 | { | ||||
3428 | const SwFormatHoriOrient &rH = pFly->GetFormat()->GetHoriOrient(); | ||||
3429 | if ( text::HoriOrientation::NONE != rH.GetHoriOrient() && | ||||
3430 | text::HoriOrientation::CENTER != rH.GetHoriOrient() && | ||||
3431 | ( !pFly->IsAutoPos() || text::RelOrientation::CHAR != rH.GetRelationOrient() ) && | ||||
3432 | (pFly->getFrameArea().Bottom() >= rRect.Top() && | ||||
3433 | pFly->getFrameArea().Top() <= rRect.Bottom()) ) | ||||
3434 | pFly->InvalidatePos(); | ||||
3435 | } | ||||
3436 | } | ||||
3437 | } | ||||
3438 | } | ||||
3439 | if ( pFlyFrame && pAnchor->GetUpper() && pAnchor->IsInTab() )//MA_FLY_HEIGHT | ||||
3440 | pAnchor->GetUpper()->InvalidateSize(); | ||||
3441 | |||||
3442 | // #i82258# - make code robust | ||||
3443 | SwViewShell* pSh = nullptr; | ||||
3444 | if ( bInva && pPage && | ||||
3445 | nullptr != (pSh = pPage->getRootFrame()->GetCurrShell()) ) | ||||
3446 | { | ||||
3447 | pSh->InvalidateWindows( rRect ); | ||||
3448 | } | ||||
3449 | } | ||||
3450 | |||||
3451 | /// Provides the Upper of an anchor in paragraph-bound objects. If the latter | ||||
3452 | /// is a chained border or a footnote, the "virtual" Upper might be returned. | ||||
3453 | const SwFrame* GetVirtualUpper( const SwFrame* pFrame, const Point& rPos ) | ||||
3454 | { | ||||
3455 | if( pFrame->IsTextFrame() ) | ||||
3456 | { | ||||
3457 | pFrame = pFrame->GetUpper(); | ||||
3458 | if( !pFrame->getFrameArea().IsInside( rPos ) ) | ||||
3459 | { | ||||
3460 | if( pFrame->IsFootnoteFrame() ) | ||||
3461 | { | ||||
3462 | const SwFootnoteFrame* pTmp = static_cast<const SwFootnoteFrame*>(pFrame)->GetFollow(); | ||||
3463 | while( pTmp ) | ||||
3464 | { | ||||
3465 | if( pTmp->getFrameArea().IsInside( rPos ) ) | ||||
3466 | return pTmp; | ||||
3467 | pTmp = pTmp->GetFollow(); | ||||
3468 | } | ||||
3469 | } | ||||
3470 | else | ||||
3471 | { | ||||
3472 | SwFlyFrame* pTmp = const_cast<SwFlyFrame*>(pFrame->FindFlyFrame()); | ||||
3473 | while( pTmp ) | ||||
3474 | { | ||||
3475 | if( pTmp->getFrameArea().IsInside( rPos ) ) | ||||
3476 | return pTmp; | ||||
3477 | pTmp = pTmp->GetNextLink(); | ||||
3478 | } | ||||
3479 | } | ||||
3480 | } | ||||
3481 | } | ||||
3482 | return pFrame; | ||||
3483 | } | ||||
3484 | |||||
3485 | bool Is_Lower_Of(const SwFrame *pCurrFrame, const SdrObject* pObj) | ||||
3486 | { | ||||
3487 | Point aPos; | ||||
3488 | const SwFrame* pFrame; | ||||
3489 | if (const SwVirtFlyDrawObj *pFlyDrawObj = dynamic_cast<const SwVirtFlyDrawObj*>(pObj)) | ||||
3490 | { | ||||
3491 | const SwFlyFrame* pFly = pFlyDrawObj->GetFlyFrame(); | ||||
3492 | pFrame = pFly->GetAnchorFrame(); | ||||
3493 | aPos = pFly->getFrameArea().Pos(); | ||||
3494 | } | ||||
3495 | else | ||||
3496 | { | ||||
3497 | pFrame = static_cast<SwDrawContact*>(GetUserCall(pObj))->GetAnchorFrame(pObj); | ||||
3498 | aPos = pObj->GetCurrentBoundRect().TopLeft(); | ||||
3499 | } | ||||
3500 | OSL_ENSURE( pFrame, "8-( Fly is lost in Space." )do { if (true && (!(pFrame))) { sal_detail_logFormat( (SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "3500" ": "), "%s", "8-( Fly is lost in Space."); } } while (false); | ||||
3501 | pFrame = GetVirtualUpper( pFrame, aPos ); | ||||
3502 | do | ||||
3503 | { if ( pFrame == pCurrFrame ) | ||||
3504 | return true; | ||||
3505 | if( pFrame->IsFlyFrame() ) | ||||
3506 | { | ||||
3507 | aPos = pFrame->getFrameArea().Pos(); | ||||
3508 | pFrame = GetVirtualUpper( static_cast<const SwFlyFrame*>(pFrame)->GetAnchorFrame(), aPos ); | ||||
3509 | } | ||||
3510 | else | ||||
3511 | pFrame = pFrame->GetUpper(); | ||||
3512 | } while ( pFrame ); | ||||
3513 | return false; | ||||
3514 | } | ||||
3515 | |||||
3516 | /// provides the area of a frame in that no Fly from another area can overlap | ||||
3517 | const SwFrame *FindContext( const SwFrame *pFrame, SwFrameType nAdditionalContextType ) | ||||
3518 | { | ||||
3519 | const SwFrameType nTyp = SwFrameType::Root | SwFrameType::Header | SwFrameType::Footer | SwFrameType::FtnCont | | ||||
3520 | SwFrameType::Ftn | SwFrameType::Fly | | ||||
3521 | SwFrameType::Tab | SwFrameType::Row | SwFrameType::Cell | | ||||
3522 | nAdditionalContextType; | ||||
3523 | do | ||||
3524 | { if ( pFrame->GetType() & nTyp ) | ||||
3525 | break; | ||||
3526 | pFrame = pFrame->GetUpper(); | ||||
3527 | } while( pFrame ); | ||||
3528 | return pFrame; | ||||
3529 | } | ||||
3530 | |||||
3531 | bool IsFrameInSameContext( const SwFrame *pInnerFrame, const SwFrame *pFrame ) | ||||
3532 | { | ||||
3533 | const SwFrame *pContext = FindContext( pInnerFrame, SwFrameType::None ); | ||||
3534 | |||||
3535 | const SwFrameType nTyp = SwFrameType::Root | SwFrameType::Header | SwFrameType::Footer | SwFrameType::FtnCont | | ||||
3536 | SwFrameType::Ftn | SwFrameType::Fly | | ||||
3537 | SwFrameType::Tab | SwFrameType::Row | SwFrameType::Cell; | ||||
3538 | do | ||||
3539 | { if ( pFrame->GetType() & nTyp ) | ||||
3540 | { | ||||
3541 | if( pFrame == pContext ) | ||||
3542 | return true; | ||||
3543 | if( pFrame->IsCellFrame() ) | ||||
3544 | return false; | ||||
3545 | } | ||||
3546 | if( pFrame->IsFlyFrame() ) | ||||
3547 | { | ||||
3548 | Point aPos( pFrame->getFrameArea().Pos() ); | ||||
3549 | pFrame = GetVirtualUpper( static_cast<const SwFlyFrame*>(pFrame)->GetAnchorFrame(), aPos ); | ||||
3550 | } | ||||
3551 | else | ||||
3552 | pFrame = pFrame->GetUpper(); | ||||
3553 | } while( pFrame ); | ||||
3554 | |||||
3555 | return false; | ||||
3556 | } | ||||
3557 | |||||
3558 | static SwTwips lcl_CalcCellRstHeight( SwLayoutFrame *pCell ) | ||||
3559 | { | ||||
3560 | SwFrame *pLow = pCell->Lower(); | ||||
3561 | if ( pLow && (pLow->IsContentFrame() || pLow->IsSctFrame()) ) | ||||
3562 | { | ||||
3563 | long nHeight = 0, nFlyAdd = 0; | ||||
3564 | do | ||||
3565 | { | ||||
3566 | long nLow = pLow->getFrameArea().Height(); | ||||
3567 | if( pLow->IsTextFrame() && static_cast<SwTextFrame*>(pLow)->IsUndersized() ) | ||||
3568 | nLow += static_cast<SwTextFrame*>(pLow)->GetParHeight()-pLow->getFramePrintArea().Height(); | ||||
3569 | else if( pLow->IsSctFrame() && static_cast<SwSectionFrame*>(pLow)->IsUndersized() ) | ||||
3570 | nLow += static_cast<SwSectionFrame*>(pLow)->Undersize(); | ||||
3571 | nFlyAdd = std::max( 0L, nFlyAdd - nLow ); | ||||
3572 | nFlyAdd = std::max( nFlyAdd, ::CalcHeightWithFlys( pLow ) ); | ||||
3573 | nHeight += nLow; | ||||
3574 | pLow = pLow->GetNext(); | ||||
3575 | } while ( pLow ); | ||||
3576 | if ( nFlyAdd ) | ||||
3577 | nHeight += nFlyAdd; | ||||
3578 | |||||
3579 | // The border cannot be calculated based on PrtArea and Frame, since both can be invalid. | ||||
3580 | SwBorderAttrAccess aAccess( SwFrame::GetCache(), pCell ); | ||||
3581 | const SwBorderAttrs &rAttrs = *aAccess.Get(); | ||||
3582 | nHeight += rAttrs.CalcTop() + rAttrs.CalcBottom(); | ||||
3583 | |||||
3584 | return pCell->getFrameArea().Height() - nHeight; | ||||
3585 | } | ||||
3586 | else | ||||
3587 | { | ||||
3588 | long nRstHeight = 0; | ||||
3589 | while (pLow && pLow->IsLayoutFrame()) | ||||
3590 | { | ||||
3591 | nRstHeight += ::CalcRowRstHeight(static_cast<SwLayoutFrame*>(pLow)); | ||||
3592 | pLow = pLow->GetNext(); | ||||
3593 | } | ||||
3594 | return nRstHeight; | ||||
3595 | } | ||||
3596 | } | ||||
3597 | |||||
3598 | SwTwips CalcRowRstHeight( SwLayoutFrame *pRow ) | ||||
3599 | { | ||||
3600 | SwFrame *pLow = pRow->Lower(); | ||||
3601 | if (!(pLow && pLow->IsLayoutFrame())) | ||||
3602 | { | ||||
3603 | return 0; | ||||
3604 | } | ||||
3605 | SwTwips nRstHeight = LONG_MAX9223372036854775807L; | ||||
3606 | while (pLow && pLow->IsLayoutFrame()) | ||||
3607 | { | ||||
3608 | nRstHeight = std::min(nRstHeight, ::lcl_CalcCellRstHeight(static_cast<SwLayoutFrame*>(pLow))); | ||||
3609 | pLow = pLow->GetNext(); | ||||
3610 | } | ||||
3611 | return nRstHeight; | ||||
3612 | } | ||||
3613 | |||||
3614 | const SwFrame* FindPage( const SwRect &rRect, const SwFrame *pPage ) | ||||
3615 | { | ||||
3616 | if ( !rRect.IsOver( pPage->getFrameArea() ) ) | ||||
3617 | { | ||||
3618 | const SwRootFrame* pRootFrame = static_cast<const SwRootFrame*>(pPage->GetUpper()); | ||||
3619 | const SwFrame* pTmpPage = pRootFrame ? pRootFrame->GetPageAtPos( rRect.TopLeft(), &rRect.SSize(), true ) : nullptr; | ||||
3620 | if ( pTmpPage ) | ||||
3621 | pPage = pTmpPage; | ||||
3622 | } | ||||
3623 | |||||
3624 | return pPage; | ||||
3625 | } | ||||
3626 | |||||
3627 | namespace { | ||||
3628 | |||||
3629 | class SwFrameHolder : private SfxListener | ||||
3630 | { | ||||
3631 | SwFrame* pFrame; | ||||
3632 | bool bSet; | ||||
3633 | virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override; | ||||
3634 | public: | ||||
3635 | SwFrameHolder() : pFrame(nullptr), bSet(false) {} | ||||
3636 | void SetFrame( SwFrame* pHold ); | ||||
3637 | SwFrame* GetFrame() { return pFrame; } | ||||
3638 | void Reset(); | ||||
3639 | bool IsSet() const { return bSet; } | ||||
3640 | }; | ||||
3641 | |||||
3642 | } | ||||
3643 | |||||
3644 | void SwFrameHolder::SetFrame( SwFrame* pHold ) | ||||
3645 | { | ||||
3646 | bSet = true; | ||||
3647 | if (pFrame != pHold) | ||||
3648 | { | ||||
3649 | if (pFrame) | ||||
3650 | EndListening(*pFrame); | ||||
3651 | StartListening(*pHold); | ||||
3652 | pFrame = pHold; | ||||
3653 | } | ||||
3654 | } | ||||
3655 | |||||
3656 | void SwFrameHolder::Reset() | ||||
3657 | { | ||||
3658 | if (pFrame) | ||||
3659 | EndListening(*pFrame); | ||||
3660 | bSet = false; | ||||
3661 | pFrame = nullptr; | ||||
3662 | } | ||||
3663 | |||||
3664 | void SwFrameHolder::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) | ||||
3665 | { | ||||
3666 | if ( rHint.GetId() == SfxHintId::Dying && &rBC == pFrame ) | ||||
3667 | { | ||||
3668 | pFrame = nullptr; | ||||
3669 | } | ||||
3670 | } | ||||
3671 | |||||
3672 | SwFrame* GetFrameOfModify(SwRootFrame const*const pLayout, SwModify const& rMod, | ||||
3673 | SwFrameType const nFrameType, SwPosition const*const pPos, | ||||
3674 | std::pair<Point, bool> const*const pViewPosAndCalcFrame) | ||||
3675 | { | ||||
3676 | SwFrame *pMinFrame = nullptr, *pTmpFrame; | ||||
3677 | SwFrameHolder aHolder; | ||||
3678 | SwRect aCalcRect; | ||||
3679 | bool bClientIterChanged = false; | ||||
3680 | |||||
3681 | SwIterator<SwFrame, SwModify, sw::IteratorMode::UnwrapMulti> aIter(rMod); | ||||
3682 | do { | ||||
3683 | pMinFrame = nullptr; | ||||
3684 | aHolder.Reset(); | ||||
3685 | sal_uInt64 nMinDist = 0; | ||||
3686 | bClientIterChanged = false; | ||||
3687 | |||||
3688 | for( pTmpFrame = aIter.First(); pTmpFrame; pTmpFrame = aIter.Next() ) | ||||
3689 | { | ||||
3690 | if( pTmpFrame->GetType() & nFrameType && | ||||
3691 | ( !pLayout || pLayout == pTmpFrame->getRootFrame() ) && | ||||
3692 | (!pTmpFrame->IsFlowFrame() || | ||||
3693 | !SwFlowFrame::CastFlowFrame( pTmpFrame )->IsFollow() )) | ||||
3694 | { | ||||
3695 | if (pViewPosAndCalcFrame) | ||||
3696 | { | ||||
3697 | // watch for Frame being deleted | ||||
3698 | if ( pMinFrame ) | ||||
3699 | aHolder.SetFrame( pMinFrame ); | ||||
3700 | else | ||||
3701 | aHolder.Reset(); | ||||
3702 | |||||
3703 | if (pViewPosAndCalcFrame->second) | ||||
3704 | { | ||||
3705 | // tdf#108118 prevent recursion | ||||
3706 | DisableCallbackAction a(*pTmpFrame->getRootFrame()); | ||||
3707 | // - format parent Writer | ||||
3708 | // fly frame, if it isn't been formatted yet. | ||||
3709 | // Note: The Writer fly frame could be the frame itself. | ||||
3710 | SwFlyFrame* pFlyFrame( pTmpFrame->FindFlyFrame() ); | ||||
3711 | if ( pFlyFrame && | ||||
3712 | pFlyFrame->getFrameArea().Pos().X() == FAR_AWAY(((sal_Int32) 0x7FFFFFFF) - 20000) && | ||||
3713 | pFlyFrame->getFrameArea().Pos().Y() == FAR_AWAY(((sal_Int32) 0x7FFFFFFF) - 20000) ) | ||||
3714 | { | ||||
3715 | SwObjectFormatter::FormatObj( *pFlyFrame ); | ||||
3716 | } | ||||
3717 | pTmpFrame->Calc(pLayout ? pLayout->GetCurrShell()->GetOut() : nullptr); | ||||
3718 | } | ||||
3719 | |||||
3720 | // aIter.IsChanged checks if the current pTmpFrame has been deleted while | ||||
3721 | // it is the current iterator | ||||
3722 | // FrameHolder watches for deletion of the current pMinFrame | ||||
3723 | if( aIter.IsChanged() || ( aHolder.IsSet() && !aHolder.GetFrame() ) ) | ||||
3724 | { | ||||
3725 | // restart iteration | ||||
3726 | bClientIterChanged = true; | ||||
3727 | break; | ||||
3728 | } | ||||
3729 | |||||
3730 | // for Flys go via the parent if the Fly is not yet "formatted" | ||||
3731 | if (!pViewPosAndCalcFrame->second && | ||||
3732 | pTmpFrame->GetType() & SwFrameType::Fly && | ||||
3733 | static_cast<SwFlyFrame*>(pTmpFrame)->GetAnchorFrame() && | ||||
3734 | FAR_AWAY(((sal_Int32) 0x7FFFFFFF) - 20000) == pTmpFrame->getFrameArea().Pos().getX() && | ||||
3735 | FAR_AWAY(((sal_Int32) 0x7FFFFFFF) - 20000) == pTmpFrame->getFrameArea().Pos().getY() ) | ||||
3736 | aCalcRect = static_cast<SwFlyFrame*>(pTmpFrame)->GetAnchorFrame()->getFrameArea(); | ||||
3737 | else | ||||
3738 | aCalcRect = pTmpFrame->getFrameArea(); | ||||
3739 | |||||
3740 | if (aCalcRect.IsInside(pViewPosAndCalcFrame->first)) | ||||
3741 | { | ||||
3742 | pMinFrame = pTmpFrame; | ||||
3743 | break; | ||||
3744 | } | ||||
3745 | |||||
3746 | // Point not in rectangle. Compare distances: | ||||
3747 | const Point aCalcRectCenter = aCalcRect.Center(); | ||||
3748 | const Point aDiff = aCalcRectCenter - pViewPosAndCalcFrame->first; | ||||
3749 | const sal_uInt64 nCurrentDist = sal_Int64(aDiff.getX()) * sal_Int64(aDiff.getX()) + sal_Int64(aDiff.getY()) * sal_Int64(aDiff.getY()); // opt: no sqrt | ||||
3750 | if ( !pMinFrame || nCurrentDist < nMinDist ) | ||||
3751 | { | ||||
3752 | pMinFrame = pTmpFrame; | ||||
3753 | nMinDist = nCurrentDist; | ||||
3754 | } | ||||
3755 | } | ||||
3756 | else | ||||
3757 | { | ||||
3758 | // if no pViewPosAndCalcFrame is provided, take the first one | ||||
3759 | pMinFrame = pTmpFrame; | ||||
3760 | break; | ||||
3761 | } | ||||
3762 | } | ||||
3763 | } | ||||
3764 | } while( bClientIterChanged ); | ||||
3765 | |||||
3766 | if( pPos && pMinFrame && pMinFrame->IsTextFrame() ) | ||||
3767 | return static_cast<SwTextFrame*>(pMinFrame)->GetFrameAtPos( *pPos ); | ||||
3768 | |||||
3769 | return pMinFrame; | ||||
3770 | } | ||||
3771 | |||||
3772 | bool IsExtraData( const SwDoc *pDoc ) | ||||
3773 | { | ||||
3774 | const SwLineNumberInfo &rInf = pDoc->GetLineNumberInfo(); | ||||
3775 | return rInf.IsPaintLineNumbers() || | ||||
3776 | rInf.IsCountInFlys() || | ||||
3777 | (static_cast<sal_Int16>(SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule ::Writer)))->GetRedlineMarkPos()) != text::HoriOrientation::NONE && | ||||
3778 | !pDoc->getIDocumentRedlineAccess().GetRedlineTable().empty()); | ||||
3779 | } | ||||
3780 | |||||
3781 | // OD 22.09.2003 #110978# | ||||
3782 | SwRect SwPageFrame::PrtWithoutHeaderAndFooter() const | ||||
3783 | { | ||||
3784 | SwRect aPrtWithoutHeaderFooter( getFramePrintArea() ); | ||||
3785 | aPrtWithoutHeaderFooter.Pos() += getFrameArea().Pos(); | ||||
3786 | |||||
3787 | const SwFrame* pLowerFrame = Lower(); | ||||
3788 | while ( pLowerFrame ) | ||||
3789 | { | ||||
3790 | // Note: independent on text direction page header and page footer are | ||||
3791 | // always at top respectively at bottom of the page frame. | ||||
3792 | if ( pLowerFrame->IsHeaderFrame() ) | ||||
3793 | { | ||||
3794 | aPrtWithoutHeaderFooter.AddTop( pLowerFrame->getFrameArea().Height() ); | ||||
3795 | } | ||||
3796 | if ( pLowerFrame->IsFooterFrame() ) | ||||
3797 | { | ||||
3798 | aPrtWithoutHeaderFooter.AddBottom( - pLowerFrame->getFrameArea().Height() ); | ||||
3799 | } | ||||
3800 | |||||
3801 | pLowerFrame = pLowerFrame->GetNext(); | ||||
3802 | } | ||||
3803 | |||||
3804 | return aPrtWithoutHeaderFooter; | ||||
3805 | } | ||||
3806 | |||||
3807 | /** method to determine the spacing values of a frame | ||||
3808 | |||||
3809 | OD 2004-03-10 #i28701# | ||||
3810 | OD 2009-08-28 #i102458# | ||||
3811 | Add output parameter <obIsLineSpacingProportional> | ||||
3812 | */ | ||||
3813 | void GetSpacingValuesOfFrame( const SwFrame& rFrame, | ||||
3814 | SwTwips& onLowerSpacing, | ||||
3815 | SwTwips& onLineSpacing, | ||||
3816 | bool& obIsLineSpacingProportional, | ||||
3817 | bool bIdenticalStyles ) | ||||
3818 | { | ||||
3819 | if ( !rFrame.IsFlowFrame() ) | ||||
3820 | { | ||||
3821 | onLowerSpacing = 0; | ||||
3822 | onLineSpacing = 0; | ||||
3823 | } | ||||
3824 | else | ||||
3825 | { | ||||
3826 | const SvxULSpaceItem& rULSpace = rFrame.GetAttrSet()->GetULSpace(); | ||||
3827 | // check contextual spacing if the style of actual and next paragraphs are identical | ||||
3828 | if (bIdenticalStyles) | ||||
3829 | onLowerSpacing = (rULSpace.GetContext() ? 0 : rULSpace.GetLower()); | ||||
3830 | else | ||||
3831 | onLowerSpacing = rULSpace.GetLower(); | ||||
3832 | |||||
3833 | onLineSpacing = 0; | ||||
3834 | obIsLineSpacingProportional = false; | ||||
3835 | if ( rFrame.IsTextFrame() ) | ||||
3836 | { | ||||
3837 | onLineSpacing = static_cast<const SwTextFrame&>(rFrame).GetLineSpace(); | ||||
3838 | obIsLineSpacingProportional = | ||||
3839 | onLineSpacing != 0 && | ||||
3840 | static_cast<const SwTextFrame&>(rFrame).GetLineSpace( true ) == 0; | ||||
3841 | } | ||||
3842 | |||||
3843 | OSL_ENSURE( onLowerSpacing >= 0 && onLineSpacing >= 0,do { if (true && (!(onLowerSpacing >= 0 && onLineSpacing >= 0))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "3844" ": "), "%s", "<GetSpacingValuesOfFrame(..)> - spacing values aren't positive!" ); } } while (false) | ||||
3844 | "<GetSpacingValuesOfFrame(..)> - spacing values aren't positive!" )do { if (true && (!(onLowerSpacing >= 0 && onLineSpacing >= 0))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "3844" ": "), "%s", "<GetSpacingValuesOfFrame(..)> - spacing values aren't positive!" ); } } while (false); | ||||
3845 | } | ||||
3846 | } | ||||
3847 | |||||
3848 | /// get the content of the table cell, skipping content from nested tables | ||||
3849 | const SwContentFrame* GetCellContent( const SwLayoutFrame& rCell ) | ||||
3850 | { | ||||
3851 | const SwContentFrame* pContent = rCell.ContainsContent(); | ||||
3852 | const SwTabFrame* pTab = rCell.FindTabFrame(); | ||||
3853 | |||||
3854 | while ( pContent && rCell.IsAnLower( pContent ) ) | ||||
3855 | { | ||||
3856 | const SwTabFrame* pTmpTab = pContent->FindTabFrame(); | ||||
3857 | if ( pTmpTab != pTab ) | ||||
3858 | { | ||||
3859 | SwFrame const*const pTmp = pTmpTab->FindLastContentOrTable(); | ||||
3860 | if (pTmp) | ||||
3861 | { | ||||
3862 | pContent = pTmp->FindNextCnt(); | ||||
3863 | } | ||||
3864 | else | ||||
3865 | { | ||||
3866 | pContent = nullptr; | ||||
3867 | } | ||||
3868 | } | ||||
3869 | else | ||||
3870 | break; | ||||
3871 | } | ||||
3872 | return pContent; | ||||
3873 | } | ||||
3874 | |||||
3875 | SwDeletionChecker::SwDeletionChecker(const SwFrame* pFrame) | ||||
3876 | : mpFrame( pFrame ) | ||||
3877 | , mpRegIn( pFrame | ||||
3878 | ? pFrame->IsTextFrame() | ||||
3879 | // sw_redlinehide: GetDep() may be a member of SwTextFrame! | ||||
3880 | ? static_cast<SwTextFrame const*>(pFrame)->GetTextNodeFirst() | ||||
3881 | : const_cast<SwFrame*>(pFrame)->GetDep() | ||||
3882 | : nullptr ) | ||||
3883 | { | ||||
3884 | } | ||||
3885 | |||||
3886 | /// Can be used to check if a frame has been deleted | ||||
3887 | bool SwDeletionChecker::HasBeenDeleted() const | ||||
3888 | { | ||||
3889 | if ( !mpFrame || !mpRegIn ) | ||||
3890 | return false; | ||||
3891 | |||||
3892 | SwIterator<SwFrame, SwModify, sw::IteratorMode::UnwrapMulti> aIter(*mpRegIn); | ||||
3893 | SwFrame* pLast = aIter.First(); | ||||
3894 | while ( pLast ) | ||||
3895 | { | ||||
3896 | if ( pLast == mpFrame ) | ||||
3897 | return false; | ||||
3898 | pLast = aIter.Next(); | ||||
3899 | } | ||||
3900 | |||||
3901 | return true; | ||||
3902 | } | ||||
3903 | |||||
3904 | /* 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: */ |