LibreOffice Module sw (master)  1
objectformattertxtfrm.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 
21 #include <IDocumentUndoRedo.hxx>
22 #include <sortedobjs.hxx>
23 #include <rootfrm.hxx>
24 #include <anchoredobject.hxx>
25 #include <txtfrm.hxx>
26 #include <pagefrm.hxx>
27 #include <rowfrm.hxx>
28 #include <layouter.hxx>
29 #include <fmtanchr.hxx>
31 #include <fmtfollowtextflow.hxx>
32 #include <layact.hxx>
33 #include <ftnfrm.hxx>
34 #include <fmtornt.hxx>
35 #include <textboxhelper.hxx>
36 #include <osl/diagnose.h>
37 
38 using namespace ::com::sun::star;
39 
40 namespace {
41 
42 // little helper class to forbid follow formatting for the given text frame
43 class SwForbidFollowFormat
44 {
45 private:
46  SwTextFrame& mrTextFrame;
47  const bool bOldFollowFormatAllowed;
48 
49 public:
50  explicit SwForbidFollowFormat( SwTextFrame& _rTextFrame )
51  : mrTextFrame( _rTextFrame ),
52  bOldFollowFormatAllowed( _rTextFrame.FollowFormatAllowed() )
53  {
54  mrTextFrame.ForbidFollowFormat();
55  }
56 
57  ~SwForbidFollowFormat()
58  {
59  if ( bOldFollowFormatAllowed )
60  {
61  mrTextFrame.AllowFollowFormat();
62  }
63  }
64 };
65 
66 }
67 
69  const SwPageFrame& _rPageFrame,
70  SwTextFrame* _pMasterAnchorTextFrame,
71  SwLayAction* _pLayAction )
72  : SwObjectFormatter( _rPageFrame, _pLayAction, true ),
73  mrAnchorTextFrame( _rAnchorTextFrame ),
74  mpMasterAnchorTextFrame( _pMasterAnchorTextFrame )
75 {
76 }
77 
79 {
80 }
81 
82 std::unique_ptr<SwObjectFormatterTextFrame> SwObjectFormatterTextFrame::CreateObjFormatter(
83  SwTextFrame& _rAnchorTextFrame,
84  const SwPageFrame& _rPageFrame,
85  SwLayAction* _pLayAction )
86 {
87  std::unique_ptr<SwObjectFormatterTextFrame> pObjFormatter;
88 
89  // determine 'master' of <_rAnchorTextFrame>, if anchor frame is a follow text frame.
90  SwTextFrame* pMasterOfAnchorFrame = nullptr;
91  if ( _rAnchorTextFrame.IsFollow() )
92  {
93  pMasterOfAnchorFrame = _rAnchorTextFrame.FindMaster();
94  while ( pMasterOfAnchorFrame && pMasterOfAnchorFrame->IsFollow() )
95  {
96  pMasterOfAnchorFrame = pMasterOfAnchorFrame->FindMaster();
97  }
98  }
99 
100  // create object formatter, if floating screen objects are registered
101  // at anchor frame (or at 'master' anchor frame)
102  if ( _rAnchorTextFrame.GetDrawObjs() ||
103  ( pMasterOfAnchorFrame && pMasterOfAnchorFrame->GetDrawObjs() ) )
104  {
105  pObjFormatter.reset(
106  new SwObjectFormatterTextFrame( _rAnchorTextFrame, _rPageFrame,
107  pMasterOfAnchorFrame, _pLayAction ));
108  }
109 
110  return pObjFormatter;
111 }
112 
114 {
115  return mrAnchorTextFrame;
116 }
117 
118 // #i40147# - add parameter <_bCheckForMovedFwd>.
120  const bool _bCheckForMovedFwd )
121 {
122  // consider, if the layout action has to be
123  // restarted due to a delete of a page frame.
124  if ( GetLayAction() && GetLayAction()->IsAgain() )
125  {
126  return false;
127  }
128 
129  bool bSuccess( true );
130 
131  if ( _rAnchoredObj.IsFormatPossible() )
132  {
133  _rAnchoredObj.SetRestartLayoutProcess( false );
134 
135  FormatObj_( _rAnchoredObj );
136  // consider, if the layout action has to be
137  // restarted due to a delete of a page frame.
138  if ( GetLayAction() && GetLayAction()->IsAgain() )
139  {
140  return false;
141  }
142 
143  // check, if layout process has to be restarted.
144  // if yes, perform needed invalidations.
145 
146  // no restart of layout process,
147  // if anchored object is anchored inside a Writer fly frame,
148  // its position is already locked, and it follows the text flow.
149  const bool bRestart =
150  _rAnchoredObj.RestartLayoutProcess() &&
151  !( _rAnchoredObj.PositionLocked() &&
152  _rAnchoredObj.GetAnchorFrame()->IsInFly() &&
153  _rAnchoredObj.GetFrameFormat().GetFollowTextFlow().GetValue() );
154  if ( bRestart )
155  {
156  bSuccess = false;
157  InvalidatePrevObjs( _rAnchoredObj );
158  InvalidateFollowObjs( _rAnchoredObj );
159  }
160 
161  // format anchor text frame, if wrapping style influence of the object
162  // has to be considered and it's <NONE_SUCCESSIVE_POSITIONED>
163  // #i3317# - consider also anchored objects, whose
164  // wrapping style influence is temporarily considered.
165  // #i40147# - consider also anchored objects, for
166  // whose the check of a moved forward anchor frame is requested.
167  // revise decision made for i3317:
168  // anchored objects, whose wrapping style influence is temporarily considered,
169  // have to be considered in method <SwObjectFormatterTextFrame::DoFormatObjs()>
170  if ( bSuccess &&
171  _rAnchoredObj.ConsiderObjWrapInfluenceOnObjPos() &&
172  ( _bCheckForMovedFwd ||
173  _rAnchoredObj.GetFrameFormat().GetWrapInfluenceOnObjPos().
174  // #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE
175  GetWrapInfluenceOnObjPos( true ) ==
176  // #i35017# - constant name has changed
177  text::WrapInfluenceOnPosition::ONCE_SUCCESSIVE ) )
178  {
179  // #i26945# - check conditions for move forward of
180  // anchor text frame
181  // determine, if anchor text frame has previous frame
182  const bool bDoesAnchorHadPrev = ( mrAnchorTextFrame.GetIndPrev() != nullptr );
183 
184  // #i40141# - use new method - it also formats the
185  // section the anchor frame is in.
187 
188  // #i35911#
189  if ( _rAnchoredObj.HasClearedEnvironment() )
190  {
191  _rAnchoredObj.SetClearedEnvironment( true );
192  // #i44049# - consider, that anchor frame
193  // could already been marked to move forward.
194  SwPageFrame* pAnchorPageFrame( mrAnchorTextFrame.FindPageFrame() );
195  if ( pAnchorPageFrame != _rAnchoredObj.GetPageFrame() )
196  {
197  bool bInsert( true );
198  sal_uInt32 nToPageNum( 0 );
199  const SwDoc& rDoc = *(GetPageFrame().GetFormat()->GetDoc());
201  rDoc, mrAnchorTextFrame, nToPageNum ) )
202  {
203  if ( nToPageNum < pAnchorPageFrame->GetPhyPageNum() )
205  else
206  bInsert = false;
207  }
208  if ( bInsert )
209  {
211  pAnchorPageFrame->GetPhyPageNum() );
213  bSuccess = false;
214  InvalidatePrevObjs( _rAnchoredObj );
215  InvalidateFollowObjs( _rAnchoredObj );
216  }
217  else
218  {
219  OSL_FAIL( "<SwObjectFormatterTextFrame::DoFormatObj(..)> - anchor frame not marked to move forward" );
220  }
221  }
222  }
223  else if ( !mrAnchorTextFrame.IsFollow() && bDoesAnchorHadPrev )
224  {
225  // index of anchored object in collection of page numbers and
226  // anchor types
227  sal_uInt32 nIdx( CountOfCollected() );
228  OSL_ENSURE( nIdx > 0,
229  "<SwObjectFormatterTextFrame::DoFormatObj(..)> - anchored object not collected!?" );
230  --nIdx;
231 
232  sal_uInt32 nToPageNum( 0 );
233  // #i43913#
234  bool bDummy( false );
235  // #i58182# - consider new method signature
237  GetPgNumOfCollected( nIdx ),
239  nToPageNum, bDummy ) )
240  {
241  // #i49987# - consider, that anchor frame
242  // could already been marked to move forward.
243  bool bInsert( true );
244  sal_uInt32 nMovedFwdToPageNum( 0 );
245  const SwDoc& rDoc = *(GetPageFrame().GetFormat()->GetDoc());
247  rDoc, mrAnchorTextFrame, nMovedFwdToPageNum ) )
248  {
249  if ( nMovedFwdToPageNum < nToPageNum )
251  else
252  bInsert = false;
253  }
254  if ( bInsert )
255  {
256  // Indicate that anchor text frame has to move forward and
257  // invalidate its position to force a re-format.
259  nToPageNum );
261 
262  // Indicate restart of the layout process
263  bSuccess = false;
264 
265  // If needed, invalidate previous objects anchored at same anchor
266  // text frame.
267  InvalidatePrevObjs( _rAnchoredObj );
268 
269  // Invalidate object and following objects for the restart of the
270  // layout process
271  InvalidateFollowObjs( _rAnchoredObj );
272  }
273  else
274  {
275  OSL_FAIL( "<SwObjectFormatterTextFrame::DoFormatObj(..)> - anchor frame not marked to move forward" );
276  }
277  }
278  }
279  // i40155# - mark anchor frame not to wrap around
280  // objects under the condition, that its follow contains all its text.
281  else if ( !mrAnchorTextFrame.IsFollow() &&
284  {
288  }
289  }
290  }
291 
292  return bSuccess;
293 }
294 
296 {
298  {
299  if ( GetLayAction() &&
301  {
302  // notify layout action, thus is can restart the layout process on
303  // a previous page.
304  GetLayAction()->SetAgain();
305  }
306  else
307  {
308  // the anchor text frame has to be valid, thus assert.
309  OSL_FAIL( "<SwObjectFormatterTextFrame::DoFormatObjs()> called for invalidate anchor text frame." );
310  }
311 
312  return false;
313  }
314 
315  bool bSuccess( true );
316 
317  if ( mrAnchorTextFrame.IsFollow() )
318  {
319  // Only floating screen objects anchored as-character are directly
320  // registered at a follow text frame. The other floating screen objects
321  // are registered at the 'master' anchor text frame.
322  // Thus, format the other floating screen objects through the 'master'
323  // anchor text frame
324  OSL_ENSURE( mpMasterAnchorTextFrame,
325  "SwObjectFormatterTextFrame::DoFormatObjs() - missing 'master' anchor text frame" );
327 
328  if ( bSuccess )
329  {
330  // format of as-character anchored floating screen objects - no failure
331  // expected on the format of these objects.
332  bSuccess = FormatObjsAtFrame_();
333  }
334  }
335  else
336  {
337  bSuccess = FormatObjsAtFrame_();
338  }
339 
340  // consider anchored objects, whose wrapping style influence are temporarily
341  // considered.
342  if ( bSuccess &&
343  ( ConsiderWrapOnObjPos() ||
346  {
347  const bool bDoesAnchorHadPrev = ( mrAnchorTextFrame.GetIndPrev() != nullptr );
348 
349  // Format anchor text frame after its objects are formatted.
350  // Note: The format of the anchor frame also formats the invalid
351  // previous frames of the anchor frame. The format of the previous
352  // frames is needed to get a correct result of format of the
353  // anchor frame for the following check for moved forward anchors
354  // #i40141# - use new method - it also formats the
355  // section the anchor frame is in.
357 
358  sal_uInt32 nToPageNum( 0 );
359  // #i43913#
360  bool bInFollow( false );
361  SwAnchoredObject* pObj = nullptr;
362  if ( !mrAnchorTextFrame.IsFollow() )
363  {
365  // #i35017# - constant name has changed
366  text::WrapInfluenceOnPosition::ONCE_CONCURRENT,
367  nToPageNum, bInFollow );
368  }
369  // #i35911#
370  if ( pObj && pObj->HasClearedEnvironment() )
371  {
372  pObj->SetClearedEnvironment( true );
373  // #i44049# - consider, that anchor frame
374  // could already been marked to move forward.
375  SwPageFrame* pAnchorPageFrame( mrAnchorTextFrame.FindPageFrame() );
376  // #i43913# - consider, that anchor frame
377  // is a follow or is in a follow row, which will move forward.
378  if ( pAnchorPageFrame != pObj->GetPageFrame() ||
379  bInFollow )
380  {
381  bool bInsert( true );
382  sal_uInt32 nTmpToPageNum( 0 );
383  const SwDoc& rDoc = *(GetPageFrame().GetFormat()->GetDoc());
385  rDoc, mrAnchorTextFrame, nTmpToPageNum ) )
386  {
387  if ( nTmpToPageNum < pAnchorPageFrame->GetPhyPageNum() )
389  else
390  bInsert = false;
391  }
392  if ( bInsert )
393  {
395  pAnchorPageFrame->GetPhyPageNum() );
397  bSuccess = false;
398  InvalidatePrevObjs( *pObj );
399  InvalidateFollowObjs( *pObj );
400  }
401  else
402  {
403  OSL_FAIL( "<SwObjectFormatterTextFrame::DoFormatObjs(..)> - anchor frame not marked to move forward" );
404  }
405  }
406  }
407  else if ( pObj && bDoesAnchorHadPrev )
408  {
409  // Object found, whose anchor is moved forward
410 
411  // #i49987# - consider, that anchor frame
412  // could already been marked to move forward.
413  bool bInsert( true );
414  sal_uInt32 nMovedFwdToPageNum( 0 );
415  const SwDoc& rDoc = *(GetPageFrame().GetFormat()->GetDoc());
417  rDoc, mrAnchorTextFrame, nMovedFwdToPageNum ) )
418  {
419  if ( nMovedFwdToPageNum < nToPageNum )
421  else
422  bInsert = false;
423  }
424  if ( bInsert )
425  {
426  // Indicate that anchor text frame has to move forward and
427  // invalidate its position to force a re-format.
430 
431  // Indicate restart of the layout process
432  bSuccess = false;
433 
434  // If needed, invalidate previous objects anchored at same anchor
435  // text frame.
436  InvalidatePrevObjs( *pObj );
437 
438  // Invalidate object and following objects for the restart of the
439  // layout process
440  InvalidateFollowObjs( *pObj );
441  }
442  else
443  {
444  OSL_FAIL( "<SwObjectFormatterTextFrame::DoFormatObjs(..)> - anchor frame not marked to move forward" );
445  }
446  }
447  // #i40155# - mark anchor frame not to wrap around
448  // objects under the condition, that its follow contains all its text.
449  else if ( !mrAnchorTextFrame.IsFollow() &&
452  {
456  }
457  }
458 
459  return bSuccess;
460 }
461 
463 {
464  // invalidate all previous objects, whose wrapping influence on the object
465  // positioning is <NONE_CONCURRENT_POSITIONED>.
466  // Note: list of objects at anchor frame is sorted by this property.
467  if ( _rAnchoredObj.GetFrameFormat().GetWrapInfluenceOnObjPos().
468  // #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE
469  GetWrapInfluenceOnObjPos( true ) !=
470  // #i35017# - constant name has changed
471  text::WrapInfluenceOnPosition::ONCE_CONCURRENT )
472  return;
473 
474  const SwSortedObjs* pObjs = GetAnchorFrame().GetDrawObjs();
475  if ( !pObjs )
476  return;
477 
478  // determine start index
479  size_t i = pObjs->ListPosOf( _rAnchoredObj );
480  while (i > 0)
481  {
482  --i;
483  SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
484  if ( pAnchoredObj->GetFrameFormat().GetWrapInfluenceOnObjPos().
485  // #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE
486  GetWrapInfluenceOnObjPos( true ) ==
487  // #i35017# - constant name has changed
488  text::WrapInfluenceOnPosition::ONCE_CONCURRENT )
489  {
491  }
492  }
493 }
494 
496 {
498 
499  const SwSortedObjs* pObjs = GetPageFrame().GetSortedObjs();
500  if ( pObjs )
501  {
502  // determine start index
503  for ( size_t i = pObjs->ListPosOf( _rAnchoredObj ) + 1; i < pObjs->size(); ++i )
504  {
505  SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
507  }
508  }
509 }
510 
512  const sal_Int16 _nWrapInfluenceOnPosition,
513  sal_uInt32& _noToPageNum,
514  bool& _boInFollow )
515 {
516  // #i35017# - constant names have changed
517  OSL_ENSURE( _nWrapInfluenceOnPosition == text::WrapInfluenceOnPosition::ONCE_SUCCESSIVE ||
518  _nWrapInfluenceOnPosition == text::WrapInfluenceOnPosition::ONCE_CONCURRENT,
519  "<SwObjectFormatterTextFrame::GetFirstObjWithMovedFwdAnchor(..)> - invalid value for parameter <_nWrapInfluenceOnPosition>" );
520 
521  SwAnchoredObject* pRetAnchoredObj = nullptr;
522 
523  sal_uInt32 i = 0;
524  for ( ; i < CountOfCollected(); ++i )
525  {
526  SwAnchoredObject* pAnchoredObj = GetCollectedObj(i);
527  if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() &&
528  pAnchoredObj->GetFrameFormat().GetWrapInfluenceOnObjPos().
529  // #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE
530  GetWrapInfluenceOnObjPos( true ) == _nWrapInfluenceOnPosition )
531  {
532  // #i26945# - use new method <_CheckMovedFwdCondition(..)>
533  // #i43913#
534  // #i58182# - consider new method signature
536  GetPgNumOfCollected( i ),
538  _noToPageNum, _boInFollow ) )
539  {
540  pRetAnchoredObj = pAnchoredObj;
541  break;
542  }
543  }
544  }
545 
546  return pRetAnchoredObj;
547 }
548 
549 // #i58182#
550 // - replace private method by corresponding static public method
552  SwAnchoredObject& _rAnchoredObj,
553  const sal_uInt32 _nFromPageNum,
554  const bool _bAnchoredAtMasterBeforeFormatAnchor,
555  sal_uInt32& _noToPageNum,
556  bool& _boInFollow )
557 {
558  bool bAnchorIsMovedForward( false );
559 
560  SwPageFrame* pPageFrameOfAnchor = _rAnchoredObj.FindPageFrameOfAnchor();
561  if ( pPageFrameOfAnchor )
562  {
563  const sal_uInt32 nPageNum = pPageFrameOfAnchor->GetPhyPageNum();
564  if ( nPageNum > _nFromPageNum )
565  {
566  _noToPageNum = nPageNum;
567  // Handling of special case:
568  // If anchor frame is move forward into a follow flow row,
569  // <_noToPageNum> is set to <_nFromPageNum + 1>, because it is
570  // possible that the anchor page frame isn't valid, because the
571  // page distance between master row and follow flow row is greater
572  // than 1.
573  if ( _noToPageNum > (_nFromPageNum + 1) )
574  {
575  SwFrame* pAnchorFrame = _rAnchoredObj.GetAnchorFrameContainingAnchPos();
576  if ( pAnchorFrame->IsInTab() &&
577  pAnchorFrame->IsInFollowFlowRow() )
578  {
579  _noToPageNum = _nFromPageNum + 1;
580  }
581  }
582  bAnchorIsMovedForward = true;
583  }
584  }
585  // #i26945# - check, if an at-paragraph|at-character
586  // anchored object is now anchored at a follow text frame, which will be
587  // on the next page. Also check, if an at-character anchored object
588  // is now anchored at a text frame, which is in a follow flow row,
589  // which will be on the next page.
590  if ( !bAnchorIsMovedForward &&
591  _bAnchoredAtMasterBeforeFormatAnchor &&
592  ((_rAnchoredObj.GetFrameFormat().GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_CHAR) ||
593  (_rAnchoredObj.GetFrameFormat().GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_PARA)))
594  {
595  SwFrame* pAnchorFrame = _rAnchoredObj.GetAnchorFrameContainingAnchPos();
596  OSL_ENSURE( pAnchorFrame->IsTextFrame(),
597  "<SwObjectFormatterTextFrame::CheckMovedFwdCondition(..) - wrong type of anchor frame>" );
598  SwTextFrame* pAnchorTextFrame = static_cast<SwTextFrame*>(pAnchorFrame);
599  bool bCheck( false );
600  if ( pAnchorTextFrame->IsFollow() )
601  {
602  bCheck = true;
603  }
604  else if( pAnchorTextFrame->IsInTab() )
605  {
606  const SwRowFrame* pMasterRow = pAnchorTextFrame->IsInFollowFlowRow();
607  if ( pMasterRow &&
608  pMasterRow->FindPageFrame() == pPageFrameOfAnchor )
609  {
610  bCheck = true;
611  }
612  }
613  if ( bCheck )
614  {
615  // check, if found text frame will be on the next page
616  // by checking, if it's in a column, which has no next.
617  SwFrame* pColFrame = pAnchorTextFrame->FindColFrame();
618  while ( pColFrame && !pColFrame->GetNext() )
619  {
620  pColFrame = pColFrame->FindColFrame();
621  }
622  if ( !pColFrame || !pColFrame->GetNext() )
623  {
624  _noToPageNum = _nFromPageNum + 1;
625  bAnchorIsMovedForward = true;
626  // #i43913#
627  _boInFollow = true;
628  }
629  }
630  }
631 
632  return bAnchorIsMovedForward;
633 }
634 
635 static void CleanupEmptyFootnoteFrame(SwFrame* pLowerFrame)
636 {
637  // Calc on a SwTextFrame in a footnote can move it to the next page -
638  // deletion of the SwFootnoteFrame was disabled with SwFrameDeleteGuard
639  // but now we have to clean up empty footnote frames to prevent crashes.
640  // Note: check it at this level, not lower: both container and footnote
641  // can be deleted at the same time!
642  if (pLowerFrame->IsFootnoteContFrame())
643  {
644  for (SwFrame * pFootnote = pLowerFrame->GetLower(); pFootnote; )
645  {
646  assert(pFootnote->IsFootnoteFrame());
647  SwFrame *const pNextNote = pFootnote->GetNext();
648  if (!pFootnote->IsDeleteForbidden() && !pFootnote->GetLower() && !pFootnote->IsColLocked() &&
649  !static_cast<SwFootnoteFrame*>(pFootnote)->IsBackMoveLocked())
650  {
651  pFootnote->Cut();
652  SwFrame::DestroyFrame(pFootnote);
653  }
654  pFootnote = pNextNote;
655  }
656  }
657 }
658 
659 // #i40140# - helper method to format layout frames used by
660 // method <SwObjectFormatterTextFrame::FormatAnchorFrameForCheckMoveFwd()>
661 // #i44049# - format till a certain lower frame, if provided.
663  SwFrame* pLastLowerFrame = nullptr )
664 {
665  SwFrame* pLowerFrame = pLayFrame->GetLower();
666  while ( pLowerFrame )
667  {
668  // #i44049#
669  if ( pLastLowerFrame && pLowerFrame == pLastLowerFrame )
670  {
671  break;
672  }
673  if ( pLowerFrame->IsLayoutFrame() )
674  {
675  SwFrameDeleteGuard aCrudeHack(pLowerFrame); // ??? any issue setting this for non-footnote frames?
676  lcl_FormatContentOfLayoutFrame( static_cast<SwLayoutFrame*>(pLowerFrame),
677  pLastLowerFrame );
678  }
679  else
680  pLowerFrame->Calc(pLowerFrame->getRootFrame()->GetCurrShell()->GetOut());
681 
682  // Calc on a SwTextFrame in a footnote can move it to the next page -
683  // deletion of the SwFootnoteFrame was disabled with SwFrameDeleteGuard
684  // but now we have to clean up empty footnote frames to prevent crashes.
685  // Note: check it at this level, not lower: both container and footnote
686  // can be deleted at the same time!
687  SwFrame *const pNext = pLowerFrame->GetNext();
688  CleanupEmptyFootnoteFrame(pLowerFrame);
689  pLowerFrame = pNext;
690  }
691 }
692 
702 {
703  // #i47014# - no format of section and previous columns
704  // for follow text frames.
705  if ( !_rAnchorTextFrame.IsFollow() )
706  {
707  // if anchor frame is directly inside a section, format this section and
708  // its previous frames.
709  // Note: It's a very simple format without formatting objects.
710  if ( _rAnchorTextFrame.IsInSct() )
711  {
712  SwFrame* pSectFrame = _rAnchorTextFrame.GetUpper();
713  while ( pSectFrame )
714  {
715  if ( pSectFrame->IsSctFrame() || pSectFrame->IsCellFrame() )
716  {
717  break;
718  }
719  pSectFrame = pSectFrame->GetUpper();
720  }
721  if ( pSectFrame && pSectFrame->IsSctFrame() )
722  {
723  SwFrameDeleteGuard aDeleteGuard(&_rAnchorTextFrame);
724  // #i44049#
725  _rAnchorTextFrame.LockJoin();
726  SwFrame* pFrame = pSectFrame->GetUpper()->GetLower();
727  // #i49605# - section frame could move forward
728  // by the format of its previous frame.
729  // Thus, check for valid <pFrame>.
730  while ( pFrame && pFrame != pSectFrame )
731  {
732  if ( pFrame->IsLayoutFrame() )
733  lcl_FormatContentOfLayoutFrame( static_cast<SwLayoutFrame*>(pFrame) );
734  else
735  pFrame->Calc(pFrame->getRootFrame()->GetCurrShell()->GetOut());
736 
737  pFrame = pFrame->GetNext();
738  }
739  lcl_FormatContentOfLayoutFrame( static_cast<SwLayoutFrame*>(pSectFrame),
740  &_rAnchorTextFrame );
741  // #i44049#
742  _rAnchorTextFrame.UnlockJoin();
743  }
744  }
745 
746  // #i40140# - if anchor frame is inside a column,
747  // format the content of the previous columns.
748  // Note: It's a very simple format without formatting objects.
749  SwFrame* pColFrameOfAnchor = _rAnchorTextFrame.FindColFrame();
750  if ( pColFrameOfAnchor )
751  {
752  // #i44049#
753  _rAnchorTextFrame.LockJoin();
754  SwFrameDeleteGuard aDeleteGuard(&_rAnchorTextFrame);
755  SwFrame* pColFrame = pColFrameOfAnchor->GetUpper()->GetLower();
756  while ( pColFrame != pColFrameOfAnchor )
757  {
758  SwFrame* pFrame = pColFrame->GetLower();
759  while ( pFrame )
760  {
761  if ( pFrame->IsLayoutFrame() )
762  lcl_FormatContentOfLayoutFrame( static_cast<SwLayoutFrame*>(pFrame) );
763  else
764  pFrame->Calc(pFrame->getRootFrame()->GetCurrShell()->GetOut());
765 
766  pFrame = pFrame->GetNext();
767  }
768 
769  pColFrame = pColFrame->GetNext();
770  }
771  // #i44049#
772  _rAnchorTextFrame.UnlockJoin();
773  }
774  }
775 
776  // format anchor frame - format of its follow not needed
777  // #i43255# - forbid follow format, only if anchor text
778  // frame is in table
779  if ( _rAnchorTextFrame.IsInTab() )
780  {
781  SwForbidFollowFormat aForbidFollowFormat( _rAnchorTextFrame );
782  _rAnchorTextFrame.Calc(_rAnchorTextFrame.getRootFrame()->GetCurrShell()->GetOut());
783  }
784  else
785  {
786  _rAnchorTextFrame.Calc(_rAnchorTextFrame.getRootFrame()->GetCurrShell()->GetOut());
787  }
788 }
789 
795 {
797 }
798 
803 {
804  bool bRet( false );
805 
806  const SwSortedObjs* pObjs = GetAnchorFrame().GetDrawObjs();
807  if ( pObjs && pObjs->size() > 1 )
808  {
809  for (SwAnchoredObject* pAnchoredObj : *pObjs)
810  {
811  if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() )
812  {
813  bRet = true;
814  break;
815  }
816  }
817  }
818 
819  return bRet;
820 }
821 
822 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:338
static bool CheckMovedFwdCondition(SwAnchoredObject &_rAnchoredObj, const sal_uInt32 _nFromPageNum, const bool _bAnchoredAtMasterBeforeFormatAnchor, sal_uInt32 &_noToPageNum, bool &_boInFollow)
method to check the conditions, if 'anchor is moved forward'
bool GetValue() const
virtual bool DoFormatObj(SwAnchoredObject &_rAnchoredObj, const bool _bCheckForMovedFwd=false) override
intrinsic method to format a certain floating screen object
Base class of the Writer layout elements.
Definition: frame.hxx:298
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:151
const SwPageFrame & GetPageFrame() const
void AllowFollowFormat()
Definition: txtfrm.hxx:739
bool IsFollow() const
Definition: flowfrm.hxx:166
const SwSortedObjs * GetDrawObjs() const
Definition: frame.hxx:548
void SetClearedEnvironment(const bool _bClearedEnvironment)
SwAnchoredObject * GetFirstObjWithMovedFwdAnchor(const sal_Int16 _nWrapInfluenceOnPosition, sal_uInt32 &_noToPageNum, bool &_boInFollow)
method to determine first anchored object, whose 'anchor is moved forward'.
bool IsInFly() const
Definition: frame.hxx:942
bool IsInSct() const
Definition: frame.hxx:948
virtual SwFrame & GetAnchorFrame() override
static std::unique_ptr< SwObjectFormatterTextFrame > CreateObjFormatter(SwTextFrame &_rAnchorTextFrame, const SwPageFrame &_rPageFrame, SwLayAction *_pLayAction)
method to create an instance of is necessary.
bool AtLeastOneObjIsTmpConsiderWrapInfluence()
method to determine if at least one anchored object has state
SwLayAction * GetLayAction()
Definition: doc.hxx:186
void InvalidatePos()
Definition: frame.hxx:1024
bool ConsiderWrapOnObjPos() const
static void DestroyFrame(SwFrame *const pFrame)
this is the only way to delete a SwFrame instance
Definition: ssfrm.cxx:383
virtual void Calc(vcl::RenderContext *pRenderContext) const
Definition: trvlfrm.cxx:1787
bool IsCellFrame() const
Definition: frame.hxx:1207
bool isFrameAreaDefinitionValid() const
Definition: frame.hxx:170
sal_uInt16 GetPhyPageNum() const
Definition: pagefrm.hxx:191
void InvalidateObjPosForConsiderWrapInfluence()
method to perform necessary invalidations for the positioning of objects, for whose the wrapping styl...
wrapper class for the positioning of Writer fly frames and drawing objects
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
bool IsInTab() const
Definition: frame.hxx:936
bool IsTextFrame() const
Definition: frame.hxx:1215
void InvalidatePrevObjs(SwAnchoredObject &_rAnchoredObj)
method to invalidate objects, anchored previous to given object at the anchor text frame ...
bool IsSctFrame() const
Definition: frame.hxx:1195
SwAnchoredObject * GetCollectedObj(const sal_uInt32 _nIndex)
accessor to collected anchored object
SwTextFrame * GetFollow()
Definition: txtfrm.hxx:846
TextFrameIndex GetOffset() const
Definition: txtfrm.hxx:429
virtual void Cut()=0
const SwFormatFollowTextFlow & GetFollowTextFlow(bool=true) const
SwFrame * GetIndPrev() const
Definition: frame.hxx:707
const SwSortedObjs * GetSortedObjs() const
Definition: pagefrm.hxx:119
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:81
int i
The usage of LayAction is always the same:
Definition: layact.hxx:55
bool FormatObjsAtFrame_(SwTextFrame *_pMasterTextFrame=nullptr)
invokes the intrinsic format method for all floating screen objects, anchored at anchor frame on the ...
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:65
sal_uInt32 GetPgNumOfCollected(const sal_uInt32 _nIndex)
accessor to 'anchor' page number of collected anchored object
size_t size() const
Definition: sortedobjs.cxx:42
SwPageFrame * FindPageFrame()
Definition: frame.hxx:663
static void RemoveMovedFwdFrame(const SwDoc &_rDoc, const SwTextFrame &_rTextFrame)
Definition: layouter.cxx:332
void FormatObj_(SwAnchoredObject &_rAnchoredObj)
performs the intrinsic format of a given floating screen object and its content.
SwLayoutFrame * GetUpper()
Definition: frame.hxx:661
void LockJoin()
Definition: flowfrm.hxx:139
const SwRowFrame * IsInFollowFlowRow() const
Definition: findfrm.cxx:1786
const SwDoc * GetDoc() const
The document is set in SwAttrPool now, therefore you always can access it.
Definition: format.hxx:119
void FormatAnchorFrameForCheckMoveFwd()
method to format the anchor frame for checking of the move forward condition
A page of the document layout.
Definition: pagefrm.hxx:41
SwFrame * GetAnchorFrameContainingAnchPos()
determine anchor frame containing the anchor position
bool RestartLayoutProcess() const
SwFrame * FindColFrame()
Definition: findfrm.cxx:530
void InvalidateFollowObjs(SwAnchoredObject &_rAnchoredObj)
method to invalidate objects, anchored after the given object at the page frame
static void lcl_FormatContentOfLayoutFrame(SwLayoutFrame *pLayFrame, SwFrame *pLastLowerFrame=nullptr)
bool IsLayoutFrame() const
Definition: frame.hxx:1151
virtual bool IsFormatPossible() const
method to determine, if a format on the anchored object is possible
bool ConsiderObjWrapInfluenceOnObjPos() const
method to determine, if wrapping style influence of the anchored object has to be considered on the o...
void UnlockJoin()
Definition: flowfrm.hxx:140
virtual SwFrameFormat & GetFrameFormat()=0
SwPageFrame * FindPageFrameOfAnchor()
method to determine the page frame, on which the 'anchor' of the given anchored object is...
void SetAgain()
Definition: layact.hxx:150
SwTextFrame * FindMaster() const
Definition: flowfrm.cxx:681
SwPageFrame * GetPageFrame()
sal_uInt16 GetPhyPageNum() const
Definition: trvlfrm.cxx:1694
bool HasClearedEnvironment() const
method to determine, if due to anchored object size and wrapping style, its layout environment is cle...
void ForbidFollowFormat()
Definition: txtfrm.hxx:744
virtual ~SwObjectFormatterTextFrame() override
SwFrame * GetLower()
Definition: findfrm.cxx:170
size_t ListPosOf(const SwAnchoredObject &_rAnchoredObj) const
Position of object <_rAnchoredObj> in sorted list.
Definition: sortedobjs.cxx:276
const SwFormatWrapInfluenceOnObjPos & GetWrapInfluenceOnObjPos(bool=true) const
bool IsCollectedAnchoredAtMaster(const sal_uInt32 _nIndex)
accessor to 'anchor' type of collected anchored object
A layout frame is a frame that contains other frames (m_pLower), e.g. SwPageFrame or SwTabFrame...
Definition: layfrm.hxx:35
static void CleanupEmptyFootnoteFrame(SwFrame *pLowerFrame)
const SwFrame * GetAnchorFrame() const
static bool FrameMovedFwdByObjPos(const SwDoc &_rDoc, const SwTextFrame &_rTextFrame, sal_uInt32 &_ornToPageNum)
Definition: layouter.cxx:342
bool IsFootnoteContFrame() const
Definition: frame.hxx:1179
static void FormatAnchorFrameAndItsPrevs(SwTextFrame &_rAnchorTextFrame)
method to format given anchor text frame and its previous frames
bool PositionLocked() const
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:208
o3tl::strong_int< sal_Int32, struct Tag_TextFrameIndex > TextFrameIndex
Denotes a character index in a text frame at a layout level, after extent mapping from a text node at...
class for collecting anchored objects
Definition: sortedobjs.hxx:48
virtual bool DoFormatObjs() override
intrinsic method to format all floating screen objects
void SetRestartLayoutProcess(const bool _bRestartLayoutProcess)
SwObjectFormatterTextFrame(SwTextFrame &_rAnchorTextFrame, const SwPageFrame &_rPageFrame, SwTextFrame *_pMasterAnchorTextFrame, SwLayAction *_pLayAction)
SwRootFrame * getRootFrame()
Definition: frame.hxx:662
static void InsertMovedFwdFrame(const SwDoc &_rDoc, const SwTextFrame &_rMovedFwdFrameByObjPos, const sal_uInt32 _nToPageNum)
Definition: layouter.cxx:312
SwRowFrame is one table row in the document layout.
Definition: rowfrm.hxx:28
virtual const SwFrameFormat * GetFormat() const
Definition: ssfrm.cxx:394
SwFrame * GetNext()
Definition: frame.hxx:659
sal_uInt32 CountOfCollected()
accessor to total number of collected anchored objects