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