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 <anchoredobject.hxx>
30 : : #include <pam.hxx>
31 : : #include <frame.hxx>
32 : : #include <txtfrm.hxx>
33 : : #include <frmfmt.hxx>
34 : : #include <fmtanchr.hxx>
35 : : #include <fmtornt.hxx>
36 : : // --> #i28701#
37 : : #include <doc.hxx>
38 : : #include <fmtsrnd.hxx>
39 : : #include <svx/svdobj.hxx>
40 : : #include <dcontact.hxx>
41 : : #include <editeng/ulspitem.hxx>
42 : : #include <editeng/lrspitem.hxx>
43 : : #include <sortedobjs.hxx>
44 : : #include <pagefrm.hxx>
45 : : #include <frmatr.hxx>
46 : : // --> #i3317#
47 : : #include <colfrm.hxx>
48 : : // --> #i35911#
49 : : #include <layouter.hxx>
50 : :
51 : :
52 : : using namespace ::com::sun::star;
53 : :
54 : :
55 : : // ============================================================================
56 : : // --> #i28701# -
57 : : // implementation of helper class <SwObjPositioningInProgress>
58 : : // ============================================================================
59 : 4187 : SwObjPositioningInProgress::SwObjPositioningInProgress( SdrObject& _rSdrObj ) :
60 : : mpAnchoredObj( 0L ),
61 : : // --> #i52904#
62 : 4187 : mbOldObjPositioningInProgress( false )
63 : : {
64 : 4187 : mpAnchoredObj = ::GetUserCall( &_rSdrObj )->GetAnchoredObj( &_rSdrObj );
65 : : // --> #i52904#
66 : 4187 : mbOldObjPositioningInProgress = mpAnchoredObj->IsPositioningInProgress();
67 : 4187 : mpAnchoredObj->SetPositioningInProgress( true );
68 : 4187 : }
69 : 585 : SwObjPositioningInProgress::SwObjPositioningInProgress( SwAnchoredObject& _rAnchoredObj ) :
70 : : mpAnchoredObj( &_rAnchoredObj ),
71 : : // --> #i52904#
72 : 585 : mbOldObjPositioningInProgress( false )
73 : : {
74 : : // --> #i52904#
75 : 585 : mbOldObjPositioningInProgress = mpAnchoredObj->IsPositioningInProgress();
76 : 585 : mpAnchoredObj->SetPositioningInProgress( true );
77 : 585 : }
78 : :
79 : 4772 : SwObjPositioningInProgress::~SwObjPositioningInProgress()
80 : : {
81 [ + - ]: 4772 : if ( mpAnchoredObj )
82 : : {
83 : : // --> #i52904#
84 : 4772 : mpAnchoredObj->SetPositioningInProgress( mbOldObjPositioningInProgress );
85 : : }
86 : 4772 : }
87 : :
88 : : // ============================================================================
89 : :
90 [ - + ]: 33268 : TYPEINIT0(SwAnchoredObject);
91 : :
92 : 1299 : SwAnchoredObject::SwAnchoredObject() :
93 : : mpDrawObj( 0L ),
94 : : mpAnchorFrm( 0L ),
95 : : // --> #i28701#
96 : : mpPageFrm( 0L ),
97 : : maRelPos(),
98 : : maLastCharRect(),
99 : : mnLastTopOfLine( 0L ),
100 : : mpVertPosOrientFrm( 0L ),
101 : : // --> #i28701#
102 : : mbPositioningInProgress( false ),
103 : : mbConsiderForTextWrap( false ),
104 : : mbPositionLocked( false ),
105 : : // --> #i40147#
106 : : mbKeepPositionLockedForSection( false ),
107 : : mbRestartLayoutProcess( false ),
108 : : // --> #i35911#
109 : : mbClearedEnvironment( false ),
110 : : // --> #i3317#
111 : : mbTmpConsiderWrapInfluence( false ),
112 : : // --> #i68520#
113 : : maObjRectWithSpaces(),
114 : : mbObjRectWithSpacesValid( false ),
115 : 1299 : maLastObjRect()
116 : : {
117 : 1299 : }
118 : :
119 : 1203 : SwAnchoredObject::~SwAnchoredObject()
120 : : {
121 [ - + ]: 1203 : }
122 : :
123 : : // =============================================================================
124 : : // accessors for member <mpDrawObj>
125 : : // =============================================================================
126 : 1299 : void SwAnchoredObject::SetDrawObj( SdrObject& _rDrawObj )
127 : : {
128 : 1299 : mpDrawObj = &_rDrawObj;
129 : 1299 : }
130 : :
131 : 62387 : const SdrObject* SwAnchoredObject::GetDrawObj() const
132 : : {
133 : 62387 : return mpDrawObj;
134 : : }
135 : :
136 : 36497 : SdrObject* SwAnchoredObject::DrawObj()
137 : : {
138 : 36497 : return mpDrawObj;
139 : : }
140 : :
141 : : // =============================================================================
142 : : // accessors for member <mpAnchorFrm>
143 : : // =============================================================================
144 : 39463 : const SwFrm* SwAnchoredObject::GetAnchorFrm() const
145 : : {
146 : 39463 : return mpAnchorFrm;
147 : : }
148 : :
149 : 49788 : SwFrm* SwAnchoredObject::AnchorFrm()
150 : : {
151 : 49788 : return mpAnchorFrm;
152 : : }
153 : :
154 : 2272 : void SwAnchoredObject::ChgAnchorFrm( SwFrm* _pNewAnchorFrm )
155 : : {
156 : 2272 : mpAnchorFrm = _pNewAnchorFrm;
157 : :
158 [ + + ]: 2272 : if ( mpAnchorFrm )
159 : : {
160 : 1184 : ObjectAttachedToAnchorFrame();
161 : : }
162 : 2272 : }
163 : :
164 : : /** determine anchor frame containing the anchor position
165 : :
166 : : #i26945#
167 : : the anchor frame, which is determined, is <mpAnchorFrm>
168 : : for an at-page, at-frame or at-paragraph anchored object
169 : : and the anchor character frame for an at-character and as-character
170 : : anchored object.
171 : :
172 : : @author OD
173 : : */
174 : 9537 : SwFrm* SwAnchoredObject::GetAnchorFrmContainingAnchPos()
175 : : {
176 : 9537 : SwFrm* pAnchorFrmContainingAnchPos = FindAnchorCharFrm();
177 [ + + ]: 9537 : if ( !pAnchorFrmContainingAnchPos )
178 : : {
179 : 2524 : pAnchorFrmContainingAnchPos = AnchorFrm();
180 : : }
181 : :
182 : 9537 : return pAnchorFrmContainingAnchPos;
183 : : }
184 : :
185 : : // =============================================================================
186 : : // #i28701# accessors for member <mpPageFrm>
187 : : // =============================================================================
188 : 100650 : SwPageFrm* SwAnchoredObject::GetPageFrm()
189 : : {
190 : 100650 : return mpPageFrm;
191 : : }
192 : :
193 : 537 : const SwPageFrm* SwAnchoredObject::GetPageFrm() const
194 : : {
195 : 537 : return mpPageFrm;
196 : : }
197 : :
198 : 439 : void SwAnchoredObject::SetPageFrm( SwPageFrm* _pNewPageFrm )
199 : : {
200 [ + - ]: 439 : if ( mpPageFrm != _pNewPageFrm )
201 : : {
202 : : // clear member, which denotes the layout frame at which the vertical
203 : : // position is oriented at, if it doesn't fit to the new page frame.
204 [ + + ]: 439 : if ( GetVertPosOrientFrm() &&
[ - + # # ]
[ + + ]
205 : : ( !_pNewPageFrm ||
206 : 0 : _pNewPageFrm != GetVertPosOrientFrm()->FindPageFrm() ) )
207 : : {
208 : 180 : ClearVertPosOrientFrm();
209 : : }
210 : :
211 : : // assign new page frame
212 : 439 : mpPageFrm = _pNewPageFrm;
213 : : }
214 : 439 : }
215 : :
216 : : // =============================================================================
217 : : // accessors for member <maLastCharRect>
218 : : // =============================================================================
219 : 518 : const SwRect& SwAnchoredObject::GetLastCharRect() const
220 : : {
221 : 518 : return maLastCharRect;
222 : : }
223 : :
224 : 0 : SwTwips SwAnchoredObject::GetRelCharX( const SwFrm* pFrm ) const
225 : : {
226 : 0 : return maLastCharRect.Left() - pFrm->Frm().Left();
227 : : }
228 : :
229 : 0 : SwTwips SwAnchoredObject::GetRelCharY( const SwFrm* pFrm ) const
230 : : {
231 : 0 : return maLastCharRect.Bottom() - pFrm->Frm().Top();
232 : : }
233 : :
234 : 0 : void SwAnchoredObject::AddLastCharY( long nDiff )
235 : : {
236 : 0 : maLastCharRect.Pos().Y() += nDiff;
237 : 0 : }
238 : :
239 : 0 : void SwAnchoredObject::ResetLastCharRectHeight()
240 : : {
241 : 0 : maLastCharRect.Height( 0 );
242 : 0 : }
243 : : // =============================================================================
244 : : // accessors for member <mpVertPosOrientFrm>
245 : : // =============================================================================
246 : 339 : void SwAnchoredObject::SetVertPosOrientFrm( const SwLayoutFrm& _rVertPosOrientFrm )
247 : : {
248 : 339 : mpVertPosOrientFrm = &_rVertPosOrientFrm;
249 : :
250 : : // #i28701# - take over functionality of deleted method
251 : : // <SwFlyAtCntFrm::AssertPage()>: assure for at-paragraph and at-character
252 : : // an anchored object, that it is registered at the correct page frame
253 : 339 : RegisterAtCorrectPage();
254 : 339 : }
255 : :
256 : : // =============================================================================
257 : : // accessors for member <mnLastTopOfLine>
258 : : // =============================================================================
259 : 354 : SwTwips SwAnchoredObject::GetLastTopOfLine() const
260 : : {
261 : 354 : return mnLastTopOfLine;
262 : : }
263 : :
264 : : // #i28701# - follow-up of #i22341#
265 : 0 : void SwAnchoredObject::AddLastTopOfLineY( SwTwips _nDiff )
266 : : {
267 : 0 : mnLastTopOfLine += _nDiff;
268 : 0 : }
269 : :
270 : : /** check anchor character rectangle and top of line
271 : :
272 : : #i26791
273 : : For to-character anchored Writer fly frames the members <maLastCharRect>
274 : : and <maLastTopOfLine> are updated. These are checked for change and
275 : : depending on the applied positioning, it's decided, if the Writer fly
276 : : frame has to be invalidated.
277 : :
278 : : add parameter <_bCheckForParaPorInf>, default value <true>
279 : :
280 : : @author OD
281 : : */
282 : 278 : void SwAnchoredObject::CheckCharRectAndTopOfLine(
283 : : const bool _bCheckForParaPorInf )
284 : : {
285 [ + - + - ]: 556 : if ( GetAnchorFrm() &&
[ + - ]
286 : 278 : GetAnchorFrm()->IsTxtFrm() )
287 : : {
288 : 278 : const SwFmtAnchor& rAnch = GetFrmFmt().GetAnchor();
289 [ + - ]: 556 : if ( (rAnch.GetAnchorId() == FLY_AT_CHAR) &&
[ + - + - ]
290 : 278 : rAnch.GetCntntAnchor() )
291 : : {
292 : : // --> if requested, assure that anchor frame,
293 : : // which contains the anchor character, has a paragraph portion information.
294 : : // The paragraph portion information is needed to determine the
295 : : // anchor character rectangle respectively the top of the line.
296 : : // Thus, a format of this frame is avoided to determine the
297 : : // paragraph portion information.
298 : : // --> #i26945# - use new method <FindAnchorCharFrm()>
299 : 278 : const SwTxtFrm& aAnchorCharFrm = *(FindAnchorCharFrm());
300 [ + + ][ + + ]: 278 : if ( !_bCheckForParaPorInf || aAnchorCharFrm.HasPara() )
[ + + ]
301 : : {
302 : 254 : _CheckCharRect( rAnch, aAnchorCharFrm );
303 : 254 : _CheckTopOfLine( rAnch, aAnchorCharFrm );
304 : : }
305 : : }
306 : : }
307 : 278 : }
308 : :
309 : : /** check anchor character rectangle
310 : :
311 : : #i22341#
312 : : helper method for method <CheckCharRectAndTopOfLine()>
313 : : For to-character anchored Writer fly frames the member <maLastCharRect>
314 : : is updated. This is checked for change and depending on the applied
315 : : positioning, it's decided, if the Writer fly frame has to be invalidated.
316 : :
317 : : improvement - add second parameter <_rAnchorCharFrm>
318 : :
319 : : @author OD
320 : : */
321 : 254 : void SwAnchoredObject::_CheckCharRect( const SwFmtAnchor& _rAnch,
322 : : const SwTxtFrm& _rAnchorCharFrm )
323 : : {
324 : : // determine rectangle of anchor character. If not exist, abort operation
325 : 254 : SwRect aCharRect;
326 [ + - ][ + - ]: 254 : if ( !_rAnchorCharFrm.GetAutoPos( aCharRect, *_rAnch.GetCntntAnchor() ) )
[ + - ]
327 : : {
328 : 254 : return;
329 : : }
330 : : // check, if anchor character rectangle has changed
331 [ + + ]: 254 : if ( aCharRect != maLastCharRect )
332 : : {
333 : : // check positioning and alignment for invalidation of position
334 : : {
335 [ + - ][ - + ]: 139 : SWRECTFN( (&_rAnchorCharFrm) );
[ # # ][ # # ]
[ - + ]
336 : : // determine positioning and alignment
337 [ + - ][ + - ]: 139 : SwFmtVertOrient aVert( GetFrmFmt().GetVertOrient() );
[ + - ]
338 [ + - ][ + - ]: 139 : SwFmtHoriOrient aHori( GetFrmFmt().GetHoriOrient() );
[ + - ]
339 : : // check for anchor character rectangle changes for certain
340 : : // positionings and alignments
341 : : // add condition to invalidate position,
342 : : // if vertical aligned at frame/page area and vertical position
343 : : // of anchor character has changed.
344 : 139 : const sal_Int16 eVertRelOrient = aVert.GetRelationOrient();
345 [ - + ][ - + ]: 278 : if ( ( aHori.GetRelationOrient() == text::RelOrientation::CHAR &&
[ # # ][ # # ]
[ + + ][ - + ]
[ # # ][ # # ]
[ + + ][ + + ]
[ + + ]
346 [ + - ][ + - ]: 54 : (aCharRect.*fnRect->fnGetLeft)() !=
347 [ + - ][ + - ]: 54 : (maLastCharRect.*fnRect->fnGetLeft)() ) ||
348 : : ( eVertRelOrient == text::RelOrientation::CHAR &&
349 [ # # ][ # # ]: 0 : ( (aCharRect.*fnRect->fnGetTop)() !=
350 [ # # ][ # # ]: 0 : (maLastCharRect.*fnRect->fnGetTop)() ||
351 [ # # ][ # # ]: 0 : (aCharRect.*fnRect->fnGetHeight)() !=
352 [ # # ][ # # ]: 0 : (maLastCharRect.*fnRect->fnGetHeight)() ) ) ||
353 : : ( ( ( eVertRelOrient == text::RelOrientation::FRAME ) ||
354 : : ( eVertRelOrient == text::RelOrientation::PRINT_AREA ) ||
355 : : ( eVertRelOrient == text::RelOrientation::PAGE_FRAME ) ||
356 : : ( eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA ) ) &&
357 [ + - ][ + - ]: 85 : ( (aCharRect.*fnRect->fnGetTop)() !=
358 [ + - ][ + - ]: 85 : (maLastCharRect.*fnRect->fnGetTop)() ) ) )
359 : : {
360 : : // #i26945#, #i35911# - unlock position of
361 : : // anchored object, if it isn't registered at the page,
362 : : // where its anchor character frame is on.
363 [ + - ][ + - ]: 118 : if ( GetPageFrm() != _rAnchorCharFrm.FindPageFrm() )
[ - + ]
364 : : {
365 : 0 : UnlockPosition();
366 : : }
367 [ + - ]: 118 : InvalidateObjPos();
368 [ + - ][ + - ]: 139 : }
369 : : }
370 : : // keep new anchor character rectangle
371 : 254 : maLastCharRect = aCharRect;
372 : : }
373 : : }
374 : :
375 : : /** check top of line
376 : :
377 : : #i22341#
378 : : helper method for method <CheckCharRectAndTopOfLine()>
379 : : For to-character anchored Writer fly frames the member <mnLastTopOfLine>
380 : : is updated. This is checked for change and depending on the applied
381 : : positioning, it's decided, if the Writer fly frame has to be invalidated.
382 : :
383 : : improvement - add second parameter <_rAnchorCharFrm>
384 : :
385 : : @author OD
386 : : */
387 : 254 : void SwAnchoredObject::_CheckTopOfLine( const SwFmtAnchor& _rAnch,
388 : : const SwTxtFrm& _rAnchorCharFrm )
389 : : {
390 : 254 : SwTwips nTopOfLine = 0L;
391 [ + - ][ + - ]: 254 : if ( _rAnchorCharFrm.GetTopOfLine( nTopOfLine, *_rAnch.GetCntntAnchor() ) )
[ + - ]
392 : : {
393 [ + + ]: 254 : if ( nTopOfLine != mnLastTopOfLine )
394 : : {
395 : : // check alignment for invalidation of position
396 [ + - ][ + - ]: 73 : if ( GetFrmFmt().GetVertOrient().GetRelationOrient() == text::RelOrientation::TEXT_LINE )
[ + + ]
397 : : {
398 : : // #i26945#, #i35911# - unlock position of
399 : : // anchored object, if it isn't registered at the page,
400 : : // where its anchor character frame is on.
401 [ + - ][ + - ]: 9 : if ( GetPageFrm() != _rAnchorCharFrm.FindPageFrm() )
[ - + ]
402 : : {
403 : 0 : UnlockPosition();
404 : : }
405 [ + - ]: 9 : InvalidateObjPos();
406 : : }
407 : : // keep new top of line value
408 : 73 : mnLastTopOfLine = nTopOfLine;
409 : : }
410 : : }
411 : 254 : }
412 : :
413 : 0 : void SwAnchoredObject::ClearCharRectAndTopOfLine()
414 : : {
415 : 0 : maLastCharRect.Clear();
416 : 0 : mnLastTopOfLine = 0;
417 : 0 : }
418 : :
419 : 2973 : const Point SwAnchoredObject::GetCurrRelPos() const
420 : : {
421 : 2973 : return maRelPos;
422 : : }
423 : 1656 : void SwAnchoredObject::SetCurrRelPos( Point _aRelPos )
424 : : {
425 : 1656 : maRelPos = _aRelPos;
426 : 1656 : }
427 : :
428 : 1184 : void SwAnchoredObject::ObjectAttachedToAnchorFrame()
429 : : {
430 : : // default behaviour:
431 : : // update layout direction, the anchored object is assigned to
432 : 1184 : UpdateLayoutDir();
433 : 1184 : }
434 : :
435 : : /** method update layout direction the layout direction, the anchored
436 : : object is in
437 : :
438 : : #i31698#
439 : : method has typically to be called, if the anchored object gets its
440 : : anchor frame assigned.
441 : :
442 : : @author OD
443 : : */
444 : 1184 : void SwAnchoredObject::UpdateLayoutDir()
445 : : {
446 : 1184 : SwFrmFmt::tLayoutDir nLayoutDir = SwFrmFmt::HORI_L2R;
447 : 1184 : const SwFrm* pAnchorFrm = GetAnchorFrm();
448 [ + - ]: 1184 : if ( pAnchorFrm )
449 : : {
450 : 1184 : const bool bVert = pAnchorFrm->IsVertical();
451 : 1184 : const bool bR2L = pAnchorFrm->IsRightToLeft();
452 [ - + ]: 1184 : if ( bVert )
453 : : {
454 : 0 : nLayoutDir = SwFrmFmt::VERT_R2L;
455 : : }
456 [ - + ]: 1184 : else if ( bR2L )
457 : : {
458 : 0 : nLayoutDir = SwFrmFmt::HORI_R2L;
459 : : }
460 : : }
461 : 1184 : GetFrmFmt().SetLayoutDir( nLayoutDir );
462 : 1184 : }
463 : :
464 : : /** method to perform necessary invalidations for the positioning of
465 : : objects, for whose the wrapping style influence has to be considered
466 : : on the object positioning.
467 : :
468 : : #i28701#
469 : :
470 : : @author OD
471 : : */
472 : 27 : void SwAnchoredObject::InvalidateObjPosForConsiderWrapInfluence(
473 : : const bool _bNotifyBackgrd )
474 : : {
475 [ + - ]: 27 : if ( ConsiderObjWrapInfluenceOnObjPos() )
476 : : {
477 : : // indicate that object has not to be considered for text wrap
478 : 27 : SetConsiderForTextWrap( false );
479 : : // unlock position
480 : 27 : UnlockPosition();
481 : : // invalidate position
482 : 27 : InvalidateObjPos();
483 : : // invalidate 'background', if requested
484 [ + - ]: 27 : if ( _bNotifyBackgrd )
485 : : {
486 : 27 : NotifyBackground( GetPageFrm(), GetObjRectWithSpaces(), PREP_FLY_LEAVE );
487 : : }
488 : : }
489 : 27 : }
490 : :
491 : : /** method to determine, if wrapping style influence of the anchored
492 : : object has to be considered on the object positioning
493 : :
494 : : #i28701#
495 : : Note: result of this method also decides, if the booleans for the
496 : : layout process are of relevance.
497 : :
498 : : @author OD
499 : : */
500 : 13539 : bool SwAnchoredObject::ConsiderObjWrapInfluenceOnObjPos() const
501 : : {
502 : 13539 : bool bRet( false );
503 : :
504 : 13539 : const SwFrmFmt& rObjFmt = GetFrmFmt();
505 : :
506 : : // --> #i3317# - add condition <IsTmpConsiderWrapInfluence()>
507 : : // --> #i55204#
508 : : // - correction: wrapping style influence has been considered, if condition
509 : : // <IsTmpConsiderWrapInfluence()> is hold, regardless of its anchor type
510 : : // or its wrapping style.
511 [ + + ]: 13539 : if ( IsTmpConsiderWrapInfluence() )
512 : : {
513 : 294 : bRet = true;
514 : : }
515 [ + + ]: 13245 : else if ( rObjFmt.getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) )
516 : : {
517 : 345 : const SwFmtAnchor& rAnchor = rObjFmt.GetAnchor();
518 [ - + ][ + + : 690 : if ( ((rAnchor.GetAnchorId() == FLY_AT_CHAR) ||
- + - + ]
519 : 45 : (rAnchor.GetAnchorId() == FLY_AT_PARA)) &&
520 : 300 : rObjFmt.GetSurround().GetSurround() != SURROUND_THROUGHT )
521 : : {
522 : : // --> #i34520# - text also wraps around anchored
523 : : // objects in the layer Hell - see the text formatting.
524 : : // Thus, it hasn't to be checked here.
525 : 0 : bRet = true;
526 : : }
527 : : }
528 : :
529 : 13539 : return bRet;
530 : : }
531 : :
532 : : /** method to determine, if other anchored objects, also attached at
533 : : to the anchor frame, have to consider its wrap influence.
534 : :
535 : : // --> #i43255#
536 : :
537 : : @author OD
538 : : */
539 : 275 : bool SwAnchoredObject::ConsiderObjWrapInfluenceOfOtherObjs() const
540 : : {
541 : 275 : bool bRet( false );
542 : :
543 : 275 : const SwSortedObjs* pObjs = GetAnchorFrm()->GetDrawObjs();
544 [ + + ]: 275 : if ( pObjs->Count() > 1 )
545 : : {
546 : 110 : sal_uInt32 i = 0;
547 [ + + ]: 416 : for ( ; i < pObjs->Count(); ++i )
548 : : {
549 : 306 : SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
550 [ - + ]: 502 : if ( pAnchoredObj != this &&
[ + + - + ]
551 : 196 : pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() )
552 : : {
553 : 0 : bRet = true;
554 : 0 : break;
555 : : }
556 : : }
557 : : }
558 : :
559 : 275 : return bRet;
560 : : }
561 : :
562 : : // =============================================================================
563 : : // --> #i28701# - accessors to booleans for layout process
564 : : // =============================================================================
565 : 3730 : bool SwAnchoredObject::ConsiderForTextWrap() const
566 : : {
567 [ + + ]: 3730 : if ( ConsiderObjWrapInfluenceOnObjPos() )
568 : 54 : return mbConsiderForTextWrap;
569 : : else
570 : 3730 : return true;
571 : : }
572 : :
573 : 45 : void SwAnchoredObject::SetConsiderForTextWrap( const bool _bConsiderForTextWrap )
574 : : {
575 : 45 : mbConsiderForTextWrap = _bConsiderForTextWrap;
576 : 45 : }
577 : :
578 : 197 : bool SwAnchoredObject::PositionLocked() const
579 : : {
580 [ + + ]: 197 : if ( ConsiderObjWrapInfluenceOnObjPos() )
581 : 33 : return mbPositionLocked;
582 : : else
583 : 197 : return false;
584 : : }
585 : :
586 : 2342 : bool SwAnchoredObject::RestartLayoutProcess() const
587 : : {
588 [ + + ]: 2342 : if ( ConsiderObjWrapInfluenceOnObjPos() )
589 : 39 : return mbRestartLayoutProcess;
590 : : else
591 : 2342 : return false;
592 : : }
593 : :
594 : 2365 : void SwAnchoredObject::SetRestartLayoutProcess( const bool _bRestartLayoutProcess )
595 : : {
596 : 2365 : mbRestartLayoutProcess = _bRestartLayoutProcess;
597 : 2365 : }
598 : :
599 : : // --> #i35911#
600 : 272 : bool SwAnchoredObject::ClearedEnvironment() const
601 : : {
602 [ + + ]: 272 : if ( ConsiderObjWrapInfluenceOnObjPos() )
603 : 18 : return mbClearedEnvironment;
604 : : else
605 : 272 : return false;
606 : : }
607 : 9 : void SwAnchoredObject::SetClearedEnvironment( const bool _bClearedEnvironment )
608 : : {
609 : 9 : mbClearedEnvironment = _bClearedEnvironment;
610 : 9 : }
611 : :
612 : : /** method to determine, if due to anchored object size and wrapping
613 : : style, its layout environment is cleared.
614 : :
615 : : #i35911#
616 : :
617 : : @author OD
618 : : */
619 : 0 : bool SwAnchoredObject::HasClearedEnvironment() const
620 : : {
621 : 0 : bool bHasClearedEnvironment( false );
622 : :
623 : : // --> #i43913# - layout frame, vertical position is orient at, has to be set.
624 : : OSL_ENSURE( GetVertPosOrientFrm(),
625 : : "<SwAnchoredObject::HasClearedEnvironment()> - layout frame missing, at which the vertical position is oriented at." );
626 [ # # # # : 0 : if ( GetVertPosOrientFrm() &&
# # # # ]
[ # # ]
627 : 0 : GetAnchorFrm()->IsTxtFrm() &&
628 : 0 : !static_cast<const SwTxtFrm*>(GetAnchorFrm())->IsFollow() &&
629 : 0 : static_cast<const SwTxtFrm*>(GetAnchorFrm())->FindPageFrm()->GetPhyPageNum() >=
630 : 0 : GetPageFrm()->GetPhyPageNum() )
631 : : {
632 : 0 : const SwFrm* pTmpFrm = GetVertPosOrientFrm()->Lower();
633 [ # # ][ # # ]: 0 : while ( pTmpFrm && pTmpFrm->IsLayoutFrm() && !pTmpFrm->IsTabFrm() )
[ # # ][ # # ]
634 : : {
635 : 0 : pTmpFrm = static_cast<const SwLayoutFrm*>(pTmpFrm)->Lower();
636 : : }
637 [ # # ]: 0 : if ( !pTmpFrm )
638 : : {
639 : 0 : bHasClearedEnvironment = true;
640 : : }
641 [ # # ][ # # ]: 0 : else if ( pTmpFrm->IsTxtFrm() && !pTmpFrm->GetNext() )
[ # # ]
642 : : {
643 : 0 : const SwTxtFrm* pTmpTxtFrm = static_cast<const SwTxtFrm*>(pTmpFrm);
644 [ # # # # : 0 : if ( pTmpTxtFrm->IsUndersized() ||
# # ][ # # ]
645 : 0 : ( pTmpTxtFrm->GetFollow() &&
646 : 0 : pTmpTxtFrm->GetFollow()->GetOfst() == 0 ) )
647 : : {
648 : 0 : bHasClearedEnvironment = true;
649 : : }
650 : : }
651 : : }
652 : :
653 : 0 : return bHasClearedEnvironment;
654 : : }
655 : :
656 : : /** method to add spacing to object area
657 : :
658 : : #i28701#
659 : : #i68520# - return constant reference and use cache
660 : :
661 : : @author OD
662 : : */
663 : 17685 : const SwRect& SwAnchoredObject::GetObjRectWithSpaces() const
664 : : {
665 [ + + - + ]: 50028 : if ( mbObjRectWithSpacesValid &&
[ - + ]
666 [ + - ][ + + ]: 32343 : maLastObjRect != GetObjRect() )
[ # # ]
667 : : {
668 : : OSL_FAIL( "<SwAnchoredObject::GetObjRectWithSpaces> - cache for object rectangle inclusive spaces marked as valid, but it couldn't be. Missing invalidation of cache. Please inform OD." );
669 : 0 : InvalidateObjRectWithSpaces();
670 : : }
671 [ + + ]: 17685 : if ( !mbObjRectWithSpacesValid )
672 : : {
673 : : // --> #i70122# - correction:
674 : : // use bounding rectangle of anchored objects.
675 : : // maObjRectWithSpaces = GetObjRect();
676 : 3027 : maObjRectWithSpaces = GetObjBoundRect();
677 : 3027 : const SwFrmFmt& rFmt = GetFrmFmt();
678 : 3027 : const SvxULSpaceItem& rUL = rFmt.GetULSpace();
679 : 3027 : const SvxLRSpaceItem& rLR = rFmt.GetLRSpace();
680 : : {
681 : 3027 : maObjRectWithSpaces.Top ( Max( maObjRectWithSpaces.Top() - long(rUL.GetUpper()), 0L ));
682 : 3027 : maObjRectWithSpaces.Left( Max( maObjRectWithSpaces.Left()- long(rLR.GetLeft()), 0L ));
683 : 3027 : maObjRectWithSpaces.SSize().Height() += rUL.GetLower();
684 : 3027 : maObjRectWithSpaces.SSize().Width() += rLR.GetRight();
685 : : }
686 : :
687 : 3027 : mbObjRectWithSpacesValid = true;
688 : 3027 : maLastObjRect = GetObjRect();
689 : : }
690 : :
691 : 17685 : return maObjRectWithSpaces;
692 : : }
693 : :
694 : : // --> #i68520#
695 : 959 : void SwAnchoredObject::SetObjTop( const SwTwips _nTop)
696 : : {
697 : 959 : const bool bTopChanged( _SetObjTop( _nTop ) );
698 [ + + ]: 959 : if ( bTopChanged )
699 : : {
700 : 176 : mbObjRectWithSpacesValid = false;
701 : : }
702 : 959 : }
703 : :
704 : 329 : void SwAnchoredObject::SetObjLeft( const SwTwips _nLeft)
705 : : {
706 : 329 : const bool bLeftChanged( _SetObjLeft( _nLeft ) );
707 [ + + ]: 329 : if ( bLeftChanged )
708 : : {
709 : 184 : mbObjRectWithSpacesValid = false;
710 : : }
711 : 329 : }
712 : :
713 : : /** method to update anchored object in the <SwSortedObjs> lists
714 : :
715 : : #i28701#
716 : : If document compatibility option 'Consider wrapping style influence
717 : : on object positioning' is ON, additionally all anchored objects
718 : : at the anchor frame and all following anchored objects on the page
719 : : frame are invalidated.
720 : :
721 : : @author OD
722 : : */
723 : 42 : void SwAnchoredObject::UpdateObjInSortedList()
724 : : {
725 [ + - ]: 42 : if ( GetAnchorFrm() )
726 : : {
727 [ - + ]: 42 : if ( GetFrmFmt().getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) )
728 : : {
729 : : // invalidate position of all anchored objects at anchor frame
730 [ # # ]: 0 : if ( GetAnchorFrm()->GetDrawObjs() )
731 : : {
732 : 0 : const SwSortedObjs* pObjs = GetAnchorFrm()->GetDrawObjs();
733 : : // determine start index
734 : 0 : sal_uInt32 i = 0;
735 [ # # ]: 0 : for ( ; i < pObjs->Count(); ++i )
736 : : {
737 : 0 : SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
738 [ # # ]: 0 : if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() )
739 : 0 : pAnchoredObj->InvalidateObjPosForConsiderWrapInfluence( true );
740 : : else
741 : 0 : pAnchoredObj->InvalidateObjPos();
742 : : }
743 : : }
744 : : // invalidate all following anchored objects on the page frame
745 [ # # ][ # # ]: 0 : if ( GetPageFrm() && GetPageFrm()->GetSortedObjs() )
[ # # ]
746 : : {
747 : 0 : const SwSortedObjs* pObjs = GetPageFrm()->GetSortedObjs();
748 : : // determine start index
749 : 0 : sal_uInt32 i = pObjs->ListPosOf( *this ) + 1;
750 [ # # ]: 0 : for ( ; i < pObjs->Count(); ++i )
751 : : {
752 : 0 : SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
753 [ # # ]: 0 : if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() )
754 : 0 : pAnchoredObj->InvalidateObjPosForConsiderWrapInfluence( true );
755 : : else
756 : 0 : pAnchoredObj->InvalidateObjPos();
757 : : }
758 : : }
759 : : }
760 : : // update its position in the sorted object list of its anchor frame
761 : 42 : AnchorFrm()->GetDrawObjs()->Update( *this );
762 : : // update its position in the sorted object list of its page frame
763 : : // note: as-character anchored object aren't registered at a page frame
764 [ + + ]: 42 : if ( GetFrmFmt().GetAnchor().GetAnchorId() != FLY_AS_CHAR )
765 : : {
766 : 28 : GetPageFrm()->GetSortedObjs()->Update( *this );
767 : : }
768 : : }
769 : 42 : }
770 : :
771 : : /** method to determine, if invalidation of position is allowed
772 : :
773 : : #i28701#
774 : :
775 : : @author OD
776 : : */
777 : 178 : bool SwAnchoredObject::InvalidationOfPosAllowed() const
778 : : {
779 : : // --> Check, if page frame layout is in progress,
780 : : // isn't needed, because of anchored object, whose are moved forward.
781 : 178 : return !PositionLocked();
782 : : }
783 : :
784 : : /** method to determine the page frame, on which the 'anchor' of
785 : : the given anchored object is.
786 : :
787 : : #i28701#
788 : : #i33751#, #i34060#
789 : : Adjust meaning of method and thus its name: If the anchored object
790 : : or its anchor isn't correctly inserted in the layout, no page frame
791 : : can be found. Thus, the return type changed to be a pointer and can
792 : : be NULL.
793 : :
794 : : @author OD
795 : : */
796 : 7100 : SwPageFrm* SwAnchoredObject::FindPageFrmOfAnchor()
797 : : {
798 : 7100 : SwPageFrm* pRetPageFrm = 0L;
799 : :
800 : : // --> #i44339# - check, if anchor frame exists.
801 [ + - ]: 7100 : if ( mpAnchorFrm )
802 : : {
803 : : // --> #i26945# - use new method <GetAnchorFrmContainingAnchPos()>
804 : 7100 : pRetPageFrm = GetAnchorFrmContainingAnchPos()->FindPageFrm();
805 : : }
806 : :
807 : 7100 : return pRetPageFrm;
808 : : }
809 : :
810 : : /** get frame, which contains the anchor character, if the object
811 : : is anchored at-character or as-character.
812 : :
813 : : #i26945#
814 : :
815 : : @author OD
816 : :
817 : : @return SwTxtFrm*
818 : : text frame containing the anchor character. It's NULL, if the object
819 : : isn't anchored at-character resp. as-character.
820 : : */
821 : 14136 : SwTxtFrm* SwAnchoredObject::FindAnchorCharFrm()
822 : : {
823 : 14136 : SwTxtFrm* pAnchorCharFrm( 0L );
824 : :
825 : : // --> #i44339# - check, if anchor frame exists.
826 [ + - ]: 14136 : if ( mpAnchorFrm )
827 : : {
828 : 14136 : const SwFmtAnchor& rAnch = GetFrmFmt().GetAnchor();
829 [ + + ]: 25764 : if ((rAnch.GetAnchorId() == FLY_AT_CHAR) ||
[ + + + + ]
830 : 11628 : (rAnch.GetAnchorId() == FLY_AS_CHAR))
831 : : {
832 : 10841 : pAnchorCharFrm = &(static_cast<SwTxtFrm*>(AnchorFrm())->
833 : 21682 : GetFrmAtOfst( rAnch.GetCntntAnchor()->nContent.GetIndex() ));
834 : : }
835 : : }
836 : :
837 : 14136 : return pAnchorCharFrm;
838 : : }
839 : :
840 : : /** method to determine, if a format on the anchored object is possible
841 : :
842 : : #i28701#
843 : : A format is possible, if anchored object is in an invisible layer.
844 : : Note: method is virtual to refine the conditions for the sub-classes.
845 : :
846 : : @author OD
847 : : */
848 : 2504 : bool SwAnchoredObject::IsFormatPossible() const
849 : : {
850 [ + - ]: 2504 : return GetFrmFmt().GetDoc()->IsVisibleLayerId( GetDrawObj()->GetLayer() );
851 : : }
852 : :
853 : : // --> #i3317#
854 : 18 : void SwAnchoredObject::SetTmpConsiderWrapInfluence( const bool _bTmpConsiderWrapInfluence )
855 : : {
856 : 18 : mbTmpConsiderWrapInfluence = _bTmpConsiderWrapInfluence;
857 : : // --> #i35911#
858 [ + + ]: 18 : if ( mbTmpConsiderWrapInfluence )
859 : : {
860 : 9 : SwLayouter::InsertObjForTmpConsiderWrapInfluence( *(GetFrmFmt().GetDoc()),
861 : 9 : *this );
862 : : }
863 : 18 : }
864 : :
865 : 13539 : bool SwAnchoredObject::IsTmpConsiderWrapInfluence() const
866 : : {
867 : 13539 : return mbTmpConsiderWrapInfluence;
868 : : }
869 : :
870 : 3 : void SwAnchoredObject::SetTmpConsiderWrapInfluenceOfOtherObjs( const bool bTmpConsiderWrapInfluence )
871 : : {
872 : 3 : const SwSortedObjs* pObjs = GetAnchorFrm()->GetDrawObjs();
873 [ + - ]: 3 : if ( pObjs->Count() > 1 )
874 : : {
875 : 3 : sal_uInt32 i = 0;
876 [ + + ]: 12 : for ( ; i < pObjs->Count(); ++i )
877 : : {
878 : 9 : SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
879 [ + + ]: 9 : if ( pAnchoredObj != this )
880 : : {
881 : 6 : pAnchoredObj->SetTmpConsiderWrapInfluence( bTmpConsiderWrapInfluence );
882 : : }
883 : : }
884 : : }
885 : 3 : }
886 : :
887 : : /** method to determine, if the anchored object is overlapping with a
888 : : previous column
889 : :
890 : : #i3317#
891 : : overlapping with a previous column means, that the object overlaps
892 : : with a column, which is a previous one of the column its anchor
893 : : frame is in.
894 : : Only applied for at-paragraph and at-character anchored objects.
895 : :
896 : : @author OD
897 : : */
898 : 281 : bool SwAnchoredObject::OverlapsPrevColumn() const
899 : : {
900 : 281 : bool bOverlapsPrevColumn( false );
901 : :
902 [ + - ][ + - ]: 281 : if ( mpAnchorFrm && mpAnchorFrm->IsTxtFrm() )
[ + - ]
903 : : {
904 : 281 : const SwFrm* pColFrm = mpAnchorFrm->FindColFrm();
905 [ # # ][ - + ]: 281 : if ( pColFrm && pColFrm->GetPrev() )
[ - + ]
906 : : {
907 : 0 : const SwFrm* pTmpColFrm = pColFrm->GetPrev();
908 : 0 : SwRect aChkRect;
909 [ # # ]: 0 : while ( pTmpColFrm )
910 : : {
911 [ # # ]: 0 : aChkRect.Union( pTmpColFrm->Frm() );
912 : 0 : pTmpColFrm = pTmpColFrm->GetPrev();
913 : : }
914 [ # # ][ # # ]: 0 : bOverlapsPrevColumn = GetObjRect().IsOver( aChkRect );
915 : : }
916 : : }
917 : :
918 : 281 : return bOverlapsPrevColumn;
919 : : }
920 : :
921 : : /** method to determine position of anchored object relative to
922 : : anchor frame
923 : :
924 : : #i30669#
925 : : Usage: Needed layout information for WW8 export
926 : :
927 : : @author OD
928 : : */
929 : 0 : Point SwAnchoredObject::GetRelPosToAnchorFrm() const
930 : : {
931 : 0 : Point aRelPos;
932 : :
933 : : OSL_ENSURE( GetAnchorFrm(),
934 : : "<SwAnchoredObject::GetRelPosToAnchorFrm()> - missing anchor frame." );
935 : 0 : aRelPos = GetObjRect().Pos();
936 : 0 : aRelPos -= GetAnchorFrm()->Frm().Pos();
937 : :
938 : 0 : return aRelPos;
939 : : }
940 : :
941 : : /** method to determine position of anchored object relative to
942 : : page frame
943 : :
944 : : #i30669#
945 : : Usage: Needed layout information for WW8 export
946 : : #i33818# - add parameters <_bFollowTextFlow> and
947 : : <_obRelToTableCell>
948 : : If <_bFollowTextFlow> is set and object is anchored inside table,
949 : : the position relative to the table cell is determined. Output
950 : : parameter <_obRelToTableCell> reflects this situation
951 : :
952 : : @author OD
953 : : */
954 : 0 : Point SwAnchoredObject::GetRelPosToPageFrm( const bool _bFollowTextFlow,
955 : : bool& _obRelToTableCell ) const
956 : : {
957 : 0 : Point aRelPos;
958 : 0 : _obRelToTableCell = false;
959 : :
960 : : OSL_ENSURE( GetAnchorFrm(),
961 : : "<SwAnchoredObject::GetRelPosToPageFrm()> - missing anchor frame." );
962 : : OSL_ENSURE( GetAnchorFrm()->FindPageFrm(),
963 : : "<SwAnchoredObject::GetRelPosToPageFrm()> - missing page frame." );
964 : :
965 : 0 : aRelPos = GetObjRect().Pos();
966 : : // --> #i33818# - search for cell frame, if object has to
967 : : // follow the text flow.
968 : 0 : const SwFrm* pFrm( 0L );
969 [ # # ][ # # ]: 0 : if ( _bFollowTextFlow && !GetAnchorFrm()->IsPageFrm() )
[ # # ]
970 : : {
971 : 0 : pFrm = GetAnchorFrm()->GetUpper();
972 [ # # ][ # # ]: 0 : while ( !pFrm->IsCellFrm() && !pFrm->IsPageFrm() )
[ # # ]
973 : : {
974 : 0 : pFrm = pFrm->GetUpper();
975 : : }
976 : : }
977 : : else
978 : : {
979 : 0 : pFrm = GetAnchorFrm()->FindPageFrm();
980 : : }
981 [ # # ]: 0 : if ( pFrm->IsCellFrm() )
982 : : {
983 : 0 : aRelPos -= ( pFrm->Frm().Pos() + pFrm->Prt().Pos() );
984 : 0 : _obRelToTableCell = true;
985 : : }
986 : : else
987 : : {
988 : 0 : aRelPos -= pFrm->Frm().Pos();
989 : : }
990 : :
991 : 0 : return aRelPos;
992 : : }
993 : :
994 : : /** method to determine position of anchored object relative to
995 : : anchor character
996 : :
997 : : #i30669#
998 : : Usage: Needed layout information for WW8 export
999 : :
1000 : : @author OD
1001 : : */
1002 : 0 : Point SwAnchoredObject::GetRelPosToChar() const
1003 : : {
1004 : 0 : Point aRelPos;
1005 : :
1006 : 0 : aRelPos = GetObjRect().Pos();
1007 : 0 : aRelPos -= GetLastCharRect().Pos();
1008 : :
1009 : 0 : return aRelPos;
1010 : : }
1011 : :
1012 : : /** method to determine position of anchored object relative to
1013 : : top of line
1014 : :
1015 : : #i30669#
1016 : : Usage: Needed layout information for WW8 export
1017 : :
1018 : : @author OD
1019 : : */
1020 : 0 : Point SwAnchoredObject::GetRelPosToLine() const
1021 : : {
1022 : 0 : Point aRelPos;
1023 : :
1024 : 0 : aRelPos = GetObjRect().Pos();
1025 : 0 : aRelPos.Y() -= GetLastTopOfLine();
1026 : :
1027 : 0 : return aRelPos;
1028 : : }
1029 : :
1030 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|