Update ooo320-m1
[ooovba.git] / sw / source / core / objectpositioning / tolayoutanchoredobjectposition.cxx
blob99a5cf2a6d77c957e66a0ada5e3fead9e28c4563
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: tolayoutanchoredobjectposition.cxx,v $
10 * $Revision: 1.13 $
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 <tolayoutanchoredobjectposition.hxx>
34 #include <anchoredobject.hxx>
35 #include <frame.hxx>
36 #include <pagefrm.hxx>
37 #ifndef _SVX_SVDOBJ_HXX
38 #include <svx/svdobj.hxx>
39 #endif
40 #include <frmfmt.hxx>
41 #include <fmtanchr.hxx>
42 #include <fmtornt.hxx>
43 #include <fmtsrnd.hxx>
44 #include <IDocumentSettingAccess.hxx>
45 #include <frmatr.hxx>
46 #include <svx/lrspitem.hxx>
47 #include <svx/ulspitem.hxx>
49 using namespace objectpositioning;
50 using namespace ::com::sun::star;
53 SwToLayoutAnchoredObjectPosition::SwToLayoutAnchoredObjectPosition( SdrObject& _rDrawObj )
54 : SwAnchoredObjectPosition( _rDrawObj ),
55 maRelPos( Point() ),
56 // --> OD 2004-06-17 #i26791#
57 maOffsetToFrmAnchorPos( Point() )
60 SwToLayoutAnchoredObjectPosition::~SwToLayoutAnchoredObjectPosition()
63 /** calculate position for object position type TO_LAYOUT
65 @author OD
67 void SwToLayoutAnchoredObjectPosition::CalcPosition()
69 const SwRect aObjBoundRect( GetAnchoredObj().GetObjRect() );
71 SWRECTFN( (&GetAnchorFrm()) );
73 const SwFrmFmt& rFrmFmt = GetFrmFmt();
74 const SvxLRSpaceItem &rLR = rFrmFmt.GetLRSpace();
75 const SvxULSpaceItem &rUL = rFrmFmt.GetULSpace();
77 const bool bFlyAtFly = FLY_AT_FLY == rFrmFmt.GetAnchor().GetAnchorId();
79 // determine position.
80 // 'vertical' and 'horizontal' position are calculated separately
81 Point aRelPos;
83 // calculate 'vertical' position
84 SwFmtVertOrient aVert( rFrmFmt.GetVertOrient() );
86 // to-frame anchored objects are *only* vertical positioned centered or
87 // bottom, if its wrap mode is 'throught' and its anchor frame has fixed
88 // size. Otherwise, it's positioned top.
89 sal_Int16 eVertOrient = aVert.GetVertOrient();
90 if ( ( bFlyAtFly &&
91 ( eVertOrient == text::VertOrientation::CENTER ||
92 eVertOrient == text::VertOrientation::BOTTOM ) &&
93 SURROUND_THROUGHT != rFrmFmt.GetSurround().GetSurround() &&
94 !GetAnchorFrm().HasFixSize() ) )
96 eVertOrient = text::VertOrientation::TOP;
98 // --> OD 2004-06-17 #i26791# - get vertical offset to frame anchor position.
99 SwTwips nVertOffsetToFrmAnchorPos( 0L );
100 SwTwips nRelPosY =
101 _GetVertRelPos( GetAnchorFrm(), GetAnchorFrm(), eVertOrient,
102 aVert.GetRelationOrient(), aVert.GetPos(),
103 rLR, rUL, nVertOffsetToFrmAnchorPos );
106 // keep the calculated relative vertical position - needed for filters
107 // (including the xml-filter)
109 SwTwips nAttrRelPosY = nRelPosY - nVertOffsetToFrmAnchorPos;
110 if ( aVert.GetVertOrient() != text::VertOrientation::NONE &&
111 aVert.GetPos() != nAttrRelPosY )
113 aVert.SetPos( nAttrRelPosY );
114 const_cast<SwFrmFmt&>(rFrmFmt).LockModify();
115 const_cast<SwFrmFmt&>(rFrmFmt).SetFmtAttr( aVert );
116 const_cast<SwFrmFmt&>(rFrmFmt).UnlockModify();
120 // determine absolute 'vertical' position, depending on layout-direction
121 // --> OD 2004-06-17 #i26791# - determine offset to 'vertical' frame
122 // anchor position, depending on layout-direction
123 if( bVert )
125 ASSERT( !bRev, "<SwToLayoutAnchoredObjectPosition::CalcPosition()> - reverse layout set." );
126 aRelPos.X() = -nRelPosY - aObjBoundRect.Width();
127 maOffsetToFrmAnchorPos.X() = nVertOffsetToFrmAnchorPos;
129 else
131 aRelPos.Y() = nRelPosY;
132 maOffsetToFrmAnchorPos.Y() = nVertOffsetToFrmAnchorPos;
135 // if in online-layout the bottom of to-page anchored object is beyond
136 // the page bottom, the page frame has to grow by growing its body frame.
137 if ( !bFlyAtFly && GetAnchorFrm().IsPageFrm() &&
138 rFrmFmt.getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE) )
140 const long nAnchorBottom = GetAnchorFrm().Frm().Bottom();
141 const long nBottom = GetAnchorFrm().Frm().Top() +
142 aRelPos.Y() + aObjBoundRect.Height();
143 if ( nAnchorBottom < nBottom )
145 static_cast<SwPageFrm&>(GetAnchorFrm()).
146 FindBodyCont()->Grow( nBottom - nAnchorBottom );
149 } // end of determination of vertical position
151 // calculate 'horizontal' position
152 SwFmtHoriOrient aHori( rFrmFmt.GetHoriOrient() );
154 // consider toggle of horizontal position for even pages.
155 const bool bToggle = aHori.IsPosToggle() &&
156 !GetAnchorFrm().FindPageFrm()->OnRightPage();
157 sal_Int16 eHoriOrient = aHori.GetHoriOrient();
158 sal_Int16 eRelOrient = aHori.GetRelationOrient();
159 // toggle orientation
160 _ToggleHoriOrientAndAlign( bToggle, eHoriOrient, eRelOrient );
162 // determine alignment values:
163 // <nWidth>: 'width' of the alignment area
164 // <nOffset>: offset of alignment area, relative to 'left' of
165 // frame anchor position
166 SwTwips nWidth, nOffset;
168 bool bDummy; // in this context irrelevant output parameter
169 _GetHoriAlignmentValues( GetAnchorFrm(), GetAnchorFrm(),
170 eRelOrient, false,
171 nWidth, nOffset, bDummy );
174 SwTwips nObjWidth = (aObjBoundRect.*fnRect->fnGetWidth)();
176 // determine relative horizontal position
177 SwTwips nRelPosX;
178 if ( text::HoriOrientation::NONE == eHoriOrient )
180 if( bToggle ||
181 ( !aHori.IsPosToggle() && GetAnchorFrm().IsRightToLeft() ) )
183 nRelPosX = nWidth - nObjWidth - aHori.GetPos();
185 else
187 nRelPosX = aHori.GetPos();
190 else if ( text::HoriOrientation::CENTER == eHoriOrient )
191 nRelPosX = (nWidth / 2) - (nObjWidth / 2);
192 else if ( text::HoriOrientation::RIGHT == eHoriOrient )
193 nRelPosX = nWidth - ( nObjWidth +
194 ( bVert ? rUL.GetLower() : rLR.GetRight() ) );
195 else
196 nRelPosX = bVert ? rUL.GetUpper() : rLR.GetLeft();
197 nRelPosX += nOffset;
199 // no 'negative' relative horizontal position
200 // OD 06.11.2003 #FollowTextFlowAtFrame# - negative positions allow for
201 // to frame anchored objects.
202 if ( !bFlyAtFly && nRelPosX < 0 )
204 nRelPosX = 0;
207 // determine absolute 'horizontal' position, depending on layout-direction
208 // --> OD 2004-06-17 #i26791# - determine offset to 'horizontal' frame
209 // anchor position, depending on layout-direction
210 if ( bVert )
212 aRelPos.Y() = nRelPosX;
213 maOffsetToFrmAnchorPos.Y() = nOffset;
215 else
217 aRelPos.X() = nRelPosX;
218 maOffsetToFrmAnchorPos.X() = nOffset;
221 // keep the calculated relative horizontal position - needed for filters
222 // (including the xml-filter)
224 SwTwips nAttrRelPosX = nRelPosX - nOffset;
225 if ( text::HoriOrientation::NONE != aHori.GetHoriOrient() &&
226 aHori.GetPos() != nAttrRelPosX )
228 aHori.SetPos( nAttrRelPosX );
229 const_cast<SwFrmFmt&>(rFrmFmt).LockModify();
230 const_cast<SwFrmFmt&>(rFrmFmt).SetFmtAttr( aHori );
231 const_cast<SwFrmFmt&>(rFrmFmt).UnlockModify();
234 } // end of determination of horizontal position
236 // keep calculate relative position
237 maRelPos = aRelPos;
240 /** calculated relative position for object position
242 @author OD
244 Point SwToLayoutAnchoredObjectPosition::GetRelPos() const
246 return maRelPos;