update dev300-m58
[ooovba.git] / sw / source / core / layout / anchoreddrawobject.cxx
blobe2376f3d8ee1bab5032d7f87390fb261d55c5e45
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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>
38 #include <cntfrm.hxx>
39 #include <doc.hxx>
40 #ifndef _TOCNTNTANCHOROBJECTPOSITION_HXX
41 #include <tocntntanchoredobjectposition.hxx>
42 #endif
43 #ifndef _TOLAYOUTANCHOROBJECTPOSITION_HXX
44 #include <tolayoutanchoredobjectposition.hxx>
45 #endif
46 #include <frmtool.hxx>
47 #include <fmtornt.hxx>
48 // --> OD 2004-08-12 #i32795#
49 #include <txtfrm.hxx>
50 // <--
51 // --> OD 2004-08-12 #i32795#
52 // template class <std::vector>
53 #include <vector>
54 // <--
56 // --> OD 2004-08-10 #i28749#
57 #include <com/sun/star/text/PositionLayoutDir.hpp>
58 // <--
59 // --> OD 2005-03-09 #i44559#
60 #include <ndtxt.hxx>
61 // <--
63 using namespace ::com::sun::star;
65 // ============================================================================
66 // helper class for correct notification due to the positioning of
67 // the anchored drawing object
68 // ============================================================================
69 class SwPosNotify
71 private:
72 SwAnchoredDrawObject* mpAnchoredDrawObj;
73 SwRect maOldObjRect;
74 SwPageFrm* mpOldPageFrm;
76 public:
77 SwPosNotify( SwAnchoredDrawObject* _pAnchoredDrawObj );
78 ~SwPosNotify();
79 // --> OD 2004-08-12 #i32795#
80 Point LastObjPos() const;
81 // <--
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();
90 // <--
93 SwPosNotify::~SwPosNotify()
95 if ( maOldObjRect != mpAnchoredDrawObj->GetObjRect() )
97 if( maOldObjRect.HasArea() && mpOldPageFrm )
99 mpAnchoredDrawObj->NotifyBackground( mpOldPageFrm, maOldObjRect,
100 PREP_FLY_LEAVE );
102 SwRect aNewObjRect( mpAnchoredDrawObj->GetObjRect() );
103 if( aNewObjRect.HasArea() )
105 // --> OD 2004-10-20 #i35640# - determine correct page frame
106 SwPageFrm* pNewPageFrm = mpAnchoredDrawObj->GetPageFrm();
107 // <--
108 if( pNewPageFrm )
109 mpAnchoredDrawObj->NotifyBackground( pNewPageFrm, aNewObjRect,
110 PREP_FLY_ARRIVE );
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
119 // text frame.
120 if ( mpAnchoredDrawObj->GetAnchorFrm()->IsTxtFrm() &&
121 mpOldPageFrm == mpAnchoredDrawObj->GetAnchorFrm()->FindPageFrm() )
123 mpAnchoredDrawObj->AnchorFrm()->Prepare( PREP_FLY_LEAVE );
125 // <--
127 // indicate a restart of the layout process
128 mpAnchoredDrawObj->SetRestartLayoutProcess( true );
130 else
132 // lock position
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(),
143 PREP_FLY_ARRIVE );
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();
157 //<--
159 // ============================================================================
160 // OD 2004-08-12 #i32795#
161 // helper class for oscillation control on object positioning
162 // ============================================================================
163 class SwObjPosOscillationControl
165 private:
166 sal_uInt8 mnPosStackSize;
168 const SwAnchoredDrawObject* mpAnchoredDrawObj;
170 std::vector<Point*> maObjPositions;
172 public:
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();
191 delete pPos;
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;
206 else
208 Point* pNewObjPos = new Point( mpAnchoredDrawObj->GetObjRect().Pos() );
209 for ( std::vector<Point*>::iterator aObjPosIter = maObjPositions.begin();
210 aObjPosIter != maObjPositions.end();
211 ++aObjPosIter )
213 if ( *(pNewObjPos) == *(*aObjPosIter) )
215 // position already occured -> oscillation
216 bOscillationDetected = true;
217 delete pNewObjPos;
218 break;
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() :
236 SwAnchoredObject(),
237 mbValidPos( false ),
238 // --> OD 2004-09-29 #i34748#
239 mpLastObjRect( 0L ),
240 // <--
241 mbNotYetAttachedToAnchorFrame( true ),
242 // --> OD 2004-08-09 #i28749#
243 mbNotYetPositioned( true ),
244 // <--
245 // --> OD 2006-03-17 #i62875#
246 mbCaptureAfterLayoutDirChange( false )
247 // <--
251 SwAnchoredDrawObject::~SwAnchoredDrawObject()
253 // --> OD 2004-11-03 - follow-up of #i34748#
254 delete mpLastObjRect;
255 // <--
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) &&
268 !IsOutsidePage() )
270 mbCaptureAfterLayoutDirChange = true;
273 // <--
275 // --> OD 2006-03-17 #i62875#
276 bool SwAnchoredDrawObject::IsOutsidePage() const
278 bool bOutsidePage( false );
280 if ( !NotYetPositioned() && GetPageFrm() )
282 SwRect aTmpRect( GetObjRect() );
283 bOutsidePage =
284 ( aTmpRect.Intersection( GetPageFrm()->Frm() ) != GetObjRect() );
287 return bOutsidePage;
289 // <--
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
300 return;
303 if ( mbValidPos )
305 // nothing to do - position is valid
306 return;
309 // --> OD 2004-08-09 #i28749# - anchored drawing object has to be attached
310 // to anchor frame
311 if ( mbNotYetAttachedToAnchorFrame )
313 ASSERT( false,
314 "<SwAnchoredDrawObject::MakeObjPos() - drawing object not yet attached to anchor frame -> no positioning" );
315 return;
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
329 // visible layer.
330 if ( mbNotYetPositioned )
332 // --> OD 2004-11-17 #i35635#
333 pDrawContact->MoveObjToVisibleLayer( DrawObj() );
334 // <--
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();
344 // <--
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;
349 // <--
351 // <--
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() )
360 case FLY_IN_CNTNT:
362 // indicate that position will be valid after positioning is performed
363 mbValidPos = true;
364 // nothing to do, because as-character anchored objects are positioned
365 // during the format of its anchor frame - see <SwFlyCntPortion::SetBase(..)>
367 break;
368 case FLY_AT_CNTNT:
369 case FLY_AUTO_CNTNT:
371 // --> OD 2004-08-12 #i32795# - move intrinsic positioning to
372 // helper method <_MakeObjPosAnchoredAtPara()>
373 _MakeObjPosAnchoredAtPara();
375 break;
376 case FLY_PAGE:
377 case FLY_AT_FLY:
379 // --> OD 2004-08-12 #i32795# - move intrinsic positioning to
380 // helper method <_MakeObjPosAnchoredAtLayout()>
381 _MakeObjPosAnchoredAtLayout();
383 break;
384 default:
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() );
393 // <--
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 &&
408 GetPageFrm() )
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;
427 // <--
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>
435 @author OD
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();
455 // <--
457 if ( bFormatAnchor )
459 // --> OD 2005-06-07 #i50356#
460 GetAnchorFrmContainingAnchPos()->Calc();
461 // <--
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 );
470 // <--
471 do {
472 // indicate that position will be valid after positioning is performed
473 mbValidPos = true;
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() );
487 _SetDrawObjAnchor();
489 // check for object position oscillation, if position has changed.
490 if ( GetObjRect().Pos() != aPosNotify.LastObjPos() )
492 bOscillationDetected = aObjPosOscCtrl.OscillationDetected();
495 // <--
496 // format anchor frame, if requested.
497 // Note: the format of the anchor frame can cause the object position
498 // to be invalid.
499 if ( bFormatAnchor )
501 // --> OD 2005-06-07 #i50356#
502 GetAnchorFrmContainingAnchPos()->Calc();
503 // <--
506 // --> OD 2004-08-25 #i3317#
507 if ( !ConsiderObjWrapInfluenceOnObjPos() &&
508 OverlapsPrevColumn() )
510 bConsiderWrapInfluenceDueToOverlapPrevCol = true;
512 // <--
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 );
524 // <--
527 /** method for the intrinsic positioning of a at-page|at-frame anchored
528 drawing object
530 OD 2004-08-12 #i32795# - helper method for method <MakeObjPos>
532 @author OD
534 void SwAnchoredDrawObject::_MakeObjPosAnchoredAtLayout()
536 // indicate that position will be valid after positioning is performed
537 mbValidPos = true;
539 // create instance of <SwPosNotify> for correct notification
540 SwPosNotify aPosNotify( this );
542 // determine position
543 objectpositioning::SwToLayoutAnchoredObjectPosition
544 aObjPositioning( *DrawObj() );
545 aObjPositioning.CalcPosition();
547 // set position
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();
558 // <--
560 // <--
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() );
567 // <--
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();
588 // <--
592 /** method to invalidate the given page frame
594 OD 2004-07-02 #i28701#
596 @author OD
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
605 // anchored objects.
606 if ( GetFrmFmt().GetAnchor().GetAnchorId() == FLY_IN_CNTNT )
608 _pPageFrm->InvalidateFlyInCnt();
610 else
612 _pPageFrm->InvalidateFlyLayout();
614 // <--
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
632 if ( mbValidPos &&
633 InvalidationOfPosAllowed() )
635 mbValidPos = false;
636 // --> OD 2006-08-10 #i68520#
637 InvalidateObjRectWithSpaces();
638 // <--
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() );
657 // <--
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 );
670 // <--
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 )
678 // <--
680 _InvalidatePage( pPageFrmOfAnchor );
683 // <--
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();
712 // <--
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 ) );
720 return nDiff != 0;
722 bool SwAnchoredDrawObject::_SetObjLeft( const SwTwips _nLeft )
724 SwTwips nDiff = _nLeft - GetObjRect().Left();
725 DrawObj()->Move( Size( nDiff, 0 ) );
727 return nDiff != 0;
729 // <--
731 /** adjust positioning and alignment attributes for new anchor frame
733 OD 2004-08-24 #i33313# - add second optional parameter <_pNewObjRect>
735 @author OD
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() );
745 // <--
746 const bool bVert = _pNewAnchorFrm->IsVertical();
747 const bool bR2L = _pNewAnchorFrm->IsRightToLeft();
748 if ( bVert )
750 nHoriRelPos = aObjRect.Top() - aAnchorPos.Y();
751 nVertRelPos = aAnchorPos.X() - aObjRect.Right();
753 else if ( bR2L )
755 nHoriRelPos = aAnchorPos.X() - aObjRect.Right();
756 nVertRelPos = aObjRect.Top() - aAnchorPos.Y();
758 else
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;
773 // <--
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;
785 // <--
787 void SwAnchoredDrawObject::ObjectAttachedToAnchorFrame()
789 // --> OD 2004-07-27 #i31698#
790 SwAnchoredObject::ObjectAttachedToAnchorFrame();
791 // <--
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.
808 @author OD
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:
831 // nothing to do
833 break;
834 case SwFrmFmt::HORI_R2L:
836 nHoriPos = -aObjRect.Left() - aObjRect.Width();
838 break;
839 case SwFrmFmt::VERT_R2L:
841 nHoriPos = aObjRect.Top();
842 nVertPos = -aObjRect.Left() - aObjRect.Width();
844 break;
845 default:
847 ASSERT( false,
848 "<SwAnchoredDrawObject::_SetPositioningAttr()> - unsupported layout direction" );
852 // <--
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 )
864 // {
865 // nVertPos = -nVertPos;
866 // }
867 // <--
868 aVert.SetPos( nVertPos );
869 GetFrmFmt().SetFmtAttr( aVert );
870 // <--
872 // --> OD 2004-10-25 #i36010# - set layout direction of the position
873 GetFrmFmt().SetPositionLayoutDir(
874 text::PositionLayoutDir::PositionInLayoutDirOfAnchor );
875 // <--
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();
881 // <--
884 void SwAnchoredDrawObject::NotifyBackground( SwPageFrm* _pPageFrm,
885 const SwRect& _rRect,
886 PrepareHint _eHint )
888 ::Notify_Background( GetDrawObj(), _pPageFrm, _rRect, _eHint, TRUE );
891 /** method to assure that anchored object is registered at the correct
892 page frame
894 OD 2004-07-02 #i28701#
896 @author OD
898 void SwAnchoredDrawObject::RegisterAtCorrectPage()
900 SwPageFrm* pPageFrm( 0L );
901 if ( GetVertPosOrientFrm() )
903 pPageFrm = const_cast<SwPageFrm*>(GetVertPosOrientFrm()->FindPageFrm());
905 if ( pPageFrm && GetPageFrm() != pPageFrm )
907 if ( GetPageFrm() )
908 GetPageFrm()->RemoveDrawObjFromPage( *this );
909 pPageFrm->AppendDrawObjToPage( *this );
913 // =============================================================================