Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <tolayoutanchoredobjectposition.hxx>
30 : : #include <anchoredobject.hxx>
31 : : #include <frame.hxx>
32 : : #include <pagefrm.hxx>
33 : : #include <svx/svdobj.hxx>
34 : : #include <frmfmt.hxx>
35 : : #include <fmtanchr.hxx>
36 : : #include <fmtornt.hxx>
37 : : #include <fmtsrnd.hxx>
38 : : #include <IDocumentSettingAccess.hxx>
39 : : #include <frmatr.hxx>
40 : : #include "viewsh.hxx"
41 : : #include "viewopt.hxx"
42 : : #include "rootfrm.hxx"
43 : : #include <editeng/lrspitem.hxx>
44 : : #include <editeng/ulspitem.hxx>
45 : :
46 : : using namespace objectpositioning;
47 : : using namespace ::com::sun::star;
48 : :
49 : :
50 : 90 : SwToLayoutAnchoredObjectPosition::SwToLayoutAnchoredObjectPosition( SdrObject& _rDrawObj )
51 : : : SwAnchoredObjectPosition( _rDrawObj ),
52 : : maRelPos( Point() ),
53 : : // #i26791#
54 : 90 : maOffsetToFrmAnchorPos( Point() )
55 : 90 : {}
56 : :
57 : 90 : SwToLayoutAnchoredObjectPosition::~SwToLayoutAnchoredObjectPosition()
58 [ - + ]: 90 : {}
59 : :
60 : : /** calculate position for object position type TO_LAYOUT
61 : :
62 : : @author OD
63 : : */
64 : 90 : void SwToLayoutAnchoredObjectPosition::CalcPosition()
65 : : {
66 [ + - ]: 90 : const SwRect aObjBoundRect( GetAnchoredObj().GetObjRect() );
67 : :
68 [ + - ][ - + ]: 90 : SWRECTFN( (&GetAnchorFrm()) );
[ # # ][ # # ]
[ - + ]
69 : :
70 : 90 : const SwFrmFmt& rFrmFmt = GetFrmFmt();
71 [ + - ]: 90 : const SvxLRSpaceItem &rLR = rFrmFmt.GetLRSpace();
72 [ + - ]: 90 : const SvxULSpaceItem &rUL = rFrmFmt.GetULSpace();
73 : :
74 [ + - ]: 90 : const bool bFlyAtFly = FLY_AT_FLY == rFrmFmt.GetAnchor().GetAnchorId();
75 : :
76 : : // determine position.
77 : : // 'vertical' and 'horizontal' position are calculated separately
78 : 90 : Point aRelPos;
79 : :
80 : : // calculate 'vertical' position
81 [ + - ][ + - ]: 90 : SwFmtVertOrient aVert( rFrmFmt.GetVertOrient() );
82 : : {
83 : : // to-frame anchored objects are *only* vertical positioned centered or
84 : : // bottom, if its wrap mode is 'throught' and its anchor frame has fixed
85 : : // size. Otherwise, it's positioned top.
86 : 90 : sal_Int16 eVertOrient = aVert.GetVertOrient();
87 [ # # ][ # # : 90 : if ( ( bFlyAtFly &&
# # # # ]
[ - + ][ - + ]
88 : : ( eVertOrient == text::VertOrientation::CENTER ||
89 : : eVertOrient == text::VertOrientation::BOTTOM ) &&
90 [ # # ]: 0 : SURROUND_THROUGHT != rFrmFmt.GetSurround().GetSurround() &&
91 : 0 : !GetAnchorFrm().HasFixSize() ) )
92 : : {
93 : 0 : eVertOrient = text::VertOrientation::TOP;
94 : : }
95 : : // #i26791# - get vertical offset to frame anchor position.
96 : 90 : SwTwips nVertOffsetToFrmAnchorPos( 0L );
97 : : SwTwips nRelPosY =
98 : 90 : _GetVertRelPos( GetAnchorFrm(), GetAnchorFrm(), eVertOrient,
99 : 90 : aVert.GetRelationOrient(), aVert.GetPos(),
100 [ + - ]: 180 : rLR, rUL, nVertOffsetToFrmAnchorPos );
101 : :
102 : :
103 : : // keep the calculated relative vertical position - needed for filters
104 : : // (including the xml-filter)
105 : : {
106 : 90 : SwTwips nAttrRelPosY = nRelPosY - nVertOffsetToFrmAnchorPos;
107 [ + + + + ]: 164 : if ( aVert.GetVertOrient() != text::VertOrientation::NONE &&
[ + + ]
108 : 74 : aVert.GetPos() != nAttrRelPosY )
109 : : {
110 : 16 : aVert.SetPos( nAttrRelPosY );
111 : 16 : const_cast<SwFrmFmt&>(rFrmFmt).LockModify();
112 [ + - ]: 16 : const_cast<SwFrmFmt&>(rFrmFmt).SetFmtAttr( aVert );
113 : 16 : const_cast<SwFrmFmt&>(rFrmFmt).UnlockModify();
114 : : }
115 : : }
116 : :
117 : : // determine absolute 'vertical' position, depending on layout-direction
118 : : // #i26791# - determine offset to 'vertical' frame
119 : : // anchor position, depending on layout-direction
120 [ - + ]: 90 : if( bVert )
121 : : {
122 : : OSL_ENSURE( !bRev, "<SwToLayoutAnchoredObjectPosition::CalcPosition()> - reverse layout set." );
123 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
124 [ # # ]: 0 : if ( bVertL2R )
125 : 0 : aRelPos.X() = nRelPosY;
126 : : else
127 : 0 : aRelPos.X() = -nRelPosY - aObjBoundRect.Width();
128 : 0 : maOffsetToFrmAnchorPos.X() = nVertOffsetToFrmAnchorPos;
129 : : }
130 : : else
131 : : {
132 : 90 : aRelPos.Y() = nRelPosY;
133 : 90 : maOffsetToFrmAnchorPos.Y() = nVertOffsetToFrmAnchorPos;
134 : : }
135 : :
136 : : // if in online-layout the bottom of to-page anchored object is beyond
137 : : // the page bottom, the page frame has to grow by growing its body frame.
138 : 90 : const ViewShell *pSh = GetAnchorFrm().getRootFrm()->GetCurrShell();
139 [ + - ]: 180 : if ( !bFlyAtFly && GetAnchorFrm().IsPageFrm() &&
[ + - - + ]
[ - + ][ + - ]
140 : 90 : pSh && pSh->GetViewOptions()->getBrowseMode() )
141 : : {
142 : 0 : const long nAnchorBottom = GetAnchorFrm().Frm().Bottom();
143 : 0 : const long nBottom = GetAnchorFrm().Frm().Top() +
144 : 0 : aRelPos.Y() + aObjBoundRect.Height();
145 [ # # ]: 0 : if ( nAnchorBottom < nBottom )
146 : : {
147 : 0 : static_cast<SwPageFrm&>(GetAnchorFrm()).
148 [ # # ][ # # ]: 0 : FindBodyCont()->Grow( nBottom - nAnchorBottom );
149 : : }
150 : : }
151 : : } // end of determination of vertical position
152 : :
153 : : // calculate 'horizontal' position
154 [ + - ][ + - ]: 90 : SwFmtHoriOrient aHori( rFrmFmt.GetHoriOrient() );
155 : : {
156 : : // consider toggle of horizontal position for even pages.
157 : 90 : const bool bToggle = aHori.IsPosToggle() &&
158 [ # # ][ # # ]: 90 : !GetAnchorFrm().FindPageFrm()->OnRightPage();
[ # # ][ - + ]
159 : 90 : sal_Int16 eHoriOrient = aHori.GetHoriOrient();
160 : 90 : sal_Int16 eRelOrient = aHori.GetRelationOrient();
161 : : // toggle orientation
162 [ + - ]: 90 : _ToggleHoriOrientAndAlign( bToggle, eHoriOrient, eRelOrient );
163 : :
164 : : // determine alignment values:
165 : : // <nWidth>: 'width' of the alignment area
166 : : // <nOffset>: offset of alignment area, relative to 'left' of
167 : : // frame anchor position
168 : : SwTwips nWidth, nOffset;
169 : : {
170 : : bool bDummy; // in this context irrelevant output parameter
171 : 90 : _GetHoriAlignmentValues( GetAnchorFrm(), GetAnchorFrm(),
172 : : eRelOrient, false,
173 [ + - ]: 90 : nWidth, nOffset, bDummy );
174 : : }
175 : :
176 [ + - ][ + - ]: 90 : SwTwips nObjWidth = (aObjBoundRect.*fnRect->fnGetWidth)();
177 : :
178 : : // determine relative horizontal position
179 : : SwTwips nRelPosX;
180 [ + + ]: 90 : if ( text::HoriOrientation::NONE == eHoriOrient )
181 : : {
182 [ + - + - ]: 48 : if( bToggle ||
[ - + ][ - + ]
183 [ + - ]: 32 : ( !aHori.IsPosToggle() && GetAnchorFrm().IsRightToLeft() ) )
184 : : {
185 : 0 : nRelPosX = nWidth - nObjWidth - aHori.GetPos();
186 : : }
187 : : else
188 : : {
189 : 16 : nRelPosX = aHori.GetPos();
190 : : }
191 : : }
192 [ + - ]: 74 : else if ( text::HoriOrientation::CENTER == eHoriOrient )
193 : 74 : nRelPosX = (nWidth / 2) - (nObjWidth / 2);
194 [ # # ]: 0 : else if ( text::HoriOrientation::RIGHT == eHoriOrient )
195 : : nRelPosX = nWidth - ( nObjWidth +
196 [ # # ]: 0 : ( bVert ? rUL.GetLower() : rLR.GetRight() ) );
197 : : else
198 [ # # ]: 0 : nRelPosX = bVert ? rUL.GetUpper() : rLR.GetLeft();
199 : 90 : nRelPosX += nOffset;
200 : :
201 : : // no 'negative' relative horizontal position
202 : : // OD 06.11.2003 #FollowTextFlowAtFrame# - negative positions allow for
203 : : // to frame anchored objects.
204 [ + - ][ + + ]: 90 : if ( !bFlyAtFly && nRelPosX < 0 )
205 : : {
206 : 2 : nRelPosX = 0;
207 : : }
208 : :
209 : : // determine absolute 'horizontal' position, depending on layout-direction
210 : : // #i26791# - determine offset to 'horizontal' frame
211 : : // anchor position, depending on layout-direction
212 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
213 : : // --> OD 2009-09-04 #mongolianlayout#
214 [ + - ][ - + ]: 90 : if( bVert || bVertL2R )
215 : : {
216 : :
217 : 0 : aRelPos.Y() = nRelPosX;
218 : 0 : maOffsetToFrmAnchorPos.Y() = nOffset;
219 : : }
220 : : else
221 : : {
222 : 90 : aRelPos.X() = nRelPosX;
223 : 90 : maOffsetToFrmAnchorPos.X() = nOffset;
224 : : }
225 : :
226 : : // keep the calculated relative horizontal position - needed for filters
227 : : // (including the xml-filter)
228 : : {
229 : 90 : SwTwips nAttrRelPosX = nRelPosX - nOffset;
230 [ + + + + ]: 164 : if ( text::HoriOrientation::NONE != aHori.GetHoriOrient() &&
[ + + ]
231 : 74 : aHori.GetPos() != nAttrRelPosX )
232 : : {
233 : 16 : aHori.SetPos( nAttrRelPosX );
234 : 16 : const_cast<SwFrmFmt&>(rFrmFmt).LockModify();
235 [ + - ]: 16 : const_cast<SwFrmFmt&>(rFrmFmt).SetFmtAttr( aHori );
236 : 16 : const_cast<SwFrmFmt&>(rFrmFmt).UnlockModify();
237 : : }
238 : : }
239 : : } // end of determination of horizontal position
240 : :
241 : : // keep calculate relative position
242 [ + - ][ + - ]: 90 : maRelPos = aRelPos;
243 : 90 : }
244 : :
245 : : /** calculated relative position for object position
246 : :
247 : : @author OD
248 : : */
249 : 166 : Point SwToLayoutAnchoredObjectPosition::GetRelPos() const
250 : : {
251 : 166 : return maRelPos;
252 : : }
253 : :
254 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|