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