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