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