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