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