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