1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: anchoreddrawobject.cxx,v $
10 * $Revision: 1.26.144.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 #include <anchoreddrawobject.hxx>
34 #include <svx/svdobj.hxx>
35 #include <dcontact.hxx>
36 #include <rootfrm.hxx>
37 #include <pagefrm.hxx>
40 #ifndef _TOCNTNTANCHOROBJECTPOSITION_HXX
41 #include <tocntntanchoredobjectposition.hxx>
43 #ifndef _TOLAYOUTANCHOROBJECTPOSITION_HXX
44 #include <tolayoutanchoredobjectposition.hxx>
46 #include <frmtool.hxx>
47 #include <fmtornt.hxx>
48 // --> OD 2004-08-12 #i32795#
51 // --> OD 2004-08-12 #i32795#
52 // template class <std::vector>
56 // --> OD 2004-08-10 #i28749#
57 #include <com/sun/star/text/PositionLayoutDir.hpp>
59 // --> OD 2005-03-09 #i44559#
63 using namespace ::com::sun::star
;
65 // ============================================================================
66 // helper class for correct notification due to the positioning of
67 // the anchored drawing object
68 // ============================================================================
72 SwAnchoredDrawObject
* mpAnchoredDrawObj
;
74 SwPageFrm
* mpOldPageFrm
;
77 SwPosNotify( SwAnchoredDrawObject
* _pAnchoredDrawObj
);
79 // --> OD 2004-08-12 #i32795#
80 Point
LastObjPos() const;
84 SwPosNotify::SwPosNotify( SwAnchoredDrawObject
* _pAnchoredDrawObj
) :
85 mpAnchoredDrawObj( _pAnchoredDrawObj
)
87 maOldObjRect
= mpAnchoredDrawObj
->GetObjRect();
88 // --> OD 2004-10-20 #i35640# - determine correct page frame
89 mpOldPageFrm
= mpAnchoredDrawObj
->GetPageFrm();
93 SwPosNotify::~SwPosNotify()
95 if ( maOldObjRect
!= mpAnchoredDrawObj
->GetObjRect() )
97 if( maOldObjRect
.HasArea() && mpOldPageFrm
)
99 mpAnchoredDrawObj
->NotifyBackground( mpOldPageFrm
, maOldObjRect
,
102 SwRect
aNewObjRect( mpAnchoredDrawObj
->GetObjRect() );
103 if( aNewObjRect
.HasArea() )
105 // --> OD 2004-10-20 #i35640# - determine correct page frame
106 SwPageFrm
* pNewPageFrm
= mpAnchoredDrawObj
->GetPageFrm();
109 mpAnchoredDrawObj
->NotifyBackground( pNewPageFrm
, aNewObjRect
,
113 ::ClrContourCache( mpAnchoredDrawObj
->GetDrawObj() );
115 // --> OD 2004-10-20 #i35640# - additional notify anchor text frame
116 // Needed for negative positioned drawing objects
117 // --> OD 2005-03-01 #i43255# - refine condition to avoid unneeded
118 // invalidations: anchored object had to be on the page of its anchor
120 if ( mpAnchoredDrawObj
->GetAnchorFrm()->IsTxtFrm() &&
121 mpOldPageFrm
== mpAnchoredDrawObj
->GetAnchorFrm()->FindPageFrm() )
123 mpAnchoredDrawObj
->AnchorFrm()->Prepare( PREP_FLY_LEAVE
);
127 // indicate a restart of the layout process
128 mpAnchoredDrawObj
->SetRestartLayoutProcess( true );
133 mpAnchoredDrawObj
->LockPosition();
135 if ( !mpAnchoredDrawObj
->ConsiderForTextWrap() )
137 // indicate that object has to be considered for text wrap
138 mpAnchoredDrawObj
->SetConsiderForTextWrap( true );
139 // invalidate 'background' in order to allow its 'background'
140 // to wrap around it.
141 mpAnchoredDrawObj
->NotifyBackground( mpAnchoredDrawObj
->GetPageFrm(),
142 mpAnchoredDrawObj
->GetObjRectWithSpaces(),
144 // invalidate position of anchor frame in order to force
145 // a re-format of the anchor frame, which also causes a
146 // re-format of the invalid previous frames of the anchor frame.
147 mpAnchoredDrawObj
->AnchorFrm()->InvalidatePos();
152 // --> OD 2004-08-12 #i32795#
153 Point
SwPosNotify::LastObjPos() const
155 return maOldObjRect
.Pos();
159 // ============================================================================
160 // OD 2004-08-12 #i32795#
161 // helper class for oscillation control on object positioning
162 // ============================================================================
163 class SwObjPosOscillationControl
166 sal_uInt8 mnPosStackSize
;
168 const SwAnchoredDrawObject
* mpAnchoredDrawObj
;
170 std::vector
<Point
*> maObjPositions
;
173 SwObjPosOscillationControl( const SwAnchoredDrawObject
& _rAnchoredDrawObj
);
174 ~SwObjPosOscillationControl();
176 bool OscillationDetected();
179 SwObjPosOscillationControl::SwObjPosOscillationControl(
180 const SwAnchoredDrawObject
& _rAnchoredDrawObj
)
181 : mnPosStackSize( 20 ),
182 mpAnchoredDrawObj( &_rAnchoredDrawObj
)
186 SwObjPosOscillationControl::~SwObjPosOscillationControl()
188 while ( !maObjPositions
.empty() )
190 Point
* pPos
= maObjPositions
.back();
193 maObjPositions
.pop_back();
197 bool SwObjPosOscillationControl::OscillationDetected()
199 bool bOscillationDetected
= false;
201 if ( maObjPositions
.size() == mnPosStackSize
)
203 // position stack is full -> oscillation
204 bOscillationDetected
= true;
208 Point
* pNewObjPos
= new Point( mpAnchoredDrawObj
->GetObjRect().Pos() );
209 for ( std::vector
<Point
*>::iterator aObjPosIter
= maObjPositions
.begin();
210 aObjPosIter
!= maObjPositions
.end();
213 if ( *(pNewObjPos
) == *(*aObjPosIter
) )
215 // position already occured -> oscillation
216 bOscillationDetected
= true;
221 if ( !bOscillationDetected
)
223 maObjPositions
.push_back( pNewObjPos
);
227 return bOscillationDetected
;
230 // ============================================================================
231 // implementation of class <SwAnchoredDrawObject>
232 // ============================================================================
233 TYPEINIT1(SwAnchoredDrawObject
,SwAnchoredObject
);
235 SwAnchoredDrawObject::SwAnchoredDrawObject() :
238 // --> OD 2004-09-29 #i34748#
241 mbNotYetAttachedToAnchorFrame( true ),
242 // --> OD 2004-08-09 #i28749#
243 mbNotYetPositioned( true ),
245 // --> OD 2006-03-17 #i62875#
246 mbCaptureAfterLayoutDirChange( false )
251 SwAnchoredDrawObject::~SwAnchoredDrawObject()
253 // --> OD 2004-11-03 - follow-up of #i34748#
254 delete mpLastObjRect
;
258 // --> OD 2006-03-17 #i62875#
259 void SwAnchoredDrawObject::UpdateLayoutDir()
261 SwFrmFmt::tLayoutDir
nOldLayoutDir( GetFrmFmt().GetLayoutDir() );
263 SwAnchoredObject::UpdateLayoutDir();
265 if ( !NotYetPositioned() &&
266 GetFrmFmt().GetLayoutDir() != nOldLayoutDir
&&
267 GetFrmFmt().GetDoc()->get(IDocumentSettingAccess::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE
) &&
270 mbCaptureAfterLayoutDirChange
= true;
275 // --> OD 2006-03-17 #i62875#
276 bool SwAnchoredDrawObject::IsOutsidePage() const
278 bool bOutsidePage( false );
280 if ( !NotYetPositioned() && GetPageFrm() )
282 SwRect
aTmpRect( GetObjRect() );
284 ( aTmpRect
.Intersection( GetPageFrm()->Frm() ) != GetObjRect() );
291 // =============================================================================
292 // OD 2004-03-25 #i26791# - implementation of pure virtual method declared in
293 // base class <SwAnchoredObject>
294 // =============================================================================
295 void SwAnchoredDrawObject::MakeObjPos()
297 if ( IsPositioningInProgress() )
299 // nothind to do - positioning already in progress
305 // nothing to do - position is valid
309 // --> OD 2004-08-09 #i28749# - anchored drawing object has to be attached
311 if ( mbNotYetAttachedToAnchorFrame
)
314 "<SwAnchoredDrawObject::MakeObjPos() - drawing object not yet attached to anchor frame -> no positioning" );
318 SwDrawContact
* pDrawContact
=
319 static_cast<SwDrawContact
*>(::GetUserCall( GetDrawObj() ));
321 // --> OD 2004-08-09 #i28749# - if anchored drawing object hasn't been yet
322 // positioned, convert its positioning attributes, if its positioning
323 // attributes are given in horizontal left-to-right layout.
324 // --> OD 2004-10-25 #i36010# - Note: horizontal left-to-right layout is made
325 // the default layout direction for <SwDrawFrmFmt> instances. Thus, it has
326 // to be adjusted manually, if no adjustment of the positioning attributes
327 // have to be performed here.
328 // --> OD 2004-11-17 #i35635# - additionally move drawing object to the
330 if ( mbNotYetPositioned
)
332 // --> OD 2004-11-17 #i35635#
333 pDrawContact
->MoveObjToVisibleLayer( DrawObj() );
335 // --> OD 2004-09-29 #117975# - perform conversion of positioning
336 // attributes only for 'master' drawing objects
337 // --> OD 2005-03-11 #i44334#, #i44681# - check, if positioning
338 // attributes already have been set.
339 if ( !GetDrawObj()->ISA(SwDrawVirtObj
) &&
340 !static_cast<SwDrawFrmFmt
&>(GetFrmFmt()).IsPosAttrSet() )
342 _SetPositioningAttr();
345 // --> OD 2006-05-24 #b6418964#
346 // - reset internal flag after all needed actions are performed to
347 // avoid callbacks from drawing layer
348 mbNotYetPositioned
= false;
353 // indicate that positioning is in progress
355 SwObjPositioningInProgress
aObjPosInProgress( *this );
357 // determine relative position of drawing object and set it
358 switch ( pDrawContact
->GetAnchorId() )
362 // indicate that position will be valid after positioning is performed
364 // nothing to do, because as-character anchored objects are positioned
365 // during the format of its anchor frame - see <SwFlyCntPortion::SetBase(..)>
371 // --> OD 2004-08-12 #i32795# - move intrinsic positioning to
372 // helper method <_MakeObjPosAnchoredAtPara()>
373 _MakeObjPosAnchoredAtPara();
379 // --> OD 2004-08-12 #i32795# - move intrinsic positioning to
380 // helper method <_MakeObjPosAnchoredAtLayout()>
381 _MakeObjPosAnchoredAtLayout();
386 ASSERT( false, "<SwAnchoredDrawObject::MakeObjPos()> - unknown anchor type - please inform OD." );
390 // keep, current object rectangle
391 // --> OD 2004-09-29 #i34748# - use new method <SetLastObjRect(..)>
392 SetLastObjRect( GetObjRect().SVRect() );
395 // Assure for 'master' drawing object, that it's registered at the correct page.
396 // Perform check not for as-character anchored drawing objects and only if
397 // the anchor frame is valid.
398 if ( !GetDrawObj()->ISA(SwDrawVirtObj
) &&
399 !pDrawContact
->ObjAnchoredAsChar() &&
400 GetAnchorFrm()->IsValid() )
402 pDrawContact
->ChkPage();
406 // --> OD 2006-03-17 #i62875#
407 if ( mbCaptureAfterLayoutDirChange
&&
410 SwRect
aPageRect( GetPageFrm()->Frm() );
411 SwRect
aObjRect( GetObjRect() );
412 if ( aObjRect
.Right() >= aPageRect
.Right() + 10 )
414 Size
aSize( aPageRect
.Right() - aObjRect
.Right(), 0 );
415 DrawObj()->Move( aSize
);
416 aObjRect
= GetObjRect();
419 if ( aObjRect
.Left() + 10 <= aPageRect
.Left() )
421 Size
aSize( aPageRect
.Left() - aObjRect
.Left(), 0 );
422 DrawObj()->Move( aSize
);
425 mbCaptureAfterLayoutDirChange
= false;
430 /** method for the intrinsic positioning of a at-paragraph|at-character
431 anchored drawing object
433 OD 2004-08-12 #i32795# - helper method for method <MakeObjPos>
437 void SwAnchoredDrawObject::_MakeObjPosAnchoredAtPara()
439 // --> OD 2004-08-12 #i32795# - adopt positioning algorithm from Writer
440 // fly frames, which are anchored at paragraph|at character
442 // Determine, if anchor frame can/has to be formatted.
443 // If yes, after each object positioning the anchor frame is formatted.
444 // If after the anchor frame format the object position isn't valid, the
445 // object is positioned again.
446 // --> OD 2005-02-22 #i43255# - refine condition: anchor frame format not
447 // allowed, if another anchored object, has to be consider its wrap influence
448 // --> OD 2005-06-07 #i50356# - format anchor frame containing the anchor
449 // position. E.g., for at-character anchored object this can be the follow
450 // frame of the anchor frame, which contains the anchor character.
451 const bool bFormatAnchor
=
452 !static_cast<const SwTxtFrm
*>( GetAnchorFrmContainingAnchPos() )->IsAnyJoinLocked() &&
453 !ConsiderObjWrapInfluenceOnObjPos() &&
454 !ConsiderObjWrapInfluenceOfOtherObjs();
459 // --> OD 2005-06-07 #i50356#
460 GetAnchorFrmContainingAnchPos()->Calc();
464 bool bOscillationDetected
= false;
465 SwObjPosOscillationControl
aObjPosOscCtrl( *this );
466 // --> OD 2004-08-25 #i3317# - boolean, to apply temporarly the
467 // 'straightforward positioning process' for the frame due to its
468 // overlapping with a previous column.
469 bool bConsiderWrapInfluenceDueToOverlapPrevCol( false );
472 // indicate that position will be valid after positioning is performed
475 // --> OD 2004-10-20 #i35640# - correct scope for <SwPosNotify> instance
477 // create instance of <SwPosNotify> for correct notification
478 SwPosNotify
aPosNotify( this );
480 // determine and set position
481 objectpositioning::SwToCntntAnchoredObjectPosition
482 aObjPositioning( *DrawObj() );
483 aObjPositioning
.CalcPosition();
485 // get further needed results of the positioning algorithm
486 SetVertPosOrientFrm ( aObjPositioning
.GetVertPosOrientFrm() );
489 // check for object position oscillation, if position has changed.
490 if ( GetObjRect().Pos() != aPosNotify
.LastObjPos() )
492 bOscillationDetected
= aObjPosOscCtrl
.OscillationDetected();
496 // format anchor frame, if requested.
497 // Note: the format of the anchor frame can cause the object position
501 // --> OD 2005-06-07 #i50356#
502 GetAnchorFrmContainingAnchPos()->Calc();
506 // --> OD 2004-08-25 #i3317#
507 if ( !ConsiderObjWrapInfluenceOnObjPos() &&
508 OverlapsPrevColumn() )
510 bConsiderWrapInfluenceDueToOverlapPrevCol
= true;
513 } while ( !mbValidPos
&& !bOscillationDetected
&&
514 !bConsiderWrapInfluenceDueToOverlapPrevCol
);
516 // --> OD 2004-08-25 #i3317# - consider a detected oscillation and overlapping
517 // with previous column.
518 // temporarly consider the anchored objects wrapping style influence
519 if ( bOscillationDetected
|| bConsiderWrapInfluenceDueToOverlapPrevCol
)
521 SetTmpConsiderWrapInfluence( true );
522 SetRestartLayoutProcess( true );
527 /** method for the intrinsic positioning of a at-page|at-frame anchored
530 OD 2004-08-12 #i32795# - helper method for method <MakeObjPos>
534 void SwAnchoredDrawObject::_MakeObjPosAnchoredAtLayout()
536 // indicate that position will be valid after positioning is performed
539 // create instance of <SwPosNotify> for correct notification
540 SwPosNotify
aPosNotify( this );
542 // determine position
543 objectpositioning::SwToLayoutAnchoredObjectPosition
544 aObjPositioning( *DrawObj() );
545 aObjPositioning
.CalcPosition();
549 // --> OD 2004-07-29 #i31698#
550 // --> OD 2004-10-18 #i34995# - setting anchor position needed for filters,
551 // especially for the xml-filter to the OpenOffice.org file format
553 const Point aNewAnchorPos
=
554 GetAnchorFrm()->GetFrmAnchorPos( ::HasWrap( GetDrawObj() ) );
555 DrawObj()->SetAnchorPos( aNewAnchorPos
);
556 // --> OD 2006-10-05 #i70122# - missing invalidation
557 InvalidateObjRectWithSpaces();
561 SetCurrRelPos( aObjPositioning
.GetRelPos() );
562 const SwFrm
* pAnchorFrm
= GetAnchorFrm();
563 SWRECTFN( pAnchorFrm
);
564 const Point
aAnchPos( (pAnchorFrm
->Frm().*fnRect
->fnGetPos
)() );
565 SetObjLeft( aAnchPos
.X() + GetCurrRelPos().X() );
566 SetObjTop( aAnchPos
.Y() + GetCurrRelPos().Y() );
570 void SwAnchoredDrawObject::_SetDrawObjAnchor()
572 // new anchor position
573 // --> OD 2004-07-29 #i31698# -
574 Point aNewAnchorPos
=
575 GetAnchorFrm()->GetFrmAnchorPos( ::HasWrap( GetDrawObj() ) );
576 Point aCurrAnchorPos
= GetDrawObj()->GetAnchorPos();
577 if ( aNewAnchorPos
!= aCurrAnchorPos
)
579 // determine movement to be applied after setting the new anchor position
580 Size
aMove( aCurrAnchorPos
.X() - aNewAnchorPos
.X(),
581 aCurrAnchorPos
.Y() - aNewAnchorPos
.Y() );
582 // set new anchor position
583 DrawObj()->SetAnchorPos( aNewAnchorPos
);
584 // correct object position, caused by setting new anchor position
585 DrawObj()->Move( aMove
);
586 // --> OD 2006-10-05 #i70122# - missing invalidation
587 InvalidateObjRectWithSpaces();
592 /** method to invalidate the given page frame
594 OD 2004-07-02 #i28701#
598 void SwAnchoredDrawObject::_InvalidatePage( SwPageFrm
* _pPageFrm
)
600 if ( _pPageFrm
&& !_pPageFrm
->GetFmt()->GetDoc()->IsInDtor() )
602 if ( _pPageFrm
->GetUpper() )
604 // --> OD 2004-11-11 #i35007# - correct invalidation for as-character
606 if ( GetFrmFmt().GetAnchor().GetAnchorId() == FLY_IN_CNTNT
)
608 _pPageFrm
->InvalidateFlyInCnt();
612 _pPageFrm
->InvalidateFlyLayout();
616 SwRootFrm
* pRootFrm
= static_cast<SwRootFrm
*>(_pPageFrm
->GetUpper());
617 pRootFrm
->DisallowTurbo();
618 if ( pRootFrm
->GetTurbo() )
620 const SwCntntFrm
* pTmpFrm
= pRootFrm
->GetTurbo();
621 pRootFrm
->ResetTurbo();
622 pTmpFrm
->InvalidatePage();
624 pRootFrm
->SetIdleFlags();
629 void SwAnchoredDrawObject::InvalidateObjPos()
631 // --> OD 2004-07-01 #i28701# - check, if invalidation is allowed
633 InvalidationOfPosAllowed() )
636 // --> OD 2006-08-10 #i68520#
637 InvalidateObjRectWithSpaces();
640 // --> OD 2005-03-08 #i44339# - check, if anchor frame exists.
641 if ( GetAnchorFrm() )
643 // --> OD 2004-11-22 #118547# - notify anchor frame of as-character
644 // anchored object, because its positioned by the format of its anchor frame.
645 // --> OD 2005-03-09 #i44559# - assure, that text hint is already
646 // existing in the text frame
647 if ( GetAnchorFrm()->ISA(SwTxtFrm
) &&
648 GetFrmFmt().GetAnchor().GetAnchorId() == FLY_IN_CNTNT
)
650 SwTxtFrm
* pAnchorTxtFrm( static_cast<SwTxtFrm
*>(AnchorFrm()) );
651 if ( pAnchorTxtFrm
->GetTxtNode()->GetpSwpHints() &&
652 pAnchorTxtFrm
->CalcFlyPos( &GetFrmFmt() ) != STRING_LEN
)
654 AnchorFrm()->Prepare( PREP_FLY_ATTR_CHG
, &GetFrmFmt() );
659 SwPageFrm
* pPageFrm
= AnchorFrm()->FindPageFrm();
660 _InvalidatePage( pPageFrm
);
662 // --> OD 2004-08-12 #i32270# - also invalidate page frame, at which the
663 // drawing object is registered at.
664 SwPageFrm
* pPageFrmRegisteredAt
= GetPageFrm();
665 if ( pPageFrmRegisteredAt
&&
666 pPageFrmRegisteredAt
!= pPageFrm
)
668 _InvalidatePage( pPageFrmRegisteredAt
);
671 // --> OD 2004-09-23 #i33751#, #i34060# - method <GetPageFrmOfAnchor()>
672 // is replaced by method <FindPageFrmOfAnchor()>. It's return value
673 // have to be checked.
674 SwPageFrm
* pPageFrmOfAnchor
= FindPageFrmOfAnchor();
675 if ( pPageFrmOfAnchor
&&
676 pPageFrmOfAnchor
!= pPageFrm
&&
677 pPageFrmOfAnchor
!= pPageFrmRegisteredAt
)
680 _InvalidatePage( pPageFrmOfAnchor
);
687 SwFrmFmt
& SwAnchoredDrawObject::GetFrmFmt()
689 ASSERT( static_cast<SwDrawContact
*>(GetUserCall(GetDrawObj()))->GetFmt(),
690 "<SwAnchoredDrawObject::GetFrmFmt()> - missing frame format -> crash." );
691 return *(static_cast<SwDrawContact
*>(GetUserCall(GetDrawObj()))->GetFmt());
693 const SwFrmFmt
& SwAnchoredDrawObject::GetFrmFmt() const
695 ASSERT( static_cast<SwDrawContact
*>(GetUserCall(GetDrawObj()))->GetFmt(),
696 "<SwAnchoredDrawObject::GetFrmFmt()> - missing frame format -> crash." );
697 return *(static_cast<SwDrawContact
*>(GetUserCall(GetDrawObj()))->GetFmt());
700 const SwRect
SwAnchoredDrawObject::GetObjRect() const
702 // use geometry of drawing object
703 //return GetDrawObj()->GetCurrentBoundRect();
704 return GetDrawObj()->GetSnapRect();
707 // --> OD 2006-10-05 #i70122#
708 const SwRect
SwAnchoredDrawObject::GetObjBoundRect() const
710 return GetDrawObj()->GetCurrentBoundRect();
714 // --> OD 2006-08-10 #i68520#
715 bool SwAnchoredDrawObject::_SetObjTop( const SwTwips _nTop
)
717 SwTwips nDiff
= _nTop
- GetObjRect().Top();
718 DrawObj()->Move( Size( 0, nDiff
) );
722 bool SwAnchoredDrawObject::_SetObjLeft( const SwTwips _nLeft
)
724 SwTwips nDiff
= _nLeft
- GetObjRect().Left();
725 DrawObj()->Move( Size( nDiff
, 0 ) );
731 /** adjust positioning and alignment attributes for new anchor frame
733 OD 2004-08-24 #i33313# - add second optional parameter <_pNewObjRect>
737 void SwAnchoredDrawObject::AdjustPositioningAttr( const SwFrm
* _pNewAnchorFrm
,
738 const SwRect
* _pNewObjRect
)
740 SwTwips nHoriRelPos
= 0;
741 SwTwips nVertRelPos
= 0;
742 const Point aAnchorPos
= _pNewAnchorFrm
->GetFrmAnchorPos( ::HasWrap( GetDrawObj() ) );
743 // --> OD 2004-08-24 #i33313#
744 const SwRect
aObjRect( _pNewObjRect
? *_pNewObjRect
: GetObjRect() );
746 const bool bVert
= _pNewAnchorFrm
->IsVertical();
747 const bool bR2L
= _pNewAnchorFrm
->IsRightToLeft();
750 nHoriRelPos
= aObjRect
.Top() - aAnchorPos
.Y();
751 nVertRelPos
= aAnchorPos
.X() - aObjRect
.Right();
755 nHoriRelPos
= aAnchorPos
.X() - aObjRect
.Right();
756 nVertRelPos
= aObjRect
.Top() - aAnchorPos
.Y();
760 nHoriRelPos
= aObjRect
.Left() - aAnchorPos
.X();
761 nVertRelPos
= aObjRect
.Top() - aAnchorPos
.Y();
764 GetFrmFmt().SetFmtAttr( SwFmtHoriOrient( nHoriRelPos
, text::HoriOrientation::NONE
, text::RelOrientation::FRAME
) );
765 GetFrmFmt().SetFmtAttr( SwFmtVertOrient( nVertRelPos
, text::VertOrientation::NONE
, text::RelOrientation::FRAME
) );
768 // --> OD 2004-09-29 #i34748# - change return type
769 const Rectangle
* SwAnchoredDrawObject::GetLastObjRect() const
771 return mpLastObjRect
;
775 // --> OD 2004-09-29 #i34748# - change return type.
776 // If member <mpLastObjRect> is NULL, create one.
777 void SwAnchoredDrawObject::SetLastObjRect( const Rectangle
& _rNewLastRect
)
779 if ( !mpLastObjRect
)
781 mpLastObjRect
= new Rectangle
;
783 *(mpLastObjRect
) = _rNewLastRect
;
787 void SwAnchoredDrawObject::ObjectAttachedToAnchorFrame()
789 // --> OD 2004-07-27 #i31698#
790 SwAnchoredObject::ObjectAttachedToAnchorFrame();
793 if ( mbNotYetAttachedToAnchorFrame
)
795 mbNotYetAttachedToAnchorFrame
= false;
799 /** method to set positioning attributes
801 OD 2004-10-20 #i35798#
802 During load the positioning attributes aren't set.
803 Thus, the positioning attributes are set by the current object geometry.
804 This method is also used for the conversion for drawing objects
805 (not anchored as-character) imported from OpenOffice.org file format
806 once and directly before the first positioning.
810 void SwAnchoredDrawObject::_SetPositioningAttr()
812 SwDrawContact
* pDrawContact
=
813 static_cast<SwDrawContact
*>(GetUserCall( GetDrawObj() ));
815 if ( !pDrawContact
->ObjAnchoredAsChar() )
817 SwRect
aObjRect( GetObjRect() );
819 SwTwips nHoriPos
= aObjRect
.Left();
820 SwTwips nVertPos
= aObjRect
.Top();
821 // --> OD 2005-03-10 #i44334#, #i44681#
822 // perform conversion only if position is in horizontal-left-to-right-layout.
823 if ( GetFrmFmt().GetPositionLayoutDir() ==
824 text::PositionLayoutDir::PositionInHoriL2R
)
826 SwFrmFmt::tLayoutDir eLayoutDir
= GetFrmFmt().GetLayoutDir();
827 switch ( eLayoutDir
)
829 case SwFrmFmt::HORI_L2R
:
834 case SwFrmFmt::HORI_R2L
:
836 nHoriPos
= -aObjRect
.Left() - aObjRect
.Width();
839 case SwFrmFmt::VERT_R2L
:
841 nHoriPos
= aObjRect
.Top();
842 nVertPos
= -aObjRect
.Left() - aObjRect
.Width();
848 "<SwAnchoredDrawObject::_SetPositioningAttr()> - unsupported layout direction" );
854 // --> OD 2006-11-10 #i71182#
855 // only change position - do not lose other attributes
856 SwFmtHoriOrient
aHori( GetFrmFmt().GetHoriOrient() );
857 aHori
.SetPos( nHoriPos
);
858 GetFrmFmt().SetFmtAttr( aHori
);
860 SwFmtVertOrient
aVert( GetFrmFmt().GetVertOrient() );
861 // --> OD 2007-01-03 #i73079# - vertical position already correct
862 // if ( aVert.GetRelationOrient() == text::RelOrientation::CHAR ||
863 // aVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE )
865 // nVertPos = -nVertPos;
868 aVert
.SetPos( nVertPos
);
869 GetFrmFmt().SetFmtAttr( aVert
);
872 // --> OD 2004-10-25 #i36010# - set layout direction of the position
873 GetFrmFmt().SetPositionLayoutDir(
874 text::PositionLayoutDir::PositionInLayoutDirOfAnchor
);
877 // --> OD 2007-11-29 #i65798# - also for as-character anchored objects
878 // --> OD 2005-05-10 #i45952# - indicate that position
879 // attributes are set now.
880 static_cast<SwDrawFrmFmt
&>(GetFrmFmt()).PosAttrSet();
884 void SwAnchoredDrawObject::NotifyBackground( SwPageFrm
* _pPageFrm
,
885 const SwRect
& _rRect
,
888 ::Notify_Background( GetDrawObj(), _pPageFrm
, _rRect
, _eHint
, TRUE
);
891 /** method to assure that anchored object is registered at the correct
894 OD 2004-07-02 #i28701#
898 void SwAnchoredDrawObject::RegisterAtCorrectPage()
900 SwPageFrm
* pPageFrm( 0L );
901 if ( GetVertPosOrientFrm() )
903 pPageFrm
= const_cast<SwPageFrm
*>(GetVertPosOrientFrm()->FindPageFrm());
905 if ( pPageFrm
&& GetPageFrm() != pPageFrm
)
908 GetPageFrm()->RemoveDrawObjFromPage( *this );
909 pPageFrm
->AppendDrawObjToPage( *this );
913 // =============================================================================