1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 #include <objectformattertxtfrm.hxx>
27 #include <anchoredobject.hxx>
28 #include <sortedobjs.hxx>
29 #include <flyfrms.hxx>
30 #include <txtfrm.hxx>
31 #include <pagefrm.hxx>
32 #include <rowfrm.hxx>
33 #include <layouter.hxx>
34 #include <frmfmt.hxx>
35 #include <fmtanchr.hxx>
36 #include <fmtwrapinfluenceonobjpos.hxx>
37 // --> OD 2004-11-03 #114798#
38 #include <fmtfollowtextflow.hxx>
39 // <--
40 #include <layact.hxx>
41
42 using namespace ::com::sun::star;
43
44 // =============================================================================
45
46 // --> OD 2004-12-03 #115759# - little helper class to forbid follow formatting
47 // for the given text frame
48 class SwForbidFollowFormat
49 {
50 private:
51 SwTxtFrm& mrTxtFrm;
52 const bool bOldFollowFormatAllowed;
53
54 public:
SwForbidFollowFormat(SwTxtFrm & _rTxtFrm)55 SwForbidFollowFormat( SwTxtFrm& _rTxtFrm )
56 : mrTxtFrm( _rTxtFrm ),
57 bOldFollowFormatAllowed( _rTxtFrm.FollowFormatAllowed() )
58 {
59 mrTxtFrm.ForbidFollowFormat();
60 }
61
~SwForbidFollowFormat()62 ~SwForbidFollowFormat()
63 {
64 if ( bOldFollowFormatAllowed )
65 {
66 mrTxtFrm.AllowFollowFormat();
67 }
68 }
69 };
70 // <--
71
72 // =============================================================================
73 // implementation of class <SwObjectFormatterTxtFrm>
74 // =============================================================================
SwObjectFormatterTxtFrm(SwTxtFrm & _rAnchorTxtFrm,const SwPageFrm & _rPageFrm,SwTxtFrm * _pMasterAnchorTxtFrm,SwLayAction * _pLayAction)75 SwObjectFormatterTxtFrm::SwObjectFormatterTxtFrm( SwTxtFrm& _rAnchorTxtFrm,
76 const SwPageFrm& _rPageFrm,
77 SwTxtFrm* _pMasterAnchorTxtFrm,
78 SwLayAction* _pLayAction )
79 : SwObjectFormatter( _rPageFrm, _pLayAction, true ),
80 mrAnchorTxtFrm( _rAnchorTxtFrm ),
81 mpMasterAnchorTxtFrm( _pMasterAnchorTxtFrm )
82 {
83 }
84
~SwObjectFormatterTxtFrm()85 SwObjectFormatterTxtFrm::~SwObjectFormatterTxtFrm()
86 {
87 }
88
CreateObjFormatter(SwTxtFrm & _rAnchorTxtFrm,const SwPageFrm & _rPageFrm,SwLayAction * _pLayAction)89 SwObjectFormatterTxtFrm* SwObjectFormatterTxtFrm::CreateObjFormatter(
90 SwTxtFrm& _rAnchorTxtFrm,
91 const SwPageFrm& _rPageFrm,
92 SwLayAction* _pLayAction )
93 {
94 SwObjectFormatterTxtFrm* pObjFormatter = 0L;
95
96 // determine 'master' of <_rAnchorTxtFrm>, if anchor frame is a follow text frame.
97 SwTxtFrm* pMasterOfAnchorFrm = 0L;
98 if ( _rAnchorTxtFrm.IsFollow() )
99 {
100 pMasterOfAnchorFrm = _rAnchorTxtFrm.FindMaster();
101 while ( pMasterOfAnchorFrm->IsFollow() )
102 {
103 pMasterOfAnchorFrm = pMasterOfAnchorFrm->FindMaster();
104 }
105 }
106
107 // create object formatter, if floating screen objects are registered
108 // at anchor frame (or at 'master' anchor frame)
109 if ( _rAnchorTxtFrm.GetDrawObjs() ||
110 ( pMasterOfAnchorFrm && pMasterOfAnchorFrm->GetDrawObjs() ) )
111 {
112 pObjFormatter =
113 new SwObjectFormatterTxtFrm( _rAnchorTxtFrm, _rPageFrm,
114 pMasterOfAnchorFrm, _pLayAction );
115 }
116
117 return pObjFormatter;
118 }
119
GetAnchorFrm()120 SwFrm& SwObjectFormatterTxtFrm::GetAnchorFrm()
121 {
122 return mrAnchorTxtFrm;
123 }
124
125 // --> OD 2005-01-10 #i40147# - add parameter <_bCheckForMovedFwd>.
DoFormatObj(SwAnchoredObject & _rAnchoredObj,const bool _bCheckForMovedFwd)126 bool SwObjectFormatterTxtFrm::DoFormatObj( SwAnchoredObject& _rAnchoredObj,
127 const bool _bCheckForMovedFwd )
128 {
129 // check, if only as-character anchored object have to be formatted, and
130 // check the anchor type
131 if ( FormatOnlyAsCharAnchored() &&
132 !(_rAnchoredObj.GetFrmFmt().GetAnchor().GetAnchorId() == FLY_AS_CHAR) )
133 {
134 return true;
135 }
136
137 // --> OD 2005-07-13 #124218# - consider, if the layout action has to be
138 // restarted due to a delete of a page frame.
139 if ( GetLayAction() && GetLayAction()->IsAgain() )
140 {
141 return false;
142 }
143 // <--
144
145 bool bSuccess( true );
146
147 if ( _rAnchoredObj.IsFormatPossible() )
148 {
149 _rAnchoredObj.SetRestartLayoutProcess( false );
150
151 _FormatObj( _rAnchoredObj );
152 // --> OD 2005-07-13 #124218# - consider, if the layout action has to be
153 // restarted due to a delete of a page frame.
154 if ( GetLayAction() && GetLayAction()->IsAgain() )
155 {
156 return false;
157 }
158 // <--
159
160 // check, if layout process has to be restarted.
161 // if yes, perform needed invalidations.
162 // --> OD 2004-11-03 #114798# - no restart of layout process,
163 // if anchored object is anchored inside a Writer fly frame,
164 // its position is already locked, and it follows the text flow.
165 const bool bRestart =
166 _rAnchoredObj.RestartLayoutProcess() &&
167 !( _rAnchoredObj.PositionLocked() &&
168 _rAnchoredObj.GetAnchorFrm()->IsInFly() &&
169 _rAnchoredObj.GetFrmFmt().GetFollowTextFlow().GetValue() );
170 if ( bRestart )
171 // <--
172 {
173 bSuccess = false;
174 _InvalidatePrevObjs( _rAnchoredObj );
175 _InvalidateFollowObjs( _rAnchoredObj, true );
176 }
177
178 // format anchor text frame, if wrapping style influence of the object
179 // has to be considered and it's <NONE_SUCCESSIVE_POSITIONED>
180 // --> OD 2004-08-25 #i3317# - consider also anchored objects, whose
181 // wrapping style influence is temporarly considered.
182 // --> OD 2005-01-10 #i40147# - consider also anchored objects, for
183 // whose the check of a moved forward anchor frame is requested.
184 // --> OD 2006-07-24 #b6449874# - revise decision made for i3317:
185 // anchored objects, whose wrapping style influence is temporarly considered,
186 // have to be considered in method <SwObjectFormatterTxtFrm::DoFormatObjs()>
187 if ( bSuccess &&
188 _rAnchoredObj.ConsiderObjWrapInfluenceOnObjPos() &&
189 ( _bCheckForMovedFwd ||
190 _rAnchoredObj.GetFrmFmt().GetWrapInfluenceOnObjPos().
191 // --> OD 2004-10-18 #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE
192 GetWrapInfluenceOnObjPos( true ) ==
193 // --> OD 2004-10-18 #i35017# - constant name has changed
194 text::WrapInfluenceOnPosition::ONCE_SUCCESSIVE ) )
195 // <--
196 {
197 // --> OD 2004-10-11 #i26945# - check conditions for move forward of
198 // anchor text frame
199 // determine, if anchor text frame has previous frame
200 const bool bDoesAnchorHadPrev = ( mrAnchorTxtFrm.GetIndPrev() != 0 );
201
202 // --> OD 2005-01-11 #i40141# - use new method - it also formats the
203 // section the anchor frame is in.
204 _FormatAnchorFrmForCheckMoveFwd();
205 // <--
206
207 // --> OD 2004-10-22 #i35911#
208 if ( _rAnchoredObj.HasClearedEnvironment() )
209 {
210 _rAnchoredObj.SetClearedEnvironment( true );
211 // --> OD 2005-03-08 #i44049# - consider, that anchor frame
212 // could already been marked to move forward.
213 SwPageFrm* pAnchorPageFrm( mrAnchorTxtFrm.FindPageFrm() );
214 if ( pAnchorPageFrm != _rAnchoredObj.GetPageFrm() )
215 {
216 bool bInsert( true );
217 sal_uInt32 nToPageNum( 0L );
218 const SwDoc& rDoc = *(GetPageFrm().GetFmt()->GetDoc());
219 if ( SwLayouter::FrmMovedFwdByObjPos(
220 rDoc, mrAnchorTxtFrm, nToPageNum ) )
221 {
222 if ( nToPageNum < pAnchorPageFrm->GetPhyPageNum() )
223 SwLayouter::RemoveMovedFwdFrm( rDoc, mrAnchorTxtFrm );
224 else
225 bInsert = false;
226 }
227 if ( bInsert )
228 {
229 SwLayouter::InsertMovedFwdFrm( rDoc, mrAnchorTxtFrm,
230 pAnchorPageFrm->GetPhyPageNum() );
231 mrAnchorTxtFrm.InvalidatePos();
232 bSuccess = false;
233 _InvalidatePrevObjs( _rAnchoredObj );
234 _InvalidateFollowObjs( _rAnchoredObj, true );
235 }
236 else
237 {
238 ASSERT( false,
239 "<SwObjectFormatterTxtFrm::DoFormatObj(..)> - anchor frame not marked to move forward" );
240 }
241 }
242 // <--
243 }
244 else if ( !mrAnchorTxtFrm.IsFollow() && bDoesAnchorHadPrev )
245 // <--
246 {
247 // index of anchored object in collection of page numbers and
248 // anchor types
249 sal_uInt32 nIdx( CountOfCollected() );
250 ASSERT( nIdx > 0,
251 "<SwObjectFormatterTxtFrm::DoFormatObj(..)> - anchored object not collected!?" );
252 --nIdx;
253
254 sal_uInt32 nToPageNum( 0L );
255 // --> OD 2005-03-30 #i43913#
256 bool bDummy( false );
257 // --> OD 2006-01-27 #i58182# - consider new method signature
258 if ( SwObjectFormatterTxtFrm::CheckMovedFwdCondition( *GetCollectedObj( nIdx ),
259 GetPgNumOfCollected( nIdx ),
260 IsCollectedAnchoredAtMaster( nIdx ),
261 nToPageNum, bDummy ) )
262 // <--
263 {
264 // --> OD 2005-06-01 #i49987# - consider, that anchor frame
265 // could already been marked to move forward.
266 bool bInsert( true );
267 sal_uInt32 nMovedFwdToPageNum( 0L );
268 const SwDoc& rDoc = *(GetPageFrm().GetFmt()->GetDoc());
269 if ( SwLayouter::FrmMovedFwdByObjPos(
270 rDoc, mrAnchorTxtFrm, nMovedFwdToPageNum ) )
271 {
272 if ( nMovedFwdToPageNum < nToPageNum )
273 SwLayouter::RemoveMovedFwdFrm( rDoc, mrAnchorTxtFrm );
274 else
275 bInsert = false;
276 }
277 if ( bInsert )
278 {
279 // Indicate that anchor text frame has to move forward and
280 // invalidate its position to force a re-format.
281 SwLayouter::InsertMovedFwdFrm( rDoc, mrAnchorTxtFrm,
282 nToPageNum );
283 mrAnchorTxtFrm.InvalidatePos();
284
285 // Indicate restart of the layout process
286 bSuccess = false;
287
288 // If needed, invalidate previous objects anchored at same anchor
289 // text frame.
290 _InvalidatePrevObjs( _rAnchoredObj );
291
292 // Invalidate object and following objects for the restart of the
293 // layout process
294 _InvalidateFollowObjs( _rAnchoredObj, true );
295 }
296 else
297 {
298 ASSERT( false,
299 "<SwObjectFormatterTxtFrm::DoFormatObj(..)> - anchor frame not marked to move forward" );
300 }
301 // <--
302 }
303 }
304 // <--
305 // --> OD 2005-01-12 #i40155# - mark anchor frame not to wrap around
306 // objects under the condition, that its follow contains all its text.
307 else if ( !mrAnchorTxtFrm.IsFollow() &&
308 mrAnchorTxtFrm.GetFollow() &&
309 mrAnchorTxtFrm.GetFollow()->GetOfst() == 0 )
310 {
311 SwLayouter::InsertFrmNotToWrap(
312 *(mrAnchorTxtFrm.FindPageFrm()->GetFmt()->GetDoc()),
313 mrAnchorTxtFrm );
314 SwLayouter::RemoveMovedFwdFrm(
315 *(mrAnchorTxtFrm.FindPageFrm()->GetFmt()->GetDoc()),
316 mrAnchorTxtFrm );
317 }
318 // <--
319 }
320 }
321
322 return bSuccess;
323 }
324
DoFormatObjs()325 bool SwObjectFormatterTxtFrm::DoFormatObjs()
326 {
327 if ( !mrAnchorTxtFrm.IsValid() )
328 {
329 if ( GetLayAction() &&
330 mrAnchorTxtFrm.FindPageFrm() != &GetPageFrm() )
331 {
332 // notify layout action, thus is can restart the layout process on
333 // a previous page.
334 GetLayAction()->SetAgain();
335 }
336 else
337 {
338 // the anchor text frame has to be valid, thus assert.
339 ASSERT( false,
340 "<SwObjectFormatterTxtFrm::DoFormatObjs()> called for invalidate anchor text frame." );
341 }
342
343 return false;
344 }
345
346 bool bSuccess( true );
347
348 if ( mrAnchorTxtFrm.IsFollow() )
349 {
350 // Only floating screen objects anchored as-character are directly
351 // registered at a follow text frame. The other floating screen objects
352 // are registered at the 'master' anchor text frame.
353 // Thus, format the other floating screen objects through the 'master'
354 // anchor text frame
355 ASSERT( mpMasterAnchorTxtFrm,
356 "SwObjectFormatterTxtFrm::DoFormatObjs() - missing 'master' anchor text frame" );
357 bSuccess = _FormatObjsAtFrm( mpMasterAnchorTxtFrm );
358
359 if ( bSuccess )
360 {
361 // format of as-character anchored floating screen objects - no failure
362 // excepted on the format of these objects.
363 bSuccess = _FormatObjsAtFrm();
364 }
365 }
366 else
367 {
368 bSuccess = _FormatObjsAtFrm();
369 }
370
371 // --> OD 2006-07-24 #b449874#
372 // consider anchored objects, whose wrapping style influence are temporarly
373 // considered.
374 if ( bSuccess &&
375 ( ConsiderWrapOnObjPos() ||
376 ( !mrAnchorTxtFrm.IsFollow() &&
377 _AtLeastOneObjIsTmpConsiderWrapInfluence() ) ) )
378 // <--
379 {
380 const bool bDoesAnchorHadPrev = ( mrAnchorTxtFrm.GetIndPrev() != 0 );
381
382 // Format anchor text frame after its objects are formatted.
383 // Note: The format of the anchor frame also formats the invalid
384 // previous frames of the anchor frame. The format of the previous
385 // frames is needed to get a correct result of format of the
386 // anchor frame for the following check for moved forward anchors
387 // --> OD 2005-01-11 #i40141# - use new method - it also formats the
388 // section the anchor frame is in.
389 _FormatAnchorFrmForCheckMoveFwd();
390 // <--
391
392 sal_uInt32 nToPageNum( 0L );
393 // --> OD 2005-03-30 #i43913#
394 bool bInFollow( false );
395 // <--
396 SwAnchoredObject* pObj = 0L;
397 if ( !mrAnchorTxtFrm.IsFollow() )
398 {
399 pObj = _GetFirstObjWithMovedFwdAnchor(
400 // --> OD 2004-10-18 #i35017# - constant name has changed
401 text::WrapInfluenceOnPosition::ONCE_CONCURRENT,
402 // <--
403 nToPageNum, bInFollow );
404 }
405 // --> OD 2004-10-25 #i35911#
406 if ( pObj && pObj->HasClearedEnvironment() )
407 {
408 pObj->SetClearedEnvironment( true );
409 // --> OD 2005-03-08 #i44049# - consider, that anchor frame
410 // could already been marked to move forward.
411 SwPageFrm* pAnchorPageFrm( mrAnchorTxtFrm.FindPageFrm() );
412 // --> OD 2005-03-30 #i43913# - consider, that anchor frame
413 // is a follow or is in a follow row, which will move forward.
414 if ( pAnchorPageFrm != pObj->GetPageFrm() ||
415 bInFollow )
416 // <--
417 {
418 bool bInsert( true );
419 sal_uInt32 nTmpToPageNum( 0L );
420 const SwDoc& rDoc = *(GetPageFrm().GetFmt()->GetDoc());
421 if ( SwLayouter::FrmMovedFwdByObjPos(
422 rDoc, mrAnchorTxtFrm, nTmpToPageNum ) )
423 {
424 if ( nTmpToPageNum < pAnchorPageFrm->GetPhyPageNum() )
425 SwLayouter::RemoveMovedFwdFrm( rDoc, mrAnchorTxtFrm );
426 else
427 bInsert = false;
428 }
429 if ( bInsert )
430 {
431 SwLayouter::InsertMovedFwdFrm( rDoc, mrAnchorTxtFrm,
432 pAnchorPageFrm->GetPhyPageNum() );
433 mrAnchorTxtFrm.InvalidatePos();
434 bSuccess = false;
435 _InvalidatePrevObjs( *pObj );
436 _InvalidateFollowObjs( *pObj, true );
437 }
438 else
439 {
440 ASSERT( false,
441 "<SwObjectFormatterTxtFrm::DoFormatObjs(..)> - anchor frame not marked to move forward" );
442 }
443 }
444 }
445 else if ( pObj && bDoesAnchorHadPrev )
446 // <--
447 {
448 // Object found, whose anchor is moved forward
449
450 // --> OD 2005-06-01 #i49987# - consider, that anchor frame
451 // could already been marked to move forward.
452 bool bInsert( true );
453 sal_uInt32 nMovedFwdToPageNum( 0L );
454 const SwDoc& rDoc = *(GetPageFrm().GetFmt()->GetDoc());
455 if ( SwLayouter::FrmMovedFwdByObjPos(
456 rDoc, mrAnchorTxtFrm, nMovedFwdToPageNum ) )
457 {
458 if ( nMovedFwdToPageNum < nToPageNum )
459 SwLayouter::RemoveMovedFwdFrm( rDoc, mrAnchorTxtFrm );
460 else
461 bInsert = false;
462 }
463 if ( bInsert )
464 {
465 // Indicate that anchor text frame has to move forward and
466 // invalidate its position to force a re-format.
467 SwLayouter::InsertMovedFwdFrm( rDoc, mrAnchorTxtFrm, nToPageNum );
468 mrAnchorTxtFrm.InvalidatePos();
469
470 // Indicate restart of the layout process
471 bSuccess = false;
472
473 // If needed, invalidate previous objects anchored at same anchor
474 // text frame.
475 _InvalidatePrevObjs( *pObj );
476
477 // Invalidate object and following objects for the restart of the
478 // layout process
479 _InvalidateFollowObjs( *pObj, true );
480 }
481 else
482 {
483 ASSERT( false,
484 "<SwObjectFormatterTxtFrm::DoFormatObjs(..)> - anchor frame not marked to move forward" );
485 }
486 // <--
487 }
488 // <--
489 // --> OD 2005-01-12 #i40155# - mark anchor frame not to wrap around
490 // objects under the condition, that its follow contains all its text.
491 else if ( !mrAnchorTxtFrm.IsFollow() &&
492 mrAnchorTxtFrm.GetFollow() &&
493 mrAnchorTxtFrm.GetFollow()->GetOfst() == 0 )
494 {
495 SwLayouter::InsertFrmNotToWrap(
496 *(mrAnchorTxtFrm.FindPageFrm()->GetFmt()->GetDoc()),
497 mrAnchorTxtFrm );
498 SwLayouter::RemoveMovedFwdFrm(
499 *(mrAnchorTxtFrm.FindPageFrm()->GetFmt()->GetDoc()),
500 mrAnchorTxtFrm );
501 }
502 // <--
503 }
504
505 return bSuccess;
506 }
507
_InvalidatePrevObjs(SwAnchoredObject & _rAnchoredObj)508 void SwObjectFormatterTxtFrm::_InvalidatePrevObjs( SwAnchoredObject& _rAnchoredObj )
509 {
510 // invalidate all previous objects, whose wrapping influence on the object
511 // positioning is <NONE_CONCURRENT_POSIITIONED>.
512 // Note: list of objects at anchor frame is sorted by this property.
513 if ( _rAnchoredObj.GetFrmFmt().GetWrapInfluenceOnObjPos().
514 // --> OD 2004-10-18 #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE
515 GetWrapInfluenceOnObjPos( true ) ==
516 // <--
517 // --> OD 2004-10-18 #i35017# - constant name has changed
518 text::WrapInfluenceOnPosition::ONCE_CONCURRENT )
519 // <--
520 {
521 const SwSortedObjs* pObjs = GetAnchorFrm().GetDrawObjs();
522 if ( pObjs )
523 {
524 // determine start index
525 sal_Int32 i = pObjs->ListPosOf( _rAnchoredObj ) - 1;
526 for ( ; i >= 0; --i )
527 {
528 SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
529 if ( pAnchoredObj->GetFrmFmt().GetWrapInfluenceOnObjPos().
530 // --> OD 2004-10-18 #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE
531 GetWrapInfluenceOnObjPos( true ) ==
532 // <--
533 // --> OD 2004-10-18 #i35017# - constant name has changed
534 text::WrapInfluenceOnPosition::ONCE_CONCURRENT )
535 // <--
536 {
537 pAnchoredObj->InvalidateObjPosForConsiderWrapInfluence( true );
538 }
539 }
540 }
541 }
542 }
543
_InvalidateFollowObjs(SwAnchoredObject & _rAnchoredObj,const bool _bInclObj)544 void SwObjectFormatterTxtFrm::_InvalidateFollowObjs( SwAnchoredObject& _rAnchoredObj,
545 const bool _bInclObj )
546 {
547 if ( _bInclObj )
548 {
549 _rAnchoredObj.InvalidateObjPosForConsiderWrapInfluence( true );
550 }
551
552 const SwSortedObjs* pObjs = GetPageFrm().GetSortedObjs();
553 if ( pObjs )
554 {
555 // determine start index
556 sal_uInt32 i = pObjs->ListPosOf( _rAnchoredObj ) + 1;
557 for ( ; i < pObjs->Count(); ++i )
558 {
559 SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
560 pAnchoredObj->InvalidateObjPosForConsiderWrapInfluence( true );
561 }
562 }
563 }
564
_GetFirstObjWithMovedFwdAnchor(const sal_Int16 _nWrapInfluenceOnPosition,sal_uInt32 & _noToPageNum,bool & _boInFollow)565 SwAnchoredObject* SwObjectFormatterTxtFrm::_GetFirstObjWithMovedFwdAnchor(
566 const sal_Int16 _nWrapInfluenceOnPosition,
567 sal_uInt32& _noToPageNum,
568 bool& _boInFollow )
569 {
570 // --> OD 2004-10-18 #i35017# - constant names have changed
571 ASSERT( _nWrapInfluenceOnPosition == text::WrapInfluenceOnPosition::ONCE_SUCCESSIVE ||
572 _nWrapInfluenceOnPosition == text::WrapInfluenceOnPosition::ONCE_CONCURRENT,
573 "<SwObjectFormatterTxtFrm::_GetFirstObjWithMovedFwdAnchor(..)> - invalid value for parameter <_nWrapInfluenceOnPosition>" );
574 // <--
575
576 SwAnchoredObject* pRetAnchoredObj = 0L;
577
578 sal_uInt32 i = 0L;
579 for ( ; i < CountOfCollected(); ++i )
580 {
581 SwAnchoredObject* pAnchoredObj = GetCollectedObj(i);
582 if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() &&
583 pAnchoredObj->GetFrmFmt().GetWrapInfluenceOnObjPos().
584 // --> OD 2004-10-18 #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE
585 GetWrapInfluenceOnObjPos( true ) == _nWrapInfluenceOnPosition )
586 // <--
587 {
588 // --> OD 2004-10-11 #i26945# - use new method <_CheckMovedFwdCondition(..)>
589 // --> OD 2005-03-30 #i43913#
590 // --> OD 2006-01-27 #i58182# - consider new method signature
591 if ( SwObjectFormatterTxtFrm::CheckMovedFwdCondition( *GetCollectedObj( i ),
592 GetPgNumOfCollected( i ),
593 IsCollectedAnchoredAtMaster( i ),
594 _noToPageNum, _boInFollow ) )
595 {
596 pRetAnchoredObj = pAnchoredObj;
597 break;
598 }
599 // <--
600 }
601 }
602
603 return pRetAnchoredObj;
604 }
605
606 // --> OD 2006-01-27 #i58182#
607 // - replace private method by corresponding static public method
CheckMovedFwdCondition(SwAnchoredObject & _rAnchoredObj,const sal_uInt32 _nFromPageNum,const bool _bAnchoredAtMasterBeforeFormatAnchor,sal_uInt32 & _noToPageNum,bool & _boInFollow)608 bool SwObjectFormatterTxtFrm::CheckMovedFwdCondition(
609 SwAnchoredObject& _rAnchoredObj,
610 const sal_uInt32 _nFromPageNum,
611 const bool _bAnchoredAtMasterBeforeFormatAnchor,
612 sal_uInt32& _noToPageNum,
613 bool& _boInFollow )
614 {
615 bool bAnchorIsMovedForward( false );
616
617 SwPageFrm* pPageFrmOfAnchor = _rAnchoredObj.FindPageFrmOfAnchor();
618 if ( pPageFrmOfAnchor )
619 {
620 const sal_uInt32 nPageNum = pPageFrmOfAnchor->GetPhyPageNum();
621 if ( nPageNum > _nFromPageNum )
622 {
623 _noToPageNum = nPageNum;
624 // --> OD 2006-06-28 #b6443897#
625 // Handling of special case:
626 // If anchor frame is move forward into a follow flow row,
627 // <_noToPageNum> is set to <_nFromPageNum + 1>, because it is
628 // possible that the anchor page frame isn't valid, because the
629 // page distance between master row and follow flow row is greater
630 // than 1.
631 if ( _noToPageNum > (_nFromPageNum + 1) )
632 {
633 SwFrm* pAnchorFrm = _rAnchoredObj.GetAnchorFrmContainingAnchPos();
634 if ( pAnchorFrm->IsInTab() &&
635 pAnchorFrm->IsInFollowFlowRow() )
636 {
637 _noToPageNum = _nFromPageNum + 1;
638 }
639 }
640 // <--
641 bAnchorIsMovedForward = true;
642 }
643 }
644 // <--
645 // --> OD 2004-11-05 #i26945# - check, if an at-paragraph|at-character
646 // anchored object is now anchored at a follow text frame, which will be
647 // on the next page. Also check, if an at-character anchored object
648 // is now anchored at a text frame, which is in a follow flow row,
649 // which will be on the next page.
650 if ( !bAnchorIsMovedForward &&
651 _bAnchoredAtMasterBeforeFormatAnchor &&
652 ((_rAnchoredObj.GetFrmFmt().GetAnchor().GetAnchorId() == FLY_AT_CHAR) ||
653 (_rAnchoredObj.GetFrmFmt().GetAnchor().GetAnchorId() == FLY_AT_PARA)))
654 {
655 SwFrm* pAnchorFrm = _rAnchoredObj.GetAnchorFrmContainingAnchPos();
656 ASSERT( pAnchorFrm->IsTxtFrm(),
657 "<SwObjectFormatterTxtFrm::CheckMovedFwdCondition(..) - wrong type of anchor frame>" );
658 SwTxtFrm* pAnchorTxtFrm = static_cast<SwTxtFrm*>(pAnchorFrm);
659 bool bCheck( false );
660 if ( pAnchorTxtFrm->IsFollow() )
661 {
662 bCheck = true;
663 }
664 else if( pAnchorTxtFrm->IsInTab() )
665 {
666 const SwRowFrm* pMasterRow = pAnchorTxtFrm->IsInFollowFlowRow();
667 if ( pMasterRow &&
668 pMasterRow->FindPageFrm() == pPageFrmOfAnchor )
669 {
670 bCheck = true;
671 }
672 }
673 if ( bCheck )
674 {
675 // check, if found text frame will be on the next page
676 // by checking, if it's in a column, which has no next.
677 SwFrm* pColFrm = pAnchorTxtFrm->FindColFrm();
678 while ( pColFrm && !pColFrm->GetNext() )
679 {
680 pColFrm = pColFrm->FindColFrm();
681 }
682 if ( !pColFrm || !pColFrm->GetNext() )
683 {
684 _noToPageNum = _nFromPageNum + 1;
685 bAnchorIsMovedForward = true;
686 // --> OD 2005-03-30 #i43913#
687 _boInFollow = true;
688 // <--
689 }
690 }
691 }
692 // <--
693
694 return bAnchorIsMovedForward;
695 }
696 // <--
697
698 // --> OD 2005-01-12 #i40140# - helper method to format layout frames used by
699 // method <SwObjectFormatterTxtFrm::_FormatAnchorFrmForCheckMoveFwd()>
700 // --> OD 2005-03-04 #i44049# - format till a certain lower frame, if provided.
lcl_FormatCntntOfLayoutFrm(SwLayoutFrm * pLayFrm,SwFrm * pLastLowerFrm=0L)701 void lcl_FormatCntntOfLayoutFrm( SwLayoutFrm* pLayFrm,
702 SwFrm* pLastLowerFrm = 0L )
703 {
704 SwFrm* pLowerFrm = pLayFrm->GetLower();
705 while ( pLowerFrm )
706 {
707 // --> OD 2005-03-04 #i44049#
708 if ( pLastLowerFrm && pLowerFrm == pLastLowerFrm )
709 {
710 break;
711 }
712 // <--
713 if ( pLowerFrm->IsLayoutFrm() )
714 lcl_FormatCntntOfLayoutFrm( static_cast<SwLayoutFrm*>(pLowerFrm),
715 pLastLowerFrm );
716 else
717 pLowerFrm->Calc();
718
719 pLowerFrm = pLowerFrm->GetNext();
720 }
721 }
722 // <--
723 /** method to format given anchor text frame and its previous frames
724
725 OD 2005-11-17 #i56300#
726 Usage: Needed to check, if the anchor text frame is moved forward
727 due to the positioning and wrapping of its anchored objects, and
728 to format the frames, which have become invalid due to the anchored
729 object formatting in the iterative object positioning algorithm
730
731 @author OD
732 */
FormatAnchorFrmAndItsPrevs(SwTxtFrm & _rAnchorTxtFrm)733 void SwObjectFormatterTxtFrm::FormatAnchorFrmAndItsPrevs( SwTxtFrm& _rAnchorTxtFrm )
734 {
735 // --> OD 2005-04-13 #i47014# - no format of section and previous columns
736 // for follow text frames.
737 if ( !_rAnchorTxtFrm.IsFollow() )
738 {
739 // if anchor frame is directly inside a section, format this section and
740 // its previous frames.
741 // Note: It's a very simple format without formatting objects.
742 if ( _rAnchorTxtFrm.IsInSct() )
743 {
744 SwFrm* pSectFrm = _rAnchorTxtFrm.GetUpper();
745 while ( pSectFrm )
746 {
747 if ( pSectFrm->IsSctFrm() || pSectFrm->IsCellFrm() )
748 {
749 break;
750 }
751 pSectFrm = pSectFrm->GetUpper();
752 }
753 if ( pSectFrm && pSectFrm->IsSctFrm() )
754 {
755 // --> OD 2005-03-04 #i44049#
756 _rAnchorTxtFrm.LockJoin();
757 // <--
758 SwFrm* pFrm = pSectFrm->GetUpper()->GetLower();
759 // --> OD 2005-05-23 #i49605# - section frame could move forward
760 // by the format of its previous frame.
761 // Thus, check for valid <pFrm>.
762 while ( pFrm && pFrm != pSectFrm )
763 // <--
764 {
765 if ( pFrm->IsLayoutFrm() )
766 lcl_FormatCntntOfLayoutFrm( static_cast<SwLayoutFrm*>(pFrm) );
767 else
768 pFrm->Calc();
769
770 pFrm = pFrm->GetNext();
771 }
772 lcl_FormatCntntOfLayoutFrm( static_cast<SwLayoutFrm*>(pSectFrm),
773 &_rAnchorTxtFrm );
774 // --> OD 2005-03-04 #i44049#
775 _rAnchorTxtFrm.UnlockJoin();
776 // <--
777 }
778 }
779
780 // --> OD 2005-01-12 #i40140# - if anchor frame is inside a column,
781 // format the content of the previous columns.
782 // Note: It's a very simple format without formatting objects.
783 SwFrm* pColFrmOfAnchor = _rAnchorTxtFrm.FindColFrm();
784 if ( pColFrmOfAnchor )
785 {
786 // --> OD 2005-03-04 #i44049#
787 _rAnchorTxtFrm.LockJoin();
788 // <--
789 SwFrm* pColFrm = pColFrmOfAnchor->GetUpper()->GetLower();
790 while ( pColFrm != pColFrmOfAnchor )
791 {
792 SwFrm* pFrm = pColFrm->GetLower();
793 while ( pFrm )
794 {
795 if ( pFrm->IsLayoutFrm() )
796 lcl_FormatCntntOfLayoutFrm( static_cast<SwLayoutFrm*>(pFrm) );
797 else
798 pFrm->Calc();
799
800 pFrm = pFrm->GetNext();
801 }
802
803 pColFrm = pColFrm->GetNext();
804 }
805 // --> OD 2005-03-04 #i44049#
806 _rAnchorTxtFrm.UnlockJoin();
807 // <--
808 }
809 // <--
810 }
811 // <--
812
813 // format anchor frame - format of its follow not needed
814 // --> OD 2005-04-08 #i43255# - forbid follow format, only if anchor text
815 // frame is in table
816 if ( _rAnchorTxtFrm.IsInTab() )
817 {
818 SwForbidFollowFormat aForbidFollowFormat( _rAnchorTxtFrm );
819 _rAnchorTxtFrm.Calc();
820 }
821 else
822 {
823 _rAnchorTxtFrm.Calc();
824 }
825 }
826
827 /** method to format the anchor frame for checking of the move forward condition
828
829 OD 2005-01-11 #i40141#
830
831 @author OD
832 */
_FormatAnchorFrmForCheckMoveFwd()833 void SwObjectFormatterTxtFrm::_FormatAnchorFrmForCheckMoveFwd()
834 {
835 SwObjectFormatterTxtFrm::FormatAnchorFrmAndItsPrevs( mrAnchorTxtFrm );
836 }
837
838 /** method to determine if at least one anchored object has state
839 <temporarly consider wrapping style influence> set.
840
841 OD 2006-07-24 #b6449874#
842
843 @author OD
844 */
_AtLeastOneObjIsTmpConsiderWrapInfluence()845 bool SwObjectFormatterTxtFrm::_AtLeastOneObjIsTmpConsiderWrapInfluence()
846 {
847 bool bRet( false );
848
849 const SwSortedObjs* pObjs = GetAnchorFrm().GetDrawObjs();
850 if ( pObjs && pObjs->Count() > 1 )
851 {
852 sal_uInt32 i = 0;
853 for ( ; i < pObjs->Count(); ++i )
854 {
855 SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
856 if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() )
857 {
858 bRet = true;
859 break;
860 }
861 }
862 }
863
864 return bRet;
865 }
866
867