summaryrefslogtreecommitdiff
path: root/sw/source/core/layout/anchoreddrawobject.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/layout/anchoreddrawobject.cxx')
-rw-r--r--sw/source/core/layout/anchoreddrawobject.cxx900
1 files changed, 900 insertions, 0 deletions
diff --git a/sw/source/core/layout/anchoreddrawobject.cxx b/sw/source/core/layout/anchoreddrawobject.cxx
new file mode 100644
index 000000000000..c00f394c9a83
--- /dev/null
+++ b/sw/source/core/layout/anchoreddrawobject.cxx
@@ -0,0 +1,900 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sw.hxx"
+#include <anchoreddrawobject.hxx>
+#include <svx/svdobj.hxx>
+#include <dcontact.hxx>
+#include <rootfrm.hxx>
+#include <pagefrm.hxx>
+#include <cntfrm.hxx>
+#include <doc.hxx>
+#include <tocntntanchoredobjectposition.hxx>
+#include <tolayoutanchoredobjectposition.hxx>
+#include <frmtool.hxx>
+#include <fmtornt.hxx>
+// --> #i32795#
+#include <txtfrm.hxx>
+// <--
+// --> #i32795#
+// template class <std::vector>
+#include <vector>
+// <--
+
+// --> #i28749#
+#include <com/sun/star/text/PositionLayoutDir.hpp>
+// <--
+// --> #i44559#
+#include <ndtxt.hxx>
+// <--
+
+using namespace ::com::sun::star;
+
+// ============================================================================
+// helper class for correct notification due to the positioning of
+// the anchored drawing object
+// ============================================================================
+class SwPosNotify
+{
+ private:
+ SwAnchoredDrawObject* mpAnchoredDrawObj;
+ SwRect maOldObjRect;
+ SwPageFrm* mpOldPageFrm;
+
+ public:
+ SwPosNotify( SwAnchoredDrawObject* _pAnchoredDrawObj );
+ ~SwPosNotify();
+ // --> OD 2004-08-12 #i32795#
+ Point LastObjPos() const;
+ // <--
+};
+
+SwPosNotify::SwPosNotify( SwAnchoredDrawObject* _pAnchoredDrawObj ) :
+ mpAnchoredDrawObj( _pAnchoredDrawObj )
+{
+ maOldObjRect = mpAnchoredDrawObj->GetObjRect();
+ // --> #i35640# - determine correct page frame
+ mpOldPageFrm = mpAnchoredDrawObj->GetPageFrm();
+ // <--
+}
+
+SwPosNotify::~SwPosNotify()
+{
+ if ( maOldObjRect != mpAnchoredDrawObj->GetObjRect() )
+ {
+ if( maOldObjRect.HasArea() && mpOldPageFrm )
+ {
+ mpAnchoredDrawObj->NotifyBackground( mpOldPageFrm, maOldObjRect,
+ PREP_FLY_LEAVE );
+ }
+ SwRect aNewObjRect( mpAnchoredDrawObj->GetObjRect() );
+ if( aNewObjRect.HasArea() )
+ {
+ // --> #i35640# - determine correct page frame
+ SwPageFrm* pNewPageFrm = mpAnchoredDrawObj->GetPageFrm();
+ // <--
+ if( pNewPageFrm )
+ mpAnchoredDrawObj->NotifyBackground( pNewPageFrm, aNewObjRect,
+ PREP_FLY_ARRIVE );
+ }
+
+ ::ClrContourCache( mpAnchoredDrawObj->GetDrawObj() );
+
+ // --> #i35640# - additional notify anchor text frame
+ // Needed for negative positioned drawing objects
+ // --> #i43255# - refine condition to avoid unneeded
+ // invalidations: anchored object had to be on the page of its anchor
+ // text frame.
+ if ( mpAnchoredDrawObj->GetAnchorFrm()->IsTxtFrm() &&
+ mpOldPageFrm == mpAnchoredDrawObj->GetAnchorFrm()->FindPageFrm() )
+ {
+ mpAnchoredDrawObj->AnchorFrm()->Prepare( PREP_FLY_LEAVE );
+ }
+ // <--
+
+ // indicate a restart of the layout process
+ mpAnchoredDrawObj->SetRestartLayoutProcess( true );
+ }
+ else
+ {
+ // lock position
+ mpAnchoredDrawObj->LockPosition();
+
+ if ( !mpAnchoredDrawObj->ConsiderForTextWrap() )
+ {
+ // indicate that object has to be considered for text wrap
+ mpAnchoredDrawObj->SetConsiderForTextWrap( true );
+ // invalidate 'background' in order to allow its 'background'
+ // to wrap around it.
+ mpAnchoredDrawObj->NotifyBackground( mpAnchoredDrawObj->GetPageFrm(),
+ mpAnchoredDrawObj->GetObjRectWithSpaces(),
+ PREP_FLY_ARRIVE );
+ // invalidate position of anchor frame in order to force
+ // a re-format of the anchor frame, which also causes a
+ // re-format of the invalid previous frames of the anchor frame.
+ mpAnchoredDrawObj->AnchorFrm()->InvalidatePos();
+ }
+ }
+}
+
+// --> #i32795#
+Point SwPosNotify::LastObjPos() const
+{
+ return maOldObjRect.Pos();
+}
+//<--
+
+// ============================================================================
+// #i32795#
+// helper class for oscillation control on object positioning
+// ============================================================================
+class SwObjPosOscillationControl
+{
+ private:
+ sal_uInt8 mnPosStackSize;
+
+ const SwAnchoredDrawObject* mpAnchoredDrawObj;
+
+ std::vector<Point*> maObjPositions;
+
+ public:
+ SwObjPosOscillationControl( const SwAnchoredDrawObject& _rAnchoredDrawObj );
+ ~SwObjPosOscillationControl();
+
+ bool OscillationDetected();
+};
+
+SwObjPosOscillationControl::SwObjPosOscillationControl(
+ const SwAnchoredDrawObject& _rAnchoredDrawObj )
+ : mnPosStackSize( 20 ),
+ mpAnchoredDrawObj( &_rAnchoredDrawObj )
+{
+}
+
+SwObjPosOscillationControl::~SwObjPosOscillationControl()
+{
+ while ( !maObjPositions.empty() )
+ {
+ Point* pPos = maObjPositions.back();
+ delete pPos;
+
+ maObjPositions.pop_back();
+ }
+}
+
+bool SwObjPosOscillationControl::OscillationDetected()
+{
+ bool bOscillationDetected = false;
+
+ if ( maObjPositions.size() == mnPosStackSize )
+ {
+ // position stack is full -> oscillation
+ bOscillationDetected = true;
+ }
+ else
+ {
+ Point* pNewObjPos = new Point( mpAnchoredDrawObj->GetObjRect().Pos() );
+ for ( std::vector<Point*>::iterator aObjPosIter = maObjPositions.begin();
+ aObjPosIter != maObjPositions.end();
+ ++aObjPosIter )
+ {
+ if ( *(pNewObjPos) == *(*aObjPosIter) )
+ {
+ // position already occurred -> oscillation
+ bOscillationDetected = true;
+ delete pNewObjPos;
+ break;
+ }
+ }
+ if ( !bOscillationDetected )
+ {
+ maObjPositions.push_back( pNewObjPos );
+ }
+ }
+
+ return bOscillationDetected;
+}
+
+// ============================================================================
+// implementation of class <SwAnchoredDrawObject>
+// ============================================================================
+TYPEINIT1(SwAnchoredDrawObject,SwAnchoredObject);
+
+SwAnchoredDrawObject::SwAnchoredDrawObject() :
+ SwAnchoredObject(),
+ mbValidPos( false ),
+ // --> #i34748#
+ mpLastObjRect( 0L ),
+ // <--
+ mbNotYetAttachedToAnchorFrame( true ),
+ // --> #i28749#
+ mbNotYetPositioned( true ),
+ // <--
+ // --> #i62875#
+ mbCaptureAfterLayoutDirChange( false )
+ // <--
+{
+}
+
+SwAnchoredDrawObject::~SwAnchoredDrawObject()
+{
+ // --> follow-up of #i34748#
+ delete mpLastObjRect;
+ // <--
+}
+
+// --> #i62875#
+void SwAnchoredDrawObject::UpdateLayoutDir()
+{
+ SwFrmFmt::tLayoutDir nOldLayoutDir( GetFrmFmt().GetLayoutDir() );
+
+ SwAnchoredObject::UpdateLayoutDir();
+
+ if ( !NotYetPositioned() &&
+ GetFrmFmt().GetLayoutDir() != nOldLayoutDir &&
+ GetFrmFmt().GetDoc()->get(IDocumentSettingAccess::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE) &&
+ !IsOutsidePage() )
+ {
+ mbCaptureAfterLayoutDirChange = true;
+ }
+}
+// <--
+
+// --> #i62875#
+bool SwAnchoredDrawObject::IsOutsidePage() const
+{
+ bool bOutsidePage( false );
+
+ if ( !NotYetPositioned() && GetPageFrm() )
+ {
+ SwRect aTmpRect( GetObjRect() );
+ bOutsidePage =
+ ( aTmpRect.Intersection( GetPageFrm()->Frm() ) != GetObjRect() );
+ }
+
+ return bOutsidePage;
+}
+// <--
+
+// =============================================================================
+// #i26791# - implementation of pure virtual method declared in
+// base class <SwAnchoredObject>
+// =============================================================================
+void SwAnchoredDrawObject::MakeObjPos()
+{
+ if ( IsPositioningInProgress() )
+ {
+ // nothind to do - positioning already in progress
+ return;
+ }
+
+ if ( mbValidPos )
+ {
+ // nothing to do - position is valid
+ return;
+ }
+
+ // --> #i28749# - anchored drawing object has to be attached
+ // to anchor frame
+ if ( mbNotYetAttachedToAnchorFrame )
+ {
+ OSL_FAIL( "<SwAnchoredDrawObject::MakeObjPos() - drawing object not yet attached to anchor frame -> no positioning" );
+ return;
+ }
+
+ SwDrawContact* pDrawContact =
+ static_cast<SwDrawContact*>(::GetUserCall( GetDrawObj() ));
+
+ // --> #i28749# - if anchored drawing object hasn't been yet
+ // positioned, convert its positioning attributes, if its positioning
+ // attributes are given in horizontal left-to-right layout.
+ // --> #i36010# - Note: horizontal left-to-right layout is made
+ // the default layout direction for <SwDrawFrmFmt> instances. Thus, it has
+ // to be adjusted manually, if no adjustment of the positioning attributes
+ // have to be performed here.
+ // --> #i35635# - additionally move drawing object to the visible layer.
+ if ( mbNotYetPositioned )
+ {
+ // --> #i35635#
+ pDrawContact->MoveObjToVisibleLayer( DrawObj() );
+ // <--
+ // --> perform conversion of positioning
+ // attributes only for 'master' drawing objects
+ // --> #i44334#, #i44681# - check, if positioning
+ // attributes already have been set.
+ if ( !GetDrawObj()->ISA(SwDrawVirtObj) &&
+ !static_cast<SwDrawFrmFmt&>(GetFrmFmt()).IsPosAttrSet() )
+ {
+ _SetPositioningAttr();
+ }
+ // <--
+ // -->
+ // - reset internal flag after all needed actions are performed to
+ // avoid callbacks from drawing layer
+ mbNotYetPositioned = false;
+ // <--
+ }
+ // <--
+
+ // indicate that positioning is in progress
+ {
+ SwObjPositioningInProgress aObjPosInProgress( *this );
+
+ // determine relative position of drawing object and set it
+ switch ( pDrawContact->GetAnchorId() )
+ {
+ case FLY_AS_CHAR:
+ {
+ // indicate that position will be valid after positioning is performed
+ mbValidPos = true;
+ // nothing to do, because as-character anchored objects are positioned
+ // during the format of its anchor frame - see <SwFlyCntPortion::SetBase(..)>
+ }
+ break;
+ case FLY_AT_PARA:
+ case FLY_AT_CHAR:
+ {
+ // --> #i32795# - move intrinsic positioning to
+ // helper method <_MakeObjPosAnchoredAtPara()>
+ _MakeObjPosAnchoredAtPara();
+ }
+ break;
+ case FLY_AT_PAGE:
+ case FLY_AT_FLY:
+ {
+ // --> #i32795# - move intrinsic positioning to
+ // helper method <_MakeObjPosAnchoredAtLayout()>
+ _MakeObjPosAnchoredAtLayout();
+ }
+ break;
+ default:
+ {
+ OSL_FAIL( "<SwAnchoredDrawObject::MakeObjPos()> - unknown anchor type - please inform OD." );
+ }
+ }
+
+ // keep, current object rectangle
+ // --> #i34748# - use new method <SetLastObjRect(..)>
+ SetLastObjRect( GetObjRect().SVRect() );
+ // <--
+
+ // Assure for 'master' drawing object, that it's registered at the correct page.
+ // Perform check not for as-character anchored drawing objects and only if
+ // the anchor frame is valid.
+ if ( !GetDrawObj()->ISA(SwDrawVirtObj) &&
+ !pDrawContact->ObjAnchoredAsChar() &&
+ GetAnchorFrm()->IsValid() )
+ {
+ pDrawContact->ChkPage();
+ }
+ }
+
+ // --> #i62875#
+ if ( mbCaptureAfterLayoutDirChange &&
+ GetPageFrm() )
+ {
+ SwRect aPageRect( GetPageFrm()->Frm() );
+ SwRect aObjRect( GetObjRect() );
+ if ( aObjRect.Right() >= aPageRect.Right() + 10 )
+ {
+ Size aSize( aPageRect.Right() - aObjRect.Right(), 0 );
+ DrawObj()->Move( aSize );
+ aObjRect = GetObjRect();
+ }
+
+ if ( aObjRect.Left() + 10 <= aPageRect.Left() )
+ {
+ Size aSize( aPageRect.Left() - aObjRect.Left(), 0 );
+ DrawObj()->Move( aSize );
+ }
+
+ mbCaptureAfterLayoutDirChange = false;
+ }
+ // <--
+}
+
+/** method for the intrinsic positioning of a at-paragraph|at-character
+ anchored drawing object
+
+ #i32795# - helper method for method <MakeObjPos>
+
+ @author OD
+*/
+void SwAnchoredDrawObject::_MakeObjPosAnchoredAtPara()
+{
+ // --> #i32795# - adopt positioning algorithm from Writer
+ // fly frames, which are anchored at paragraph|at character
+
+ // Determine, if anchor frame can/has to be formatted.
+ // If yes, after each object positioning the anchor frame is formatted.
+ // If after the anchor frame format the object position isn't valid, the
+ // object is positioned again.
+ // --> #i43255# - refine condition: anchor frame format not
+ // allowed, if another anchored object, has to be consider its wrap influence
+ // --> #i50356# - format anchor frame containing the anchor
+ // position. E.g., for at-character anchored object this can be the follow
+ // frame of the anchor frame, which contains the anchor character.
+ const bool bFormatAnchor =
+ !static_cast<const SwTxtFrm*>( GetAnchorFrmContainingAnchPos() )->IsAnyJoinLocked() &&
+ !ConsiderObjWrapInfluenceOnObjPos() &&
+ !ConsiderObjWrapInfluenceOfOtherObjs();
+ // <--
+
+ if ( bFormatAnchor )
+ {
+ // --> #i50356#
+ GetAnchorFrmContainingAnchPos()->Calc();
+ // <--
+ }
+
+ bool bOscillationDetected = false;
+ SwObjPosOscillationControl aObjPosOscCtrl( *this );
+ // --> #i3317# - boolean, to apply temporarly the
+ // 'straightforward positioning process' for the frame due to its
+ // overlapping with a previous column.
+ bool bConsiderWrapInfluenceDueToOverlapPrevCol( false );
+ // <--
+ do {
+ // indicate that position will be valid after positioning is performed
+ mbValidPos = true;
+
+ // --> #i35640# - correct scope for <SwPosNotify> instance
+ {
+ // create instance of <SwPosNotify> for correct notification
+ SwPosNotify aPosNotify( this );
+
+ // determine and set position
+ objectpositioning::SwToCntntAnchoredObjectPosition
+ aObjPositioning( *DrawObj() );
+ aObjPositioning.CalcPosition();
+
+ // get further needed results of the positioning algorithm
+ SetVertPosOrientFrm ( aObjPositioning.GetVertPosOrientFrm() );
+ _SetDrawObjAnchor();
+
+ // check for object position oscillation, if position has changed.
+ if ( GetObjRect().Pos() != aPosNotify.LastObjPos() )
+ {
+ bOscillationDetected = aObjPosOscCtrl.OscillationDetected();
+ }
+ }
+ // <--
+ // format anchor frame, if requested.
+ // Note: the format of the anchor frame can cause the object position
+ // to be invalid.
+ if ( bFormatAnchor )
+ {
+ // --> #i50356#
+ GetAnchorFrmContainingAnchPos()->Calc();
+ // <--
+ }
+
+ // --> #i3317#
+ if ( !ConsiderObjWrapInfluenceOnObjPos() &&
+ OverlapsPrevColumn() )
+ {
+ bConsiderWrapInfluenceDueToOverlapPrevCol = true;
+ }
+ // <--
+ } while ( !mbValidPos && !bOscillationDetected &&
+ !bConsiderWrapInfluenceDueToOverlapPrevCol );
+
+ // --> #i3317# - consider a detected oscillation and overlapping
+ // with previous column.
+ // temporarly consider the anchored objects wrapping style influence
+ if ( bOscillationDetected || bConsiderWrapInfluenceDueToOverlapPrevCol )
+ {
+ SetTmpConsiderWrapInfluence( true );
+ SetRestartLayoutProcess( true );
+ }
+ // <--
+}
+
+/** method for the intrinsic positioning of a at-page|at-frame anchored
+ drawing object
+
+ #i32795# - helper method for method <MakeObjPos>
+
+ @author OD
+*/
+void SwAnchoredDrawObject::_MakeObjPosAnchoredAtLayout()
+{
+ // indicate that position will be valid after positioning is performed
+ mbValidPos = true;
+
+ // create instance of <SwPosNotify> for correct notification
+ SwPosNotify aPosNotify( this );
+
+ // determine position
+ objectpositioning::SwToLayoutAnchoredObjectPosition
+ aObjPositioning( *DrawObj() );
+ aObjPositioning.CalcPosition();
+
+ // set position
+
+ // --> #i31698#
+ // --> #i34995# - setting anchor position needed for filters,
+ // especially for the xml-filter to the OpenOffice.org file format
+ {
+ const Point aNewAnchorPos =
+ GetAnchorFrm()->GetFrmAnchorPos( ::HasWrap( GetDrawObj() ) );
+ DrawObj()->SetAnchorPos( aNewAnchorPos );
+ // --> #i70122# - missing invalidation
+ InvalidateObjRectWithSpaces();
+ // <--
+ }
+ // <--
+ SetCurrRelPos( aObjPositioning.GetRelPos() );
+ const SwFrm* pAnchorFrm = GetAnchorFrm();
+ SWRECTFN( pAnchorFrm );
+ const Point aAnchPos( (pAnchorFrm->Frm().*fnRect->fnGetPos)() );
+ SetObjLeft( aAnchPos.X() + GetCurrRelPos().X() );
+ SetObjTop( aAnchPos.Y() + GetCurrRelPos().Y() );
+ // <--
+}
+
+void SwAnchoredDrawObject::_SetDrawObjAnchor()
+{
+ // new anchor position
+ // --> #i31698# -
+ Point aNewAnchorPos =
+ GetAnchorFrm()->GetFrmAnchorPos( ::HasWrap( GetDrawObj() ) );
+ Point aCurrAnchorPos = GetDrawObj()->GetAnchorPos();
+ if ( aNewAnchorPos != aCurrAnchorPos )
+ {
+ // determine movement to be applied after setting the new anchor position
+ Size aMove( aCurrAnchorPos.X() - aNewAnchorPos.X(),
+ aCurrAnchorPos.Y() - aNewAnchorPos.Y() );
+ // set new anchor position
+ DrawObj()->SetAnchorPos( aNewAnchorPos );
+ // correct object position, caused by setting new anchor position
+ DrawObj()->Move( aMove );
+ // --> #i70122# - missing invalidation
+ InvalidateObjRectWithSpaces();
+ // <--
+ }
+}
+
+/** method to invalidate the given page frame
+
+ #i28701#
+
+ @author OD
+*/
+void SwAnchoredDrawObject::_InvalidatePage( SwPageFrm* _pPageFrm )
+{
+ if ( _pPageFrm && !_pPageFrm->GetFmt()->GetDoc()->IsInDtor() )
+ {
+ if ( _pPageFrm->GetUpper() )
+ {
+ // --> #i35007# - correct invalidation for as-character
+ // anchored objects.
+ if ( GetFrmFmt().GetAnchor().GetAnchorId() == FLY_AS_CHAR )
+ {
+ _pPageFrm->InvalidateFlyInCnt();
+ }
+ else
+ {
+ _pPageFrm->InvalidateFlyLayout();
+ }
+ // <--
+
+ SwRootFrm* pRootFrm = static_cast<SwRootFrm*>(_pPageFrm->GetUpper());
+ pRootFrm->DisallowTurbo();
+ if ( pRootFrm->GetTurbo() )
+ {
+ const SwCntntFrm* pTmpFrm = pRootFrm->GetTurbo();
+ pRootFrm->ResetTurbo();
+ pTmpFrm->InvalidatePage();
+ }
+ pRootFrm->SetIdleFlags();
+ }
+ }
+}
+
+void SwAnchoredDrawObject::InvalidateObjPos()
+{
+ // --> #i28701# - check, if invalidation is allowed
+ if ( mbValidPos &&
+ InvalidationOfPosAllowed() )
+ {
+ mbValidPos = false;
+ // --> #i68520#
+ InvalidateObjRectWithSpaces();
+ // <--
+
+ // --> #i44339# - check, if anchor frame exists.
+ if ( GetAnchorFrm() )
+ {
+ // --> #118547# - notify anchor frame of as-character
+ // anchored object, because its positioned by the format of its anchor frame.
+ // --> #i44559# - assure, that text hint is already
+ // existing in the text frame
+ if ( GetAnchorFrm()->ISA(SwTxtFrm) &&
+ (GetFrmFmt().GetAnchor().GetAnchorId() == FLY_AS_CHAR) )
+ {
+ SwTxtFrm* pAnchorTxtFrm( static_cast<SwTxtFrm*>(AnchorFrm()) );
+ if ( pAnchorTxtFrm->GetTxtNode()->GetpSwpHints() &&
+ pAnchorTxtFrm->CalcFlyPos( &GetFrmFmt() ) != STRING_LEN )
+ {
+ AnchorFrm()->Prepare( PREP_FLY_ATTR_CHG, &GetFrmFmt() );
+ }
+ }
+ // <--
+
+ SwPageFrm* pPageFrm = AnchorFrm()->FindPageFrm();
+ _InvalidatePage( pPageFrm );
+
+ // --> #i32270# - also invalidate page frame, at which the
+ // drawing object is registered at.
+ SwPageFrm* pPageFrmRegisteredAt = GetPageFrm();
+ if ( pPageFrmRegisteredAt &&
+ pPageFrmRegisteredAt != pPageFrm )
+ {
+ _InvalidatePage( pPageFrmRegisteredAt );
+ }
+ // <--
+ // --> #i33751#, #i34060# - method <GetPageFrmOfAnchor()>
+ // is replaced by method <FindPageFrmOfAnchor()>. It's return value
+ // have to be checked.
+ SwPageFrm* pPageFrmOfAnchor = FindPageFrmOfAnchor();
+ if ( pPageFrmOfAnchor &&
+ pPageFrmOfAnchor != pPageFrm &&
+ pPageFrmOfAnchor != pPageFrmRegisteredAt )
+ // <--
+ {
+ _InvalidatePage( pPageFrmOfAnchor );
+ }
+ }
+ // <--
+ }
+}
+
+SwFrmFmt& SwAnchoredDrawObject::GetFrmFmt()
+{
+ OSL_ENSURE( static_cast<SwDrawContact*>(GetUserCall(GetDrawObj()))->GetFmt(),
+ "<SwAnchoredDrawObject::GetFrmFmt()> - missing frame format -> crash." );
+ return *(static_cast<SwDrawContact*>(GetUserCall(GetDrawObj()))->GetFmt());
+}
+const SwFrmFmt& SwAnchoredDrawObject::GetFrmFmt() const
+{
+ OSL_ENSURE( static_cast<SwDrawContact*>(GetUserCall(GetDrawObj()))->GetFmt(),
+ "<SwAnchoredDrawObject::GetFrmFmt()> - missing frame format -> crash." );
+ return *(static_cast<SwDrawContact*>(GetUserCall(GetDrawObj()))->GetFmt());
+}
+
+const SwRect SwAnchoredDrawObject::GetObjRect() const
+{
+ // use geometry of drawing object
+ //return GetDrawObj()->GetCurrentBoundRect();
+ return GetDrawObj()->GetSnapRect();
+}
+
+// --> #i70122#
+const SwRect SwAnchoredDrawObject::GetObjBoundRect() const
+{
+ return GetDrawObj()->GetCurrentBoundRect();
+}
+// <--
+
+// --> #i68520#
+bool SwAnchoredDrawObject::_SetObjTop( const SwTwips _nTop )
+{
+ SwTwips nDiff = _nTop - GetObjRect().Top();
+ DrawObj()->Move( Size( 0, nDiff ) );
+
+ return nDiff != 0;
+}
+bool SwAnchoredDrawObject::_SetObjLeft( const SwTwips _nLeft )
+{
+ SwTwips nDiff = _nLeft - GetObjRect().Left();
+ DrawObj()->Move( Size( nDiff, 0 ) );
+
+ return nDiff != 0;
+}
+// <--
+
+/** adjust positioning and alignment attributes for new anchor frame
+
+ #i33313# - add second optional parameter <_pNewObjRect>
+
+ @author OD
+*/
+void SwAnchoredDrawObject::AdjustPositioningAttr( const SwFrm* _pNewAnchorFrm,
+ const SwRect* _pNewObjRect )
+{
+ SwTwips nHoriRelPos = 0;
+ SwTwips nVertRelPos = 0;
+ const Point aAnchorPos = _pNewAnchorFrm->GetFrmAnchorPos( ::HasWrap( GetDrawObj() ) );
+ // --> #i33313#
+ const SwRect aObjRect( _pNewObjRect ? *_pNewObjRect : GetObjRect() );
+ // <--
+ const bool bVert = _pNewAnchorFrm->IsVertical();
+ const bool bR2L = _pNewAnchorFrm->IsRightToLeft();
+ if ( bVert )
+ {
+ nHoriRelPos = aObjRect.Top() - aAnchorPos.Y();
+ nVertRelPos = aAnchorPos.X() - aObjRect.Right();
+ }
+ else if ( bR2L )
+ {
+ nHoriRelPos = aAnchorPos.X() - aObjRect.Right();
+ nVertRelPos = aObjRect.Top() - aAnchorPos.Y();
+ }
+ else
+ {
+ nHoriRelPos = aObjRect.Left() - aAnchorPos.X();
+ nVertRelPos = aObjRect.Top() - aAnchorPos.Y();
+ }
+
+ GetFrmFmt().SetFmtAttr( SwFmtHoriOrient( nHoriRelPos, text::HoriOrientation::NONE, text::RelOrientation::FRAME ) );
+ GetFrmFmt().SetFmtAttr( SwFmtVertOrient( nVertRelPos, text::VertOrientation::NONE, text::RelOrientation::FRAME ) );
+}
+
+// --> #i34748# - change return type
+const Rectangle* SwAnchoredDrawObject::GetLastObjRect() const
+{
+ return mpLastObjRect;
+}
+// <--
+
+// --> #i34748# - change return type.
+// If member <mpLastObjRect> is NULL, create one.
+void SwAnchoredDrawObject::SetLastObjRect( const Rectangle& _rNewLastRect )
+{
+ if ( !mpLastObjRect )
+ {
+ mpLastObjRect = new Rectangle;
+ }
+ *(mpLastObjRect) = _rNewLastRect;
+}
+// <--
+
+void SwAnchoredDrawObject::ObjectAttachedToAnchorFrame()
+{
+ // --> #i31698#
+ SwAnchoredObject::ObjectAttachedToAnchorFrame();
+ // <--
+
+ if ( mbNotYetAttachedToAnchorFrame )
+ {
+ mbNotYetAttachedToAnchorFrame = false;
+ }
+}
+
+/** method to set positioning attributes
+
+ #i35798#
+ During load the positioning attributes aren't set.
+ Thus, the positioning attributes are set by the current object geometry.
+ This method is also used for the conversion for drawing objects
+ (not anchored as-character) imported from OpenOffice.org file format
+ once and directly before the first positioning.
+
+ @author OD
+*/
+void SwAnchoredDrawObject::_SetPositioningAttr()
+{
+ SwDrawContact* pDrawContact =
+ static_cast<SwDrawContact*>(GetUserCall( GetDrawObj() ));
+
+ if ( !pDrawContact->ObjAnchoredAsChar() )
+ {
+ SwRect aObjRect( GetObjRect() );
+
+ SwTwips nHoriPos = aObjRect.Left();
+ SwTwips nVertPos = aObjRect.Top();
+ // --> #i44334#, #i44681#
+ // perform conversion only if position is in horizontal-left-to-right-layout.
+ if ( GetFrmFmt().GetPositionLayoutDir() ==
+ text::PositionLayoutDir::PositionInHoriL2R )
+ {
+ SwFrmFmt::tLayoutDir eLayoutDir = GetFrmFmt().GetLayoutDir();
+ switch ( eLayoutDir )
+ {
+ case SwFrmFmt::HORI_L2R:
+ {
+ // nothing to do
+ }
+ break;
+ case SwFrmFmt::HORI_R2L:
+ {
+ nHoriPos = -aObjRect.Left() - aObjRect.Width();
+ }
+ break;
+ case SwFrmFmt::VERT_R2L:
+ {
+ nHoriPos = aObjRect.Top();
+ nVertPos = -aObjRect.Left() - aObjRect.Width();
+ }
+ break;
+ default:
+ {
+ OSL_FAIL( "<SwAnchoredDrawObject::_SetPositioningAttr()> - unsupported layout direction" );
+ }
+ }
+ }
+ // <--
+
+ // --> #i71182#
+ // only change position - do not lose other attributes
+ SwFmtHoriOrient aHori( GetFrmFmt().GetHoriOrient() );
+ aHori.SetPos( nHoriPos );
+ GetFrmFmt().SetFmtAttr( aHori );
+
+ SwFmtVertOrient aVert( GetFrmFmt().GetVertOrient() );
+
+ aVert.SetPos( nVertPos );
+ GetFrmFmt().SetFmtAttr( aVert );
+ // <--
+
+ // --> #i36010# - set layout direction of the position
+ GetFrmFmt().SetPositionLayoutDir(
+ text::PositionLayoutDir::PositionInLayoutDirOfAnchor );
+ // <--
+ }
+ // --> #i65798# - also for as-character anchored objects
+ // --> #i45952# - indicate that position
+ // attributes are set now.
+ static_cast<SwDrawFrmFmt&>(GetFrmFmt()).PosAttrSet();
+ // <--
+}
+
+void SwAnchoredDrawObject::NotifyBackground( SwPageFrm* _pPageFrm,
+ const SwRect& _rRect,
+ PrepareHint _eHint )
+{
+ ::Notify_Background( GetDrawObj(), _pPageFrm, _rRect, _eHint, sal_True );
+}
+
+/** method to assure that anchored object is registered at the correct
+ page frame
+
+ #i28701#
+
+ @author OD
+*/
+void SwAnchoredDrawObject::RegisterAtCorrectPage()
+{
+ SwPageFrm* pPageFrm( 0L );
+ if ( GetVertPosOrientFrm() )
+ {
+ pPageFrm = const_cast<SwPageFrm*>(GetVertPosOrientFrm()->FindPageFrm());
+ }
+ if ( pPageFrm && GetPageFrm() != pPageFrm )
+ {
+ if ( GetPageFrm() )
+ GetPageFrm()->RemoveDrawObjFromPage( *this );
+ pPageFrm->AppendDrawObjToPage( *this );
+ }
+}
+
+// =============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */