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 : :
30 : : #include <tools/bigint.hxx>
31 : : #include "pagefrm.hxx"
32 : : #include "cntfrm.hxx"
33 : : #include "flyfrm.hxx"
34 : : #include "txtfrm.hxx"
35 : : #include <doc.hxx>
36 : : #include <IDocumentUndoRedo.hxx>
37 : : #include "viewsh.hxx"
38 : : #include "viewimp.hxx"
39 : : #include "pam.hxx"
40 : : #include "frmfmt.hxx"
41 : : #include "frmtool.hxx"
42 : : #include "dflyobj.hxx"
43 : : #include "hints.hxx"
44 : : #include "ndtxt.hxx"
45 : : #include "swundo.hxx"
46 : : #include <editeng/ulspitem.hxx>
47 : : #include <editeng/lrspitem.hxx>
48 : : #include <fmtanchr.hxx>
49 : : #include <fmtornt.hxx>
50 : : #include <fmtfsize.hxx>
51 : : #include <fmtsrnd.hxx>
52 : :
53 : : #include "tabfrm.hxx"
54 : : #include "flyfrms.hxx"
55 : : #include "crstate.hxx"
56 : : #include "sectfrm.hxx"
57 : :
58 : : #include <tocntntanchoredobjectposition.hxx>
59 : : #include <dcontact.hxx>
60 : : #include <sortedobjs.hxx>
61 : : #include <layouter.hxx>
62 : : #include <objectformattertxtfrm.hxx>
63 : : #include <HandleAnchorNodeChg.hxx>
64 : :
65 : : using namespace ::com::sun::star;
66 : :
67 : :
68 : : /*************************************************************************
69 : : |*
70 : : |* SwFlyAtCntFrm::SwFlyAtCntFrm()
71 : : |*
72 : : |*************************************************************************/
73 : :
74 : 129 : SwFlyAtCntFrm::SwFlyAtCntFrm( SwFlyFrmFmt *pFmt, SwFrm* pSib, SwFrm *pAnch ) :
75 : 129 : SwFlyFreeFrm( pFmt, pSib, pAnch )
76 : : {
77 : 129 : bAtCnt = sal_True;
78 [ + - ]: 129 : bAutoPosition = (FLY_AT_CHAR == pFmt->GetAnchor().GetAnchorId());
79 : 129 : }
80 : :
81 : : // #i28701#
82 [ - + ][ + + ]: 15396 : TYPEINIT1(SwFlyAtCntFrm,SwFlyFreeFrm);
83 : : /*************************************************************************
84 : : |*
85 : : |* SwFlyAtCntFrm::Modify()
86 : : |*
87 : : |*************************************************************************/
88 : :
89 : 104 : void SwFlyAtCntFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
90 : : {
91 [ + - ]: 104 : sal_uInt16 nWhich = pNew ? pNew->Which() : 0;
92 : 104 : const SwFmtAnchor *pAnch = 0;
93 : :
94 [ + + ][ - + ]: 150 : if( RES_ATTRSET_CHG == nWhich && SFX_ITEM_SET ==
[ + - ]
95 : 46 : ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( RES_ANCHOR, sal_False,
96 [ + - ]: 46 : (const SfxPoolItem**)&pAnch ))
97 : : ; // The anchor pointer is set at GetItemState!
98 : :
99 [ - + ]: 104 : else if( RES_ANCHOR == nWhich )
100 : : {
101 : : //Change anchor, I move myself to a new place.
102 : : //The anchor type must not change, this is only possible using
103 : : //SwFEShell.
104 : 0 : pAnch = (const SwFmtAnchor*)pNew;
105 : : }
106 : :
107 [ - + ]: 104 : if( pAnch )
108 : : {
109 : : OSL_ENSURE( pAnch->GetAnchorId() == GetFmt()->GetAnchor().GetAnchorId(),
110 : : "Illegal change of anchor type. " );
111 : :
112 : : //Unregister, get hold of a new anchor and attach it
113 [ # # ]: 0 : SwRect aOld( GetObjRectWithSpaces() );
114 [ # # ]: 0 : SwPageFrm *pOldPage = FindPageFrm();
115 [ # # ]: 0 : const SwFrm *pOldAnchor = GetAnchorFrm();
116 [ # # ]: 0 : SwCntntFrm *pCntnt = (SwCntntFrm*)GetAnchorFrm();
117 [ # # ][ # # ]: 0 : AnchorFrm()->RemoveFly( this );
118 : :
119 [ # # ][ # # ]: 0 : const sal_Bool bBodyFtn = (pCntnt->IsInDocBody() || pCntnt->IsInFtn());
[ # # ][ # # ]
120 : :
121 : : // Search the new anchor using the NodeIdx; the relation between old
122 : : // and new NodeIdx determines the search direction
123 [ # # ][ # # ]: 0 : const SwNodeIndex aNewIdx( pAnch->GetCntntAnchor()->nNode );
124 [ # # ]: 0 : SwNodeIndex aOldIdx( *pCntnt->GetNode() );
125 : :
126 : : //fix: depending on which index was smaller, searching in the do-while
127 : : //loop previously was done forward or backwards respectively. This however
128 : : //could lead to an infinite loop. To at least avoid the loop, searching
129 : : //is now done in only one direction. Getting hold of a frame from the node
130 : : //is still possible if the new anchor could not be found. Chances are
131 : : //good that this will be the correct one.
132 : 0 : const bool bNext = aOldIdx < aNewIdx;
133 : : // consider the case that at found anchor frame candidate already a
134 : : // fly frame of the given fly format is registered.
135 : : // consider, that <pCntnt> is the already
136 : : // the new anchor frame.
137 : 0 : bool bFound( aOldIdx == aNewIdx );
138 [ # # ][ # # ]: 0 : while ( pCntnt && !bFound )
[ # # ]
139 : : {
140 [ # # ][ # # ]: 0 : do
[ # # ]
141 : : {
142 [ # # ]: 0 : if ( bNext )
143 [ # # ]: 0 : pCntnt = pCntnt->GetNextCntntFrm();
144 : : else
145 [ # # ]: 0 : pCntnt = pCntnt->GetPrevCntntFrm();
146 : : } while ( pCntnt &&
147 [ # # ]: 0 : !( bBodyFtn == ( pCntnt->IsInDocBody() ||
148 [ # # ][ # # ]: 0 : pCntnt->IsInFtn() ) ) );
[ # # ]
149 [ # # ]: 0 : if ( pCntnt )
150 [ # # ]: 0 : aOldIdx = *pCntnt->GetNode();
151 : :
152 : : // check, if at found anchor frame candidate already a fly frame
153 : : // of the given fly frame format is registered.
154 : 0 : bFound = aOldIdx == aNewIdx;
155 [ # # ][ # # ]: 0 : if ( bFound && pCntnt->GetDrawObjs() )
[ # # ]
156 : : {
157 [ # # ]: 0 : SwFrmFmt* pMyFlyFrmFmt( &GetFrmFmt() );
158 : 0 : SwSortedObjs &rObjs = *pCntnt->GetDrawObjs();
159 [ # # ][ # # ]: 0 : for( sal_uInt16 i = 0; i < rObjs.Count(); ++i)
160 : : {
161 [ # # ][ # # ]: 0 : SwFlyFrm* pFlyFrm = dynamic_cast<SwFlyFrm*>(rObjs[i]);
162 [ # # ][ # # ]: 0 : if ( pFlyFrm &&
[ # # ]
163 [ # # ]: 0 : &(pFlyFrm->GetFrmFmt()) == pMyFlyFrmFmt )
164 : : {
165 : 0 : bFound = false;
166 : 0 : break;
167 : : }
168 : : }
169 : : }
170 : : }
171 [ # # ]: 0 : if ( !pCntnt )
172 : : {
173 : 0 : SwCntntNode *pNode = aNewIdx.GetNode().GetCntntNode();
174 [ # # ]: 0 : pCntnt = pNode->getLayoutFrm( getRootFrm(), &pOldAnchor->Frm().Pos(), 0, sal_False );
175 : : OSL_ENSURE( pCntnt, "Neuen Anker nicht gefunden" );
176 : : }
177 : : //Flys are never attached to a follow, but always on the master which
178 : : //we are going to search now.
179 : 0 : SwCntntFrm* pFlow = pCntnt;
180 [ # # ]: 0 : while ( pFlow->IsFollow() )
181 [ # # ]: 0 : pFlow = pFlow->FindMaster();
182 : 0 : pCntnt = pFlow;
183 : :
184 : : //and *puff* it's attached...
185 [ # # ]: 0 : pCntnt->AppendFly( this );
186 [ # # ][ # # ]: 0 : if ( pOldPage && pOldPage != FindPageFrm() )
[ # # ][ # # ]
187 [ # # ]: 0 : NotifyBackground( pOldPage, aOld, PREP_FLY_LEAVE );
188 : :
189 : : //Fix(3495)
190 [ # # ]: 0 : _InvalidatePos();
191 [ # # ]: 0 : InvalidatePage();
192 : 0 : SetNotifyBack();
193 : : // #i28701# - reset member <maLastCharRect> and
194 : : // <mnLastTopOfLine> for to-character anchored objects.
195 [ # # ][ # # ]: 0 : ClearCharRectAndTopOfLine();
[ # # ]
196 : : }
197 : : else
198 [ + - ]: 104 : SwFlyFrm::Modify( pOld, pNew );
199 : 104 : }
200 : :
201 : : /*************************************************************************
202 : : |*
203 : : |* SwFlyAtCntFrm::MakeAll()
204 : : |*
205 : : |* Description With a paragraph-anchored fly it's absolutely possible that
206 : : |* the anchor reacts to changes of the fly. To this reaction the fly must
207 : : |* certaily react too. Sadly this can lead to oscillations; for example the
208 : : |* fly wants to go down therefore the content can go up - this leads to a
209 : : |* smaller TxtFrm thus the fly needs to go up again whereby the text will
210 : : |* get pushed down...
211 : : |* To avoid such oscillations, a small position stack is built. If the fly
212 : : |* reaches a position which it already had once, the action is stopped.
213 : : |* To not run into problems, the stack is designed to hold five positions.
214 : : |* If the stack flows over, the action is stopped too.
215 : : |* Cancellation leads to the situation that the fly has a bad position in
216 : : |* the end. In case of cancellation, the frame is set to automatic top
217 : : |* alignment to not trigger a 'big oscillation' when calling from outside
218 : : |* again.
219 : : |*************************************************************************/
220 : : //We need some helper classes to monitor the oscillation and a few functions
221 : : //to not get lost.
222 : :
223 : : // #i3317# - re-factoring of the position stack
224 : : class SwOszControl
225 : : {
226 : : static const SwFlyFrm *pStk1;
227 : : static const SwFlyFrm *pStk2;
228 : : static const SwFlyFrm *pStk3;
229 : : static const SwFlyFrm *pStk4;
230 : : static const SwFlyFrm *pStk5;
231 : :
232 : : const SwFlyFrm *pFly;
233 : : // #i3317#
234 : : sal_uInt8 mnPosStackSize;
235 : : std::vector<Point*> maObjPositions;
236 : :
237 : : public:
238 : : SwOszControl( const SwFlyFrm *pFrm );
239 : : ~SwOszControl();
240 : : bool ChkOsz();
241 : : static sal_Bool IsInProgress( const SwFlyFrm *pFly );
242 : : };
243 : : const SwFlyFrm *SwOszControl::pStk1 = 0;
244 : : const SwFlyFrm *SwOszControl::pStk2 = 0;
245 : : const SwFlyFrm *SwOszControl::pStk3 = 0;
246 : : const SwFlyFrm *SwOszControl::pStk4 = 0;
247 : : const SwFlyFrm *SwOszControl::pStk5 = 0;
248 : :
249 : 236 : SwOszControl::SwOszControl( const SwFlyFrm *pFrm )
250 : : : pFly( pFrm ),
251 : : // #i3317#
252 : 236 : mnPosStackSize( 20 )
253 : : {
254 [ + - ]: 236 : if ( !SwOszControl::pStk1 )
255 : 236 : SwOszControl::pStk1 = pFly;
256 [ # # ]: 0 : else if ( !SwOszControl::pStk2 )
257 : 0 : SwOszControl::pStk2 = pFly;
258 [ # # ]: 0 : else if ( !SwOszControl::pStk3 )
259 : 0 : SwOszControl::pStk3 = pFly;
260 [ # # ]: 0 : else if ( !SwOszControl::pStk4 )
261 : 0 : SwOszControl::pStk4 = pFly;
262 [ # # ]: 0 : else if ( !SwOszControl::pStk5 )
263 : 0 : SwOszControl::pStk5 = pFly;
264 : 236 : }
265 : :
266 : 236 : SwOszControl::~SwOszControl()
267 : : {
268 [ + - ]: 236 : if ( SwOszControl::pStk1 == pFly )
269 : 236 : SwOszControl::pStk1 = 0;
270 [ # # ]: 0 : else if ( SwOszControl::pStk2 == pFly )
271 : 0 : SwOszControl::pStk2 = 0;
272 [ # # ]: 0 : else if ( SwOszControl::pStk3 == pFly )
273 : 0 : SwOszControl::pStk3 = 0;
274 [ # # ]: 0 : else if ( SwOszControl::pStk4 == pFly )
275 : 0 : SwOszControl::pStk4 = 0;
276 [ # # ]: 0 : else if ( SwOszControl::pStk5 == pFly )
277 : 0 : SwOszControl::pStk5 = 0;
278 : : // #i3317#
279 [ + + ]: 378 : while ( !maObjPositions.empty() )
280 : : {
281 [ + - ]: 142 : Point* pPos = maObjPositions.back();
282 : 142 : delete pPos;
283 : :
284 [ + - ]: 142 : maObjPositions.pop_back();
285 : : }
286 : 236 : }
287 : :
288 : 768 : sal_Bool SwOszControl::IsInProgress( const SwFlyFrm *pFly )
289 : : {
290 [ - + ][ # # ]: 768 : if ( SwOszControl::pStk1 && !pFly->IsLowerOf( SwOszControl::pStk1 ) )
[ - + ]
291 : 0 : return sal_True;
292 [ - + ][ # # ]: 768 : if ( SwOszControl::pStk2 && !pFly->IsLowerOf( SwOszControl::pStk2 ) )
[ - + ]
293 : 0 : return sal_True;
294 [ - + ][ # # ]: 768 : if ( SwOszControl::pStk3 && !pFly->IsLowerOf( SwOszControl::pStk3 ) )
[ - + ]
295 : 0 : return sal_True;
296 [ - + ][ # # ]: 768 : if ( SwOszControl::pStk4 && !pFly->IsLowerOf( SwOszControl::pStk4 ) )
[ - + ]
297 : 0 : return sal_True;
298 [ - + ][ # # ]: 768 : if ( SwOszControl::pStk5 && !pFly->IsLowerOf( SwOszControl::pStk5 ) )
[ - + ]
299 : 0 : return sal_True;
300 : 768 : return sal_False;
301 : : }
302 : :
303 : 145 : bool SwOszControl::ChkOsz()
304 : : {
305 : 145 : bool bOscillationDetected = false;
306 : :
307 [ - + ]: 145 : if ( maObjPositions.size() == mnPosStackSize )
308 : : {
309 : : // position stack is full -> oscillation
310 : 0 : bOscillationDetected = true;
311 : : }
312 : : else
313 : : {
314 [ + - ][ + - ]: 145 : Point* pNewObjPos = new Point( pFly->GetObjRect().Pos() );
315 [ + - ][ + + ]: 296 : for ( std::vector<Point*>::iterator aObjPosIter = maObjPositions.begin();
316 : 148 : aObjPosIter != maObjPositions.end();
317 : : ++aObjPosIter )
318 : : {
319 [ + + ]: 6 : if ( *(pNewObjPos) == *(*aObjPosIter) )
320 : : {
321 : : // position already occurred -> oscillation
322 : 3 : bOscillationDetected = true;
323 : 3 : delete pNewObjPos;
324 : 3 : break;
325 : : }
326 : : }
327 [ + + ]: 145 : if ( !bOscillationDetected )
328 : : {
329 [ + - ]: 145 : maObjPositions.push_back( pNewObjPos );
330 : : }
331 : : }
332 : :
333 : 145 : return bOscillationDetected;
334 : : }
335 : :
336 : 236 : void SwFlyAtCntFrm::MakeAll()
337 : : {
338 [ + - ][ - + ]: 236 : if ( !GetFmt()->GetDoc()->IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) )
339 : : {
340 : 236 : return;
341 : : }
342 : :
343 [ + - ][ + - ]: 236 : if ( !SwOszControl::IsInProgress( this ) && !IsLocked() && !IsColLocked() )
[ + - ][ + - ]
344 : : {
345 : : // #i28701# - use new method <GetPageFrm()>
346 [ - + ][ # # ]: 236 : if( !GetPageFrm() && GetAnchorFrm() && GetAnchorFrm()->IsInFly() )
[ # # ][ - + ]
347 : : {
348 : 0 : SwFlyFrm* pFly = AnchorFrm()->FindFlyFrm();
349 [ # # ]: 0 : SwPageFrm *pTmpPage = pFly ? pFly->FindPageFrm() : NULL;
350 [ # # ]: 0 : if( pTmpPage )
351 : 0 : pTmpPage->AppendFlyToPage( this );
352 : : }
353 : : // #i28701# - use new method <GetPageFrm()>
354 [ + - ]: 236 : if( GetPageFrm() )
355 : : {
356 : 236 : bSetCompletePaintOnInvalidate = sal_True;
357 : : {
358 [ + - ]: 236 : SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt();
359 [ + - ][ + - ]: 236 : const SwFmtFrmSize &rFrmSz = GetFmt()->GetFrmSize();
360 [ + - - + ]: 472 : if( rFrmSz.GetHeightPercent() != 0xFF &&
[ - + ]
361 : 236 : rFrmSz.GetHeightPercent() >= 100 )
362 : : {
363 : 0 : pFmt->LockModify();
364 [ # # ][ # # ]: 0 : SwFmtSurround aMain( pFmt->GetSurround() );
365 [ # # ]: 0 : if ( aMain.GetSurround() == SURROUND_NONE )
366 : : {
367 : 0 : aMain.SetSurround( SURROUND_THROUGHT );
368 [ # # ]: 0 : pFmt->SetFmtAttr( aMain );
369 : : }
370 [ # # ]: 0 : pFmt->UnlockModify();
371 : : }
372 : : }
373 : :
374 [ + - ]: 236 : SwOszControl aOszCntrl( this );
375 : :
376 : : // #i43255#
377 : : // #i50356# - format the anchor frame, which
378 : : // contains the anchor position. E.g., for at-character anchored
379 : : // object this can be the follow frame of the anchor frame.
380 : : const bool bFormatAnchor =
381 [ + - ][ + - ]: 236 : !static_cast<const SwTxtFrm*>( GetAnchorFrmContainingAnchPos() )->IsAnyJoinLocked() &&
382 [ + - ]: 236 : !ConsiderObjWrapInfluenceOnObjPos() &&
383 [ + - ][ + + ]: 472 : !ConsiderObjWrapInfluenceOfOtherObjs();
[ + - ][ + - ]
384 : :
385 [ + - ][ + - ]: 236 : const SwFrm* pFooter = GetAnchorFrm()->FindFooterOrHeader();
386 [ + + ][ + - ]: 236 : if( pFooter && !pFooter->IsFooterFrm() )
[ + + ]
387 : 18 : pFooter = NULL;
388 : 236 : bool bOsz = false;
389 [ + - ][ - + ]: 236 : sal_Bool bExtra = Lower() && Lower()->IsColumnFrm();
390 : : // #i3317# - boolean, to apply temporarly the
391 : : // 'straightforward positioning process' for the frame due to its
392 : : // overlapping with a previous column.
393 : 236 : bool bConsiderWrapInfluenceDueToOverlapPrevCol( false );
394 : : // #i35911# - boolean, to apply temporarly the
395 : : // 'straightforward positioning process' for the frame due to fact
396 : : // that it causes the complete content of its layout environment
397 : : // to move forward.
398 : : // #i40444# - extend usage of this boolean:
399 : : // apply temporarly the 'straightforward positioning process' for
400 : : // the frame due to the fact that the frame clears the area for
401 : : // the anchor frame, thus it has to move forward.
402 : 236 : bool bConsiderWrapInfluenceDueToMovedFwdAnchor( false );
403 [ + + ][ + - ]: 490 : do {
[ + - ][ + - ]
[ + + ][ + + ]
404 [ + - ][ - + ]: 242 : SWRECTFN( this )
[ # # ][ # # ]
[ - + ]
405 [ + - ][ + - ]: 242 : Point aOldPos( (Frm().*fnRect->fnGetPos)() );
406 [ + - ]: 242 : SwFlyFreeFrm::MakeAll();
407 : : const bool bPosChgDueToOwnFormat =
408 [ + - ][ + - ]: 242 : aOldPos != (Frm().*fnRect->fnGetPos)();
409 : : // #i3317#
410 [ + + ][ - + ]: 460 : if ( !ConsiderObjWrapInfluenceOnObjPos() &&
[ - + ][ + - ]
411 [ + - ]: 218 : OverlapsPrevColumn() )
412 : : {
413 : 0 : bConsiderWrapInfluenceDueToOverlapPrevCol = true;
414 : : }
415 : : // #i28701# - no format of anchor frame, if
416 : : // wrapping style influence is considered on object positioning
417 [ + + ]: 242 : if ( bFormatAnchor )
418 : : {
419 : : SwTxtFrm* pAnchPosAnchorFrm =
420 [ + - ][ - + ]: 218 : dynamic_cast<SwTxtFrm*>(GetAnchorFrmContainingAnchPos());
421 : : OSL_ENSURE( pAnchPosAnchorFrm,
422 : : "<SwFlyAtCntFrm::MakeAll()> - anchor frame of wrong type -> crash" );
423 : : // #i58182# - For the usage of new method
424 : : // <SwObjectFormatterTxtFrm::CheckMovedFwdCondition(..)>
425 : : // to check move forward of anchor frame due to the object
426 : : // positioning it's needed to know, if the object is anchored
427 : : // at the master frame before the anchor frame is formatted.
428 : 218 : const bool bAnchoredAtMaster( !pAnchPosAnchorFrm->IsFollow() );
429 : :
430 : : // #i56300#
431 : : // perform complete format of anchor text frame and its
432 : : // previous frames, which have become invalid due to the
433 : : // fly frame format.
434 [ + - ]: 218 : SwObjectFormatterTxtFrm::FormatAnchorFrmAndItsPrevs( *pAnchPosAnchorFrm );
435 : : // #i35911#
436 : : // #i40444#
437 : : // #i58182# - usage of new method
438 : : // <SwObjectFormatterTxtFrm::CheckMovedFwdCondition(..)>
439 : 218 : sal_uInt32 nToPageNum( 0L );
440 : 218 : bool bDummy( false );
441 [ - + ][ + - ]: 218 : if ( SwObjectFormatterTxtFrm::CheckMovedFwdCondition(
442 [ + - ]: 218 : *this, GetPageFrm()->GetPhyPageNum(),
443 : 436 : bAnchoredAtMaster, nToPageNum, bDummy ) )
444 : : {
445 : 0 : bConsiderWrapInfluenceDueToMovedFwdAnchor = true;
446 : : // mark anchor text frame
447 : : // directly, that it is moved forward by object positioning.
448 [ # # ]: 0 : SwTxtFrm* pAnchorTxtFrm( static_cast<SwTxtFrm*>(AnchorFrm()) );
449 : 0 : bool bInsert( true );
450 : 0 : sal_uInt32 nAnchorFrmToPageNum( 0L );
451 [ # # ]: 0 : const SwDoc& rDoc = *(GetFrmFmt().GetDoc());
452 [ # # ][ # # ]: 0 : if ( SwLayouter::FrmMovedFwdByObjPos(
453 : : rDoc, *pAnchorTxtFrm, nAnchorFrmToPageNum ) )
454 : : {
455 [ # # ]: 0 : if ( nAnchorFrmToPageNum < nToPageNum )
456 [ # # ]: 0 : SwLayouter::RemoveMovedFwdFrm( rDoc, *pAnchorTxtFrm );
457 : : else
458 : 0 : bInsert = false;
459 : : }
460 [ # # ]: 0 : if ( bInsert )
461 : : {
462 : : SwLayouter::InsertMovedFwdFrm( rDoc, *pAnchorTxtFrm,
463 [ # # ]: 218 : nToPageNum );
464 : : }
465 : : }
466 : : }
467 : :
468 [ + - ][ + - ]: 339 : if ( aOldPos != (Frm().*fnRect->fnGetPos)() ||
[ + + - + ]
[ # # ][ # # ]
[ + - ]
[ + + # # ]
469 : 97 : ( !GetValidPosFlag() &&
470 : : ( pFooter || bPosChgDueToOwnFormat ) ) )
471 : : {
472 [ + - ]: 145 : bOsz = aOszCntrl.ChkOsz();
473 : :
474 : : // special loop prevention for dedicated document:
475 [ + + + - : 151 : if ( bOsz &&
- + # # ]
[ - + ]
476 : 6 : HasFixSize() && IsClipped() &&
477 [ # # ]: 0 : GetAnchorFrm()->GetUpper()->IsCellFrm() )
478 : : {
479 [ # # ]: 0 : SwFrmFmt* pFmt = GetFmt();
480 [ # # ]: 0 : const SwFmtFrmSize& rFrmSz = pFmt->GetFrmSize();
481 [ # # # # ]: 0 : if ( rFrmSz.GetWidthPercent() &&
[ # # ]
482 : 0 : rFrmSz.GetHeightPercent() == 0xFF )
483 : : {
484 [ # # ][ # # ]: 0 : SwFmtSurround aSurround( pFmt->GetSurround() );
485 [ # # ]: 0 : if ( aSurround.GetSurround() == SURROUND_NONE )
486 : : {
487 : 0 : pFmt->LockModify();
488 : 0 : aSurround.SetSurround( SURROUND_THROUGHT );
489 [ # # ]: 0 : pFmt->SetFmtAttr( aSurround );
490 : 0 : pFmt->UnlockModify();
491 : 0 : bOsz = false;
492 : : OSL_FAIL( "<SwFlyAtCntFrm::MakeAll()> - special loop prevention for dedicated document of b6403541 applied" );
493 [ # # ]: 0 : }
494 : : }
495 : : }
496 : : }
497 : :
498 [ - + ][ # # ]: 242 : if ( bExtra && Lower() && !Lower()->GetValidPosFlag() )
[ # # ][ - + ]
499 : : {
500 : : // If a multi column frame leaves invalid columns because of
501 : : // a position change, we loop once more and format
502 : : // our content using FormatWidthCols again.
503 [ # # ]: 0 : _InvalidateSize();
504 : 0 : bExtra = sal_False; // Ensure only one additional loop run
505 : : }
506 : 242 : } while ( !IsValid() && !bOsz &&
507 : : // #i3317#
508 : 6 : !bConsiderWrapInfluenceDueToOverlapPrevCol &&
509 : : // #i40444#
510 : 6 : !bConsiderWrapInfluenceDueToMovedFwdAnchor &&
511 [ + - ][ + - ]: 248 : GetFmt()->GetDoc()->IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) );
[ + - ][ + - ]
[ + + ][ # # ]
512 : :
513 : : // #i3317# - instead of attribute change apply
514 : : // temporarly the 'straightforward positioning process'.
515 : : // #i80924#
516 : : // handle special case during splitting of table rows
517 [ - + ][ # # ]: 236 : if ( bConsiderWrapInfluenceDueToMovedFwdAnchor &&
[ # # ][ - + ]
518 [ # # ][ # # ]: 0 : GetAnchorFrm()->IsInTab() &&
519 [ # # ][ # # ]: 0 : GetAnchorFrm()->IsInFollowFlowRow() )
520 : : {
521 [ # # ]: 0 : const SwFrm* pCellFrm = GetAnchorFrm();
522 [ # # ][ # # ]: 0 : while ( pCellFrm && !pCellFrm->IsCellFrm() )
[ # # ]
523 : : {
524 : 0 : pCellFrm = pCellFrm->GetUpper();
525 : : }
526 [ # # ]: 0 : if ( pCellFrm )
527 : : {
528 [ # # ][ # # ]: 0 : SWRECTFN( pCellFrm )
[ # # ][ # # ]
[ # # ]
529 [ # # ][ # # ]: 0 : if ( (pCellFrm->Frm().*fnRect->fnGetTop)() == 0 &&
[ # # ][ # # ]
[ # # ]
530 [ # # ][ # # ]: 0 : (pCellFrm->Frm().*fnRect->fnGetHeight)() == 0 )
531 : : {
532 : 0 : bConsiderWrapInfluenceDueToMovedFwdAnchor = false;
533 : : }
534 : : }
535 : : }
536 [ + + ][ + - ]: 236 : if ( bOsz || bConsiderWrapInfluenceDueToOverlapPrevCol ||
[ - + ]
537 : : // #i40444#
538 : : bConsiderWrapInfluenceDueToMovedFwdAnchor )
539 : : {
540 [ + - ]: 3 : SetTmpConsiderWrapInfluence( true );
541 [ + - ]: 3 : SetRestartLayoutProcess( true );
542 [ + - ]: 3 : SetTmpConsiderWrapInfluenceOfOtherObjs( true );
543 : : }
544 [ + - ]: 236 : bSetCompletePaintOnInvalidate = sal_False;
545 : : }
546 : : }
547 : : }
548 : :
549 : : /** method to determine, if a <MakeAll()> on the Writer fly frame is possible
550 : :
551 : : #i28701#
552 : : */
553 : 532 : bool SwFlyAtCntFrm::IsFormatPossible() const
554 : : {
555 : 532 : return SwFlyFreeFrm::IsFormatPossible() &&
556 [ + - ][ + - ]: 532 : !SwOszControl::IsInProgress( this );
557 : : }
558 : :
559 : : /*************************************************************************
560 : : |*
561 : : |* FindAnchor() und Hilfsfunktionen.
562 : : |*
563 : : |* Description: Searches an anchor for paragraph bound objects
564 : : |* starting from pOldAnch. This is used to show anchors as well as changing
565 : : |* anchors when dragging paragraph bound objects.
566 : : |*
567 : : |*************************************************************************/
568 : :
569 : : class SwDistance
570 : : {
571 : : public:
572 : : SwTwips nMain, nSub;
573 : 6 : SwDistance() { nMain = nSub = 0; }
574 : 4 : SwDistance& operator=( const SwDistance &rTwo )
575 : 4 : { nMain = rTwo.nMain; nSub = rTwo.nSub; return *this; }
576 : 2 : sal_Bool operator<( const SwDistance& rTwo ) const
577 : : { return nMain < rTwo.nMain || ( nMain == rTwo.nMain && nSub &&
578 [ + - ][ + - ]: 2 : rTwo.nSub && nSub < rTwo.nSub ); }
[ - + ][ # # ]
[ # # ]
579 : 0 : sal_Bool operator<=( const SwDistance& rTwo ) const
580 : 0 : { return nMain < rTwo.nMain || ( nMain == rTwo.nMain && ( !nSub ||
581 [ # # ][ # # ]: 0 : !rTwo.nSub || nSub <= rTwo.nSub ) ); }
[ # # ][ # # ]
[ # # ]
582 : : };
583 : :
584 : 2 : const SwFrm * lcl_CalcDownDist( SwDistance &rRet,
585 : : const Point &rPt,
586 : : const SwCntntFrm *pCnt )
587 : : {
588 : 2 : rRet.nSub = 0;
589 : : //If the point stays inside the Cnt everything is clear already; the Cntnt
590 : : //automatically has a distance of 0.
591 [ - + ]: 2 : if ( pCnt->Frm().IsInside( rPt ) )
592 : : {
593 : 0 : rRet.nMain = 0;
594 : 0 : return pCnt;
595 : : }
596 : : else
597 : : {
598 [ - + ]: 2 : const SwLayoutFrm *pUp = pCnt->IsInTab() ? pCnt->FindTabFrm()->GetUpper() : pCnt->GetUpper();
599 : : // single column sections need to interconnect to their upper
600 [ - + ]: 2 : while( pUp->IsSctFrm() )
601 : 0 : pUp = pUp->GetUpper();
602 : 2 : const bool bVert = pUp->IsVertical();
603 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
604 : 2 : const bool bVertL2R = pUp->IsVertLR();
605 : :
606 : : //Follow the text flow.
607 : : // #i70582#
608 : : // --> OD 2009-03-05 - adopted for Support for Classical Mongolian Script
609 : : const SwTwips nTopForObjPos =
610 : : bVert
611 : : ? ( bVertL2R
612 : 0 : ? ( pCnt->Frm().Left() +
613 : 0 : pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() )
614 : 0 : : ( pCnt->Frm().Left() +
615 : 0 : pCnt->Frm().Width() -
616 : 0 : pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() ) )
617 : 2 : : ( pCnt->Frm().Top() +
618 [ # # ][ - + ]: 4 : pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() );
619 [ + - ]: 2 : if ( pUp->Frm().IsInside( rPt ) )
620 : : {
621 : : // <rPt> point is inside environment of given content frame
622 : : // #i70582#
623 [ - + ]: 2 : if( bVert )
624 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
625 : : {
626 [ # # ]: 0 : if ( bVertL2R )
627 : 0 : rRet.nMain = rPt.X() - nTopForObjPos;
628 : : else
629 : 0 : rRet.nMain = nTopForObjPos - rPt.X();
630 : : }
631 : : else
632 : 2 : rRet.nMain = rPt.Y() - nTopForObjPos;
633 : 2 : return pCnt;
634 : : }
635 [ # # ]: 0 : else if ( rPt.Y() <= pUp->Frm().Top() )
636 : : {
637 : : // <rPt> point is above environment of given content frame
638 : : // correct for vertical layout?
639 : 0 : rRet.nMain = LONG_MAX;
640 : : }
641 [ # # # # ]: 0 : else if( rPt.X() < pUp->Frm().Left() &&
[ # # ][ # # ]
642 : 0 : rPt.Y() <= ( bVert ? pUp->Frm().Top() : pUp->Frm().Bottom() ) )
643 : : {
644 : : // <rPt> point is left of environment of given content frame
645 : : // seems not to be correct for vertical layout!?
646 : 0 : const SwFrm *pLay = pUp->GetLeaf( MAKEPAGE_NONE, sal_False, pCnt );
647 [ # # # # ]: 0 : if( !pLay ||
[ # # # # ]
[ # # ][ # # ]
648 : 0 : (bVert && (pLay->Frm().Top() + pLay->Prt().Bottom()) <rPt.Y())||
649 : 0 : (!bVert && (pLay->Frm().Left() + pLay->Prt().Right())<rPt.X()) )
650 : : {
651 : : // <rPt> point is in left border of environment
652 : : // #i70582#
653 [ # # ]: 0 : if( bVert )
654 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
655 : : {
656 [ # # ]: 0 : if ( bVertL2R )
657 : 0 : rRet.nMain = rPt.X() - nTopForObjPos;
658 : : else
659 : 0 : rRet.nMain = nTopForObjPos - rPt.X();
660 : : }
661 : : else
662 : 0 : rRet.nMain = rPt.Y() - nTopForObjPos;
663 : 0 : return pCnt;
664 : : }
665 : : else
666 : 0 : rRet.nMain = LONG_MAX;
667 : : }
668 : : else
669 : : {
670 : : // Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
671 : : rRet.nMain = bVert
672 : : ? ( bVertL2R
673 : 0 : ? ( (pUp->Frm().Left() + pUp->Prt().Right()) - nTopForObjPos )
674 : 0 : : ( nTopForObjPos - (pUp->Frm().Left() + pUp->Prt().Left() ) ) )
675 [ # # ][ # # ]: 0 : : ( (pUp->Frm().Top() + pUp->Prt().Bottom()) - nTopForObjPos );
676 : :
677 : 0 : const SwFrm *pPre = pCnt;
678 : 0 : const SwFrm *pLay = pUp->GetLeaf( MAKEPAGE_NONE, sal_True, pCnt );
679 : 0 : SwTwips nFrmTop = 0;
680 : 0 : SwTwips nPrtHeight = 0;
681 : 0 : sal_Bool bSct = sal_False;
682 : 0 : const SwSectionFrm *pSect = pUp->FindSctFrm();
683 [ # # ]: 0 : if( pSect )
684 : : {
685 : 0 : rRet.nSub = rRet.nMain;
686 : 0 : rRet.nMain = 0;
687 : : }
688 [ # # ][ # # ]: 0 : if( pSect && !pSect->IsAnLower( pLay ) )
[ # # ]
689 : : {
690 : 0 : bSct = sal_False;
691 [ # # ]: 0 : const SwSectionFrm* pNxtSect = pLay ? pLay->FindSctFrm() : 0;
692 [ # # ][ # # ]: 0 : if( pSect->IsAnFollow( pNxtSect ) )
693 : : {
694 [ # # ]: 0 : if( pLay->IsVertical() )
695 : : {
696 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
697 [ # # ]: 0 : if ( pLay->IsVertLR() )
698 : 0 : nFrmTop = pLay->Frm().Left();
699 : : else
700 : 0 : nFrmTop = pLay->Frm().Left() + pLay->Frm().Width();
701 : 0 : nPrtHeight = pLay->Prt().Width();
702 : : }
703 : : else
704 : : {
705 : 0 : nFrmTop = pLay->Frm().Top();
706 : 0 : nPrtHeight = pLay->Prt().Height();
707 : : }
708 : 0 : pSect = pNxtSect;
709 : : }
710 : : else
711 : : {
712 : 0 : pLay = pSect->GetUpper();
713 [ # # ]: 0 : if( pLay->IsVertical() )
714 : : {
715 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
716 [ # # ]: 0 : if ( pLay->IsVertLR() )
717 : : {
718 : 0 : nFrmTop = pSect->Frm().Right();
719 : 0 : nPrtHeight = pLay->Frm().Left() + pLay->Prt().Left()
720 : 0 : + pLay->Prt().Width() - pSect->Frm().Left()
721 : 0 : - pSect->Frm().Width();
722 : : }
723 : : else
724 : : {
725 : 0 : nFrmTop = pSect->Frm().Left();
726 : 0 : nPrtHeight = pSect->Frm().Left() - pLay->Frm().Left()
727 : 0 : - pLay->Prt().Left();
728 : : }
729 : : }
730 : : else
731 : : {
732 : 0 : nFrmTop = pSect->Frm().Bottom();
733 : 0 : nPrtHeight = pLay->Frm().Top() + pLay->Prt().Top()
734 : 0 : + pLay->Prt().Height() - pSect->Frm().Top()
735 : 0 : - pSect->Frm().Height();
736 : : }
737 : 0 : pSect = 0;
738 : : }
739 : : }
740 [ # # ]: 0 : else if( pLay )
741 : : {
742 [ # # ]: 0 : if( pLay->IsVertical() )
743 : : {
744 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
745 [ # # ]: 0 : if ( pLay->IsVertLR() )
746 : : {
747 : 0 : nFrmTop = pLay->Frm().Left();
748 : 0 : nPrtHeight = pLay->Prt().Width();
749 : : }
750 : : else
751 : : {
752 : 0 : nFrmTop = pLay->Frm().Left() + pLay->Frm().Width();
753 : 0 : nPrtHeight = pLay->Prt().Width();
754 : : }
755 : : }
756 : : else
757 : : {
758 : 0 : nFrmTop = pLay->Frm().Top();
759 : 0 : nPrtHeight = pLay->Prt().Height();
760 : : }
761 : 0 : bSct = 0 != pSect;
762 : : }
763 [ # # ][ # # : 0 : while ( pLay && !pLay->Frm().IsInside( rPt ) &&
# # # # #
# # # ]
[ # # ]
764 : 0 : ( pLay->Frm().Top() <= rPt.Y() || pLay->IsInFly() ||
765 : 0 : ( pLay->IsInSct() &&
766 : 0 : pLay->FindSctFrm()->GetUpper()->Frm().Top() <= rPt.Y())) )
767 : : {
768 [ # # ]: 0 : if ( pLay->IsFtnContFrm() )
769 : : {
770 [ # # ]: 0 : if ( !((SwLayoutFrm*)pLay)->Lower() )
771 : : {
772 : 0 : SwFrm *pDel = (SwFrm*)pLay;
773 : 0 : pDel->Cut();
774 [ # # ]: 0 : delete pDel;
775 : 0 : return pPre;
776 : : }
777 : 0 : return 0;
778 : : }
779 : : else
780 : : {
781 [ # # ][ # # ]: 0 : if( bSct || pSect )
782 : 0 : rRet.nSub += nPrtHeight;
783 : : else
784 : 0 : rRet.nMain += nPrtHeight;
785 : 0 : pPre = pLay;
786 : 0 : pLay = pLay->GetLeaf( MAKEPAGE_NONE, sal_True, pCnt );
787 [ # # ][ # # ]: 0 : if( pSect && !pSect->IsAnLower( pLay ) )
[ # # ]
788 : : { // If we're leaving a SwSectionFrm, the next Leaf-Frm
789 : : // is the part of the upper below the SectionFrm.
790 : : const SwSectionFrm* pNxtSect = pLay ?
791 [ # # ]: 0 : pLay->FindSctFrm() : NULL;
792 : 0 : bSct = sal_False;
793 [ # # ][ # # ]: 0 : if( pSect->IsAnFollow( pNxtSect ) )
794 : : {
795 : 0 : pSect = pNxtSect;
796 [ # # ]: 0 : if( pLay->IsVertical() )
797 : : {
798 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
799 [ # # ]: 0 : if ( pLay->IsVertLR() )
800 : : {
801 : 0 : nFrmTop = pLay->Frm().Left();
802 : 0 : nPrtHeight = pLay->Prt().Width();
803 : : }
804 : : else
805 : : {
806 : 0 : nFrmTop = pLay->Frm().Left() + pLay->Frm().Width();
807 : 0 : nPrtHeight = pLay->Prt().Width();
808 : : }
809 : : }
810 : : else
811 : : {
812 : 0 : nFrmTop = pLay->Frm().Top();
813 : 0 : nPrtHeight = pLay->Prt().Height();
814 : : }
815 : : }
816 : : else
817 : : {
818 : 0 : pLay = pSect->GetUpper();
819 [ # # ]: 0 : if( pLay->IsVertical() )
820 : : {
821 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
822 [ # # ]: 0 : if ( pLay->IsVertLR() )
823 : : {
824 : 0 : nFrmTop = pSect->Frm().Right();
825 : 0 : nPrtHeight = pLay->Frm().Left()+pLay->Prt().Left()
826 : 0 : + pLay->Prt().Width() - pSect->Frm().Left()
827 : 0 : - pSect->Frm().Width();
828 : : }
829 : : else
830 : : {
831 : 0 : nFrmTop = pSect->Frm().Left();
832 : 0 : nPrtHeight = pSect->Frm().Left() -
833 : 0 : pLay->Frm().Left() - pLay->Prt().Left();
834 : : }
835 : : }
836 : : else
837 : : {
838 : 0 : nFrmTop = pSect->Frm().Bottom();
839 : 0 : nPrtHeight = pLay->Frm().Top()+pLay->Prt().Top()
840 : 0 : + pLay->Prt().Height() - pSect->Frm().Top()
841 : 0 : - pSect->Frm().Height();
842 : : }
843 : 0 : pSect = 0;
844 : : }
845 : : }
846 [ # # ]: 0 : else if( pLay )
847 : : {
848 [ # # ]: 0 : if( pLay->IsVertical() )
849 : : {
850 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
851 [ # # ]: 0 : if ( pLay->IsVertLR() )
852 : : {
853 : 0 : nFrmTop = pLay->Frm().Left();
854 : 0 : nPrtHeight = pLay->Prt().Width();
855 : : }
856 : : else
857 : : {
858 : 0 : nFrmTop = pLay->Frm().Left() + pLay->Frm().Width();
859 : 0 : nPrtHeight = pLay->Prt().Width();
860 : : }
861 : : }
862 : : else
863 : : {
864 : 0 : nFrmTop = pLay->Frm().Top();
865 : 0 : nPrtHeight = pLay->Prt().Height();
866 : : }
867 : 0 : bSct = 0 != pSect;
868 : : }
869 : : }
870 : : }
871 [ # # ]: 0 : if ( pLay )
872 : : {
873 [ # # ]: 0 : if ( pLay->Frm().IsInside( rPt ) )
874 : : {
875 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
876 : 0 : SwTwips nDiff = pLay->IsVertical() ? ( pLay->IsVertLR() ? ( rPt.X() - nFrmTop ) : ( nFrmTop - rPt.X() ) )
877 [ # # # # ]: 0 : : ( rPt.Y() - nFrmTop );
878 [ # # ][ # # ]: 0 : if( bSct || pSect )
879 : 0 : rRet.nSub += nDiff;
880 : : else
881 : 0 : rRet.nMain += nDiff;
882 : : }
883 [ # # ][ # # ]: 0 : if ( pLay->IsFtnContFrm() && !((SwLayoutFrm*)pLay)->Lower() )
[ # # ]
884 : : {
885 : 0 : SwFrm *pDel = (SwFrm*)pLay;
886 : 0 : pDel->Cut();
887 [ # # ]: 0 : delete pDel;
888 : 0 : return 0;
889 : : }
890 : 0 : return pLay;
891 : : }
892 : : else
893 : 0 : rRet.nMain = LONG_MAX;
894 : : }
895 : : }
896 : 2 : return 0;
897 : : }
898 : :
899 : 0 : sal_uLong lcl_FindCntDiff( const Point &rPt, const SwLayoutFrm *pLay,
900 : : const SwCntntFrm *& rpCnt,
901 : : const sal_Bool bBody, const sal_Bool bFtn )
902 : : {
903 : : // Searches below pLay the nearest Cnt to the point. The reference point of
904 : : //the Cntnts is always the left upper corner.
905 : : //The Cnt should preferably be above the point.
906 : :
907 : : #if OSL_DEBUG_LEVEL > 1
908 : : Point arPoint( rPt );
909 : : #endif
910 : :
911 : 0 : rpCnt = 0;
912 : 0 : sal_uLong nDistance = ULONG_MAX;
913 : 0 : sal_uLong nNearest = ULONG_MAX;
914 : 0 : const SwCntntFrm *pCnt = pLay->ContainsCntnt();
915 : :
916 [ # # ][ # # ]: 0 : while ( pCnt && (bBody != pCnt->IsInDocBody() || bFtn != pCnt->IsInFtn()))
[ # # ][ # # ]
917 : : {
918 : 0 : pCnt = pCnt->GetNextCntntFrm();
919 [ # # ]: 0 : if ( !pLay->IsAnLower( pCnt ) )
920 : 0 : pCnt = 0;
921 : : }
922 : 0 : const SwCntntFrm *pNearest = pCnt;
923 [ # # ]: 0 : if ( pCnt )
924 : : {
925 [ # # # # ]: 0 : do
[ # # ]
926 : : {
927 : : //Calculate the distance between those two points.
928 : : //'delta' X^2 + 'delta' Y^2 = 'distance'^2
929 : 0 : sal_uInt32 dX = Max( pCnt->Frm().Left(), rPt.X() ) -
930 : 0 : Min( pCnt->Frm().Left(), rPt.X() ),
931 : 0 : dY = Max( pCnt->Frm().Top(), rPt.Y() ) -
932 : 0 : Min( pCnt->Frm().Top(), rPt.Y() );
933 [ # # ][ # # ]: 0 : BigInt dX1( dX ), dY1( dY );
934 [ # # ][ # # ]: 0 : dX1 *= dX1; dY1 *= dY1;
935 [ # # ][ # # ]: 0 : const sal_uLong nDiff = ::SqRt( dX1 + dY1 );
936 [ # # ]: 0 : if ( pCnt->Frm().Top() <= rPt.Y() )
937 : : {
938 [ # # ]: 0 : if ( nDiff < nDistance )
939 : : {
940 : : //This one is the nearer one
941 : 0 : nDistance = nNearest = nDiff;
942 : 0 : rpCnt = pNearest = pCnt;
943 : : }
944 : : }
945 [ # # ]: 0 : else if ( nDiff < nNearest )
946 : : {
947 : 0 : nNearest = nDiff;
948 : 0 : pNearest = pCnt;
949 : : }
950 [ # # ]: 0 : pCnt = pCnt->GetNextCntntFrm();
951 [ # # ][ # # ]: 0 : while ( pCnt &&
[ # # ][ # # ]
952 [ # # ][ # # ]: 0 : (bBody != pCnt->IsInDocBody() || bFtn != pCnt->IsInFtn()))
953 [ # # ]: 0 : pCnt = pCnt->GetNextCntntFrm();
954 : :
955 : 0 : } while ( pCnt && pLay->IsAnLower( pCnt ) );
956 : : }
957 [ # # ]: 0 : if ( nDistance == ULONG_MAX )
958 : 0 : { rpCnt = pNearest;
959 : 0 : return nNearest;
960 : : }
961 : 0 : return nDistance;
962 : : }
963 : :
964 : 0 : const SwCntntFrm * lcl_FindCnt( const Point &rPt, const SwCntntFrm *pCnt,
965 : : const sal_Bool bBody, const sal_Bool bFtn )
966 : : {
967 : : //Starting from pCnt searches the CntntFrm whose left upper corner is the
968 : : //nearest to the point.
969 : : //Always returns a CntntFrm.
970 : :
971 : : //First the nearest Cntnt inside the page which contains the Cntnt is
972 : : //searched. Starting from this page the pages in both directions need to
973 : : //be considered. If possible a Cntnt is returned whose Y-position is
974 : : //above the point.
975 : : const SwCntntFrm *pRet, *pNew;
976 [ # # ]: 0 : const SwLayoutFrm *pLay = pCnt->FindPageFrm();
977 : : sal_uLong nDist;
978 : :
979 [ # # ]: 0 : nDist = ::lcl_FindCntDiff( rPt, pLay, pNew, bBody, bFtn );
980 [ # # ]: 0 : if ( pNew )
981 : 0 : pRet = pNew;
982 : : else
983 : 0 : { pRet = pCnt;
984 : 0 : nDist = ULONG_MAX;
985 : : }
986 : 0 : const SwCntntFrm *pNearest = pRet;
987 : 0 : sal_uLong nNearest = nDist;
988 : :
989 [ # # ]: 0 : if ( pLay )
990 : : {
991 : 0 : const SwLayoutFrm *pPge = pLay;
992 : 0 : sal_uLong nOldNew = ULONG_MAX;
993 [ # # ][ # # ]: 0 : for ( sal_uInt16 i = 0; pPge->GetPrev() && (i < 3); ++i )
[ # # ]
994 : : {
995 : 0 : pPge = (SwLayoutFrm*)pPge->GetPrev();
996 [ # # ]: 0 : const sal_uLong nNew = ::lcl_FindCntDiff( rPt, pPge, pNew, bBody, bFtn );
997 [ # # ]: 0 : if ( nNew < nDist )
998 : : {
999 [ # # ]: 0 : if ( pNew->Frm().Top() <= rPt.Y() )
1000 : : {
1001 : 0 : pRet = pNearest = pNew;
1002 : 0 : nDist = nNearest = nNew;
1003 : : }
1004 [ # # ]: 0 : else if ( nNew < nNearest )
1005 : : {
1006 : 0 : pNearest = pNew;
1007 : 0 : nNearest = nNew;
1008 : : }
1009 : : }
1010 [ # # ][ # # ]: 0 : else if ( nOldNew != ULONG_MAX && nNew > nOldNew )
1011 : 0 : break;
1012 : : else
1013 : 0 : nOldNew = nNew;
1014 : :
1015 : : }
1016 : 0 : pPge = pLay;
1017 : 0 : nOldNew = ULONG_MAX;
1018 [ # # ][ # # ]: 0 : for ( sal_uInt16 j = 0; pPge->GetNext() && (j < 3); ++j )
[ # # ]
1019 : : {
1020 : 0 : pPge = (SwLayoutFrm*)pPge->GetNext();
1021 [ # # ]: 0 : const sal_uLong nNew = ::lcl_FindCntDiff( rPt, pPge, pNew, bBody, bFtn );
1022 [ # # ]: 0 : if ( nNew < nDist )
1023 : : {
1024 [ # # ]: 0 : if ( pNew->Frm().Top() <= rPt.Y() )
1025 : : {
1026 : 0 : pRet = pNearest = pNew;
1027 : 0 : nDist = nNearest = nNew;
1028 : : }
1029 [ # # ]: 0 : else if ( nNew < nNearest )
1030 : : {
1031 : 0 : pNearest = pNew;
1032 : 0 : nNearest = nNew;
1033 : : }
1034 : : }
1035 [ # # ][ # # ]: 0 : else if ( nOldNew != ULONG_MAX && nNew > nOldNew )
1036 : 0 : break;
1037 : : else
1038 : 0 : nOldNew = nNew;
1039 : : }
1040 : : }
1041 [ # # ]: 0 : if ( (pRet->Frm().Top() > rPt.Y()) )
1042 : 0 : return pNearest;
1043 : : else
1044 : 0 : return pRet;
1045 : : }
1046 : :
1047 : 16 : void lcl_PointToPrt( Point &rPoint, const SwFrm *pFrm )
1048 : : {
1049 : 16 : SwRect aTmp( pFrm->Prt() );
1050 : 16 : aTmp += pFrm->Frm().Pos();
1051 [ + + ]: 16 : if ( rPoint.X() < aTmp.Left() )
1052 : 2 : rPoint.X() = aTmp.Left();
1053 [ - + ]: 14 : else if ( rPoint.X() > aTmp.Right() )
1054 : 0 : rPoint.X() = aTmp.Right();
1055 [ - + ]: 16 : if ( rPoint.Y() < aTmp.Top() )
1056 : 0 : rPoint.Y() = aTmp.Top();
1057 [ - + ]: 16 : else if ( rPoint.Y() > aTmp.Bottom() )
1058 : 0 : rPoint.Y() = aTmp.Bottom();
1059 : :
1060 : 16 : }
1061 : :
1062 : 8 : const SwCntntFrm *FindAnchor( const SwFrm *pOldAnch, const Point &rNew,
1063 : : const sal_Bool bBodyOnly )
1064 : : {
1065 : : //Search the nearest Cnt around the given document position in the text
1066 : : //flow. The given anchor is the starting Frm.
1067 : : const SwCntntFrm* pCnt;
1068 [ + + ]: 8 : if ( pOldAnch->IsCntntFrm() )
1069 : : {
1070 : 6 : pCnt = (const SwCntntFrm*)pOldAnch;
1071 : : }
1072 : : else
1073 : : {
1074 : 2 : Point aTmp( rNew );
1075 : 2 : SwLayoutFrm *pTmpLay = (SwLayoutFrm*)pOldAnch;
1076 [ - + ]: 2 : if( pTmpLay->IsRootFrm() )
1077 : : {
1078 : 0 : SwRect aTmpRect( aTmp, Size(0,0) );
1079 [ # # ]: 0 : pTmpLay = (SwLayoutFrm*)::FindPage( aTmpRect, pTmpLay->Lower() );
1080 : : }
1081 [ + - ]: 2 : pCnt = pTmpLay->GetCntntPos( aTmp, sal_False, bBodyOnly );
1082 : : }
1083 : :
1084 : : //Take care to use meaningful ranges during search. This means to not enter
1085 : : //or leave header/footer in this case.
1086 [ + - ][ - + ]: 8 : const sal_Bool bBody = pCnt->IsInDocBody() || bBodyOnly;
[ # # ]
1087 [ + - ][ + - ]: 8 : const sal_Bool bFtn = !bBodyOnly && pCnt->IsInFtn();
[ - + ]
1088 : :
1089 : 8 : Point aNew( rNew );
1090 [ + - ]: 8 : if ( bBody )
1091 : : {
1092 : : //#38848 drag from page margin into the body.
1093 [ + - ]: 8 : const SwFrm *pPage = pCnt->FindPageFrm();
1094 : 8 : ::lcl_PointToPrt( aNew, pPage->GetUpper() );
1095 : 8 : SwRect aTmp( aNew, Size( 0, 0 ) );
1096 [ + - ]: 8 : pPage = ::FindPage( aTmp, pPage );
1097 : 8 : ::lcl_PointToPrt( aNew, pPage );
1098 : : }
1099 : :
1100 [ + - ][ + - ]: 8 : if ( pCnt->IsInDocBody() == bBody && pCnt->Frm().IsInside( aNew ) )
[ + - ][ + + ]
[ + + ]
1101 : 6 : return pCnt;
1102 [ + - ][ + - ]: 2 : else if ( pOldAnch->IsInDocBody() || pOldAnch->IsPageFrm() )
[ + - ][ + - ]
1103 : : {
1104 : : // Maybe the selected anchor is on the same page as the current anchor.
1105 : : // With this we won't run into problems with the columns.
1106 : 2 : Point aTmp( aNew );
1107 [ + - ]: 2 : const SwCntntFrm *pTmp = pCnt->FindPageFrm()->
1108 [ + - ]: 2 : GetCntntPos( aTmp, sal_False, sal_True, sal_False );
1109 [ + - ][ + - ]: 2 : if ( pTmp && pTmp->Frm().IsInside( aNew ) )
[ - + ][ - + ]
1110 : 2 : return pTmp;
1111 : : }
1112 : :
1113 : : //Starting from the anchor we now search in both directions until we found
1114 : : //the nearest one respectively.
1115 : : //Not the direct distance is relevant but the distance which needs to be
1116 : : //traveled through the text flow.
1117 : : const SwCntntFrm *pUpLst;
1118 : 2 : const SwCntntFrm *pUpFrm = pCnt;
1119 : 2 : SwDistance nUp, nUpLst;
1120 [ + - ]: 2 : ::lcl_CalcDownDist( nUp, aNew, pUpFrm );
1121 : 2 : SwDistance nDown = nUp;
1122 : 2 : sal_Bool bNegAllowed = sal_True;// Make it possible to leave the negative section once.
1123 [ - + ][ # # ]: 2 : do
[ # # # # ]
[ - + ]
1124 : : {
1125 : 2 : pUpLst = pUpFrm; nUpLst = nUp;
1126 [ + - ]: 2 : pUpFrm = pUpLst->GetPrevCntntFrm();
1127 [ - + ][ # # ]: 2 : while ( pUpFrm &&
[ # # ][ - + ]
1128 [ # # ][ # # ]: 0 : (bBody != pUpFrm->IsInDocBody() || bFtn != pUpFrm->IsInFtn()))
1129 [ # # ]: 0 : pUpFrm = pUpFrm->GetPrevCntntFrm();
1130 [ - + ]: 2 : if ( pUpFrm )
1131 : : {
1132 [ # # ]: 0 : ::lcl_CalcDownDist( nUp, aNew, pUpFrm );
1133 : : //It makes sense to search further, if the distance grows inside
1134 : : //a table.
1135 [ # # ][ # # ]: 0 : if ( pUpLst->IsInTab() && pUpFrm->IsInTab() )
[ # # ][ # # ]
[ # # ]
1136 : : {
1137 [ # # ][ # # ]: 0 : while ( pUpFrm && ((nUpLst < nUp && pUpFrm->IsInTab()) ||
[ # # ][ # # ]
[ # # ][ # # ]
1138 [ # # ]: 0 : bBody != pUpFrm->IsInDocBody()) )
1139 : : {
1140 [ # # ]: 0 : pUpFrm = pUpFrm->GetPrevCntntFrm();
1141 [ # # ]: 0 : if ( pUpFrm )
1142 [ # # ]: 0 : ::lcl_CalcDownDist( nUp, aNew, pUpFrm );
1143 : : }
1144 : : }
1145 : : }
1146 [ + - ]: 2 : if ( !pUpFrm )
1147 : 2 : nUp.nMain = LONG_MAX;
1148 [ + - ][ - + ]: 2 : if ( nUp.nMain >= 0 && LONG_MAX != nUp.nMain )
1149 : : {
1150 : 0 : bNegAllowed = sal_False;
1151 [ # # ]: 0 : if ( nUpLst.nMain < 0 ) //don't take the wrong one, if the value
1152 : : //just changed from negative to positive.
1153 : 0 : { pUpLst = pUpFrm;
1154 : 0 : nUpLst = nUp;
1155 : : }
1156 : : }
1157 : 0 : } while ( pUpFrm && ( ( bNegAllowed && nUp.nMain < 0 ) || ( nUp <= nUpLst ) ) );
1158 : :
1159 : : const SwCntntFrm *pDownLst;
1160 : 2 : const SwCntntFrm *pDownFrm = pCnt;
1161 : 2 : SwDistance nDownLst;
1162 [ - + ]: 2 : if ( nDown.nMain < 0 )
1163 : 0 : nDown.nMain = LONG_MAX;
1164 [ - + # # ]: 2 : do
[ # # ][ # # ]
[ - + ]
1165 : : {
1166 : 2 : pDownLst = pDownFrm; nDownLst = nDown;
1167 [ + - ]: 2 : pDownFrm = pDownLst->GetNextCntntFrm();
1168 [ - + ][ # # ]: 2 : while ( pDownFrm &&
[ # # ][ - + ]
1169 [ # # ][ # # ]: 0 : (bBody != pDownFrm->IsInDocBody() || bFtn != pDownFrm->IsInFtn()))
1170 [ # # ]: 0 : pDownFrm = pDownFrm->GetNextCntntFrm();
1171 [ - + ]: 2 : if ( pDownFrm )
1172 : : {
1173 [ # # ]: 0 : ::lcl_CalcDownDist( nDown, aNew, pDownFrm );
1174 [ # # ]: 0 : if ( nDown.nMain < 0 )
1175 : 0 : nDown.nMain = LONG_MAX;
1176 : : //It makes sense to search further, if the distance grows inside
1177 : : //a table.
1178 [ # # ][ # # ]: 0 : if ( pDownLst->IsInTab() && pDownFrm->IsInTab() )
[ # # ][ # # ]
[ # # ]
1179 : : {
1180 [ # # ][ # # ]: 0 : while ( pDownFrm && ( ( nDown.nMain != LONG_MAX && pDownFrm->IsInTab()) || bBody != pDownFrm->IsInDocBody() ) )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1181 : : {
1182 [ # # ]: 0 : pDownFrm = pDownFrm->GetNextCntntFrm();
1183 [ # # ]: 0 : if ( pDownFrm )
1184 [ # # ]: 0 : ::lcl_CalcDownDist( nDown, aNew, pDownFrm );
1185 [ # # ]: 0 : if ( nDown.nMain < 0 )
1186 : 0 : nDown.nMain = LONG_MAX;
1187 : : }
1188 : : }
1189 : : }
1190 [ + - ]: 2 : if ( !pDownFrm )
1191 : 2 : nDown.nMain = LONG_MAX;
1192 : :
1193 : 0 : } while ( pDownFrm && nDown <= nDownLst &&
1194 : : nDown.nMain != LONG_MAX && nDownLst.nMain != LONG_MAX );
1195 : :
1196 : : //If we couldn't find one in both directions, we'll search the Cntnt whose
1197 : : //left upper corner is the nearest to the point. Such a situation may
1198 : : //happen, if the point doesn't lay in the text flow but in any margin.
1199 [ - + ][ # # ]: 2 : if ( nDownLst.nMain == LONG_MAX && nUpLst.nMain == LONG_MAX )
1200 : : {
1201 : : // If an OLE objects, which is contained in a fly frame
1202 : : // is resized in inplace mode and the new Position is outside the
1203 : : // fly frame, we do not want to leave our fly frame.
1204 [ # # ][ # # ]: 0 : if ( pCnt->IsInFly() )
1205 : 0 : return pCnt;
1206 : :
1207 [ # # ]: 0 : return ::lcl_FindCnt( aNew, pCnt, bBody, bFtn );
1208 : : }
1209 : : else
1210 [ - + ]: 8 : return nDownLst < nUpLst ? pDownLst : pUpLst;
1211 : : }
1212 : :
1213 : : /*************************************************************************
1214 : : |*
1215 : : |* SwFlyAtCntFrm::SetAbsPos()
1216 : : |*
1217 : : |*************************************************************************/
1218 : :
1219 : 0 : void SwFlyAtCntFrm::SetAbsPos( const Point &rNew )
1220 : : {
1221 [ # # ]: 0 : SwPageFrm *pOldPage = FindPageFrm();
1222 [ # # ]: 0 : const SwRect aOld( GetObjRectWithSpaces() );
1223 : 0 : Point aNew( rNew );
1224 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1225 [ # # ][ # # ]: 0 : if( ( GetAnchorFrm()->IsVertical() && !GetAnchorFrm()->IsVertLR() ) || GetAnchorFrm()->IsRightToLeft() )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1226 : 0 : aNew.X() += Frm().Width();
1227 [ # # ][ # # ]: 0 : SwCntntFrm *pCnt = (SwCntntFrm*)::FindAnchor( GetAnchorFrm(), aNew );
1228 [ # # ][ # # ]: 0 : if( pCnt->IsProtected() )
1229 [ # # ]: 0 : pCnt = (SwCntntFrm*)GetAnchorFrm();
1230 : :
1231 : 0 : SwPageFrm *pTmpPage = 0;
1232 [ # # ]: 0 : const bool bVert = pCnt->IsVertical();
1233 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1234 : 0 : const bool bVertL2R = pCnt->IsVertLR();
1235 [ # # ]: 0 : const sal_Bool bRTL = pCnt->IsRightToLeft();
1236 : :
1237 [ # # ][ # # ]: 0 : if( ( !bVert != !GetAnchorFrm()->IsVertical() ) ||
[ # # ][ # # ]
[ # # ]
1238 [ # # ][ # # ]: 0 : ( !bRTL != !GetAnchorFrm()->IsRightToLeft() ) )
1239 : : {
1240 [ # # ][ # # ]: 0 : if( bVert || bRTL )
1241 : 0 : aNew.X() += Frm().Width();
1242 : : else
1243 : 0 : aNew.X() -= Frm().Width();
1244 : : }
1245 : :
1246 [ # # ][ # # ]: 0 : if ( pCnt->IsInDocBody() )
1247 : : {
1248 : : //#38848 drag from page margin into the body.
1249 [ # # ]: 0 : pTmpPage = pCnt->FindPageFrm();
1250 : 0 : ::lcl_PointToPrt( aNew, pTmpPage->GetUpper() );
1251 : 0 : SwRect aTmp( aNew, Size( 0, 0 ) );
1252 [ # # ]: 0 : pTmpPage = (SwPageFrm*)::FindPage( aTmp, pTmpPage );
1253 : 0 : ::lcl_PointToPrt( aNew, pTmpPage );
1254 : : }
1255 : :
1256 : : //Setup RelPos, only invalidate if requested.
1257 : : //rNew is an absolute position. We need to calculate the distance from rNew
1258 : : //to the anchor inside the text flow to correctly set RelPos.
1259 : : //!!!!!We can optimize here: FindAnchor could also return RelPos!
1260 : 0 : const SwFrm *pFrm = 0;
1261 : : SwTwips nY;
1262 [ # # ][ # # ]: 0 : if ( pCnt->Frm().IsInside( aNew ) )
1263 : : {
1264 : : // #i70582#
1265 : : const SwTwips nTopForObjPos =
1266 : : bVert
1267 : : ? ( bVertL2R
1268 : 0 : ? ( pCnt->Frm().Left() +
1269 [ # # ]: 0 : pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() )
1270 : 0 : : ( pCnt->Frm().Left() +
1271 : 0 : pCnt->Frm().Width() -
1272 [ # # ]: 0 : pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() ) )
1273 : 0 : : ( pCnt->Frm().Top() +
1274 [ # # ][ # # ]: 0 : pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() );
[ # # ]
1275 [ # # ]: 0 : if( bVert )
1276 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1277 : : {
1278 [ # # ]: 0 : if ( bVertL2R )
1279 : 0 : nY = rNew.X() - nTopForObjPos;
1280 : : else
1281 : 0 : nY = nTopForObjPos - rNew.X() - Frm().Width();
1282 : : }
1283 : : else
1284 : : {
1285 : 0 : nY = rNew.Y() - nTopForObjPos;
1286 : : }
1287 : : }
1288 : : else
1289 : : {
1290 : 0 : SwDistance aDist;
1291 [ # # ]: 0 : pFrm = ::lcl_CalcDownDist( aDist, aNew, pCnt );
1292 : 0 : nY = aDist.nMain + aDist.nSub;
1293 : : }
1294 : :
1295 : 0 : SwTwips nX = 0;
1296 : :
1297 [ # # ]: 0 : if ( pCnt->IsFollow() )
1298 : : {
1299 : : // Flys are never attached to the follow but always to the master,
1300 : : // which we're going to search now.
1301 : 0 : const SwCntntFrm *pOriginal = pCnt;
1302 : 0 : const SwCntntFrm *pFollow = pCnt;
1303 [ # # ]: 0 : while ( pCnt->IsFollow() )
1304 : : {
1305 [ # # ]: 0 : do
1306 [ # # ]: 0 : { pCnt = pCnt->GetPrevCntntFrm();
1307 : 0 : } while ( pCnt->GetFollow() != pFollow );
1308 : 0 : pFollow = pCnt;
1309 : : }
1310 : 0 : SwTwips nDiff = 0;
1311 [ # # ]: 0 : do
1312 : 0 : { const SwFrm *pUp = pFollow->GetUpper();
1313 [ # # ][ # # ]: 0 : if( pUp->IsVertical() )
1314 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1315 : : {
1316 [ # # ]: 0 : if ( pUp->IsVertLR() )
1317 : 0 : nDiff += pUp->Prt().Width() - pFollow->GetRelPos().X();
1318 : : else
1319 : 0 : nDiff += pFollow->Frm().Left() + pFollow->Frm().Width()
1320 : 0 : - pUp->Frm().Left() - pUp->Prt().Left();
1321 : : }
1322 : : else
1323 : 0 : nDiff += pUp->Prt().Height() - pFollow->GetRelPos().Y();
1324 : 0 : pFollow = pFollow->GetFollow();
1325 : : } while ( pFollow != pOriginal );
1326 : 0 : nY += nDiff;
1327 [ # # ]: 0 : if( bVert )
1328 : 0 : nX = pCnt->Frm().Top() - pOriginal->Frm().Top();
1329 : : else
1330 : 0 : nX = pCnt->Frm().Left() - pOriginal->Frm().Left();
1331 : : }
1332 : :
1333 [ # # ]: 0 : if ( nY == LONG_MAX )
1334 : : {
1335 : : // #i70582#
1336 : : const SwTwips nTopForObjPos =
1337 : : bVert
1338 : : ? ( bVertL2R
1339 : 0 : ? ( pCnt->Frm().Left() +
1340 [ # # ]: 0 : pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() )
1341 : 0 : : ( pCnt->Frm().Left() +
1342 : 0 : pCnt->Frm().Width() -
1343 [ # # ]: 0 : pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() ) )
1344 : 0 : : ( pCnt->Frm().Top() +
1345 [ # # ][ # # ]: 0 : pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() );
[ # # ]
1346 [ # # ]: 0 : if( bVert )
1347 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1348 : : {
1349 [ # # ]: 0 : if ( bVertL2R )
1350 : 0 : nY = rNew.X() - nTopForObjPos;
1351 : : else
1352 : 0 : nY = nTopForObjPos - rNew.X();
1353 : : }
1354 : : else
1355 : : {
1356 : 0 : nY = rNew.Y() - nTopForObjPos;
1357 : : }
1358 : : }
1359 : :
1360 [ # # ]: 0 : SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt();
1361 [ # # ]: 0 : const SwFmtSurround& rSurround = pFmt->GetSurround();
1362 : : const sal_Bool bWrapThrough =
1363 : 0 : rSurround.GetSurround() == SURROUND_THROUGHT;
1364 : 0 : SwTwips nBaseOfstForFly = 0;
1365 [ # # ]: 0 : const SwFrm* pTmpFrm = pFrm ? pFrm : pCnt;
1366 [ # # ]: 0 : if ( pTmpFrm->IsTxtFrm() )
1367 : : nBaseOfstForFly =
1368 : 0 : ((SwTxtFrm*)pTmpFrm)->GetBaseOfstForFly( !bWrapThrough );
1369 : :
1370 [ # # ]: 0 : if( bVert )
1371 : : {
1372 [ # # ]: 0 : if( !pFrm )
1373 : 0 : nX += rNew.Y() - pCnt->Frm().Top() - nBaseOfstForFly;
1374 : : else
1375 : 0 : nX = rNew.Y() - pFrm->Frm().Top() - nBaseOfstForFly;
1376 : : }
1377 : : else
1378 : : {
1379 [ # # ]: 0 : if( !pFrm )
1380 : : {
1381 [ # # ][ # # ]: 0 : if ( pCnt->IsRightToLeft() )
1382 : 0 : nX += pCnt->Frm().Right() - rNew.X() - Frm().Width() +
1383 : 0 : nBaseOfstForFly;
1384 : : else
1385 : 0 : nX += rNew.X() - pCnt->Frm().Left() - nBaseOfstForFly;
1386 : : }
1387 : : else
1388 : : {
1389 [ # # ][ # # ]: 0 : if ( pFrm->IsRightToLeft() )
1390 : 0 : nX += pFrm->Frm().Right() - rNew.X() - Frm().Width() +
1391 : 0 : nBaseOfstForFly;
1392 : : else
1393 : 0 : nX = rNew.X() - pFrm->Frm().Left() - nBaseOfstForFly;
1394 : : }
1395 : : }
1396 [ # # ][ # # ]: 0 : GetFmt()->GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
[ # # ]
1397 : :
1398 [ # # ][ # # ]: 0 : if( pCnt != GetAnchorFrm() || ( IsAutoPos() && pCnt->IsTxtFrm() &&
[ # # ][ # # ]
[ # # ][ # # ]
1399 [ # # ][ # # ]: 0 : GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::HTML_MODE)) )
[ # # ]
1400 : : {
1401 : : //Set the anchor attribute according to the new Cnt.
1402 [ # # ][ # # ]: 0 : SwFmtAnchor aAnch( pFmt->GetAnchor() );
1403 [ # # ]: 0 : SwPosition *pPos = (SwPosition*)aAnch.GetCntntAnchor();
1404 [ # # ][ # # ]: 0 : if( IsAutoPos() && pCnt->IsTxtFrm() )
[ # # ]
1405 : : {
1406 : 0 : SwCrsrMoveState eTmpState( MV_SETONLYTEXT );
1407 : 0 : Point aPt( rNew );
1408 [ # # # # ]: 0 : if( pCnt->GetCrsrOfst( pPos, aPt, &eTmpState )
[ # # ][ # # ]
1409 [ # # ][ # # ]: 0 : && pPos->nNode == *pCnt->GetNode() )
[ # # ][ # # ]
1410 : : {
1411 [ # # ]: 0 : ResetLastCharRectHeight();
1412 [ # # ][ # # ]: 0 : if( text::RelOrientation::CHAR == pFmt->GetVertOrient().GetRelationOrient() )
1413 : 0 : nY = LONG_MAX;
1414 [ # # ][ # # ]: 0 : if( text::RelOrientation::CHAR == pFmt->GetHoriOrient().GetRelationOrient() )
1415 : 0 : nX = LONG_MAX;
1416 : : }
1417 : : else
1418 : : {
1419 [ # # ]: 0 : pPos->nNode = *pCnt->GetNode();
1420 [ # # ][ # # ]: 0 : pPos->nContent.Assign( pCnt->GetNode(), 0 );
1421 : : }
1422 : : }
1423 : : else
1424 : : {
1425 [ # # ]: 0 : pPos->nNode = *pCnt->GetNode();
1426 [ # # ][ # # ]: 0 : pPos->nContent.Assign( pCnt->GetNode(), 0 );
1427 : : }
1428 : :
1429 : : // handle change of anchor node:
1430 : : // if count of the anchor frame also change, the fly frames have to be
1431 : : // re-created. Thus, delete all fly frames except the <this> before the
1432 : : // anchor attribute is change and re-create them afterwards.
1433 : : {
1434 [ # # ]: 0 : SwHandleAnchorNodeChg aHandleAnchorNodeChg( *pFmt, aAnch, this );
1435 [ # # ][ # # ]: 0 : pFmt->GetDoc()->SetAttr( aAnch, *pFmt );
1436 [ # # ]: 0 : }
1437 : : }
1438 : : // #i28701# - use new method <GetPageFrm()>
1439 [ # # ][ # # ]: 0 : else if ( pTmpPage && pTmpPage != GetPageFrm() )
[ # # ][ # # ]
1440 [ # # ][ # # ]: 0 : GetPageFrm()->MoveFly( this, pTmpPage );
1441 : :
1442 [ # # ]: 0 : const Point aRelPos = bVert ? Point( -nY, nX ) : Point( nX, nY );
1443 : :
1444 [ # # ]: 0 : ChgRelPos( aRelPos );
1445 : :
1446 [ # # ][ # # ]: 0 : GetFmt()->GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
[ # # ]
1447 : :
1448 [ # # ][ # # ]: 0 : if ( pOldPage != FindPageFrm() )
1449 [ # # ]: 0 : ::Notify_Background( GetVirtDrawObj(), pOldPage, aOld, PREP_FLY_LEAVE,
1450 [ # # ]: 0 : sal_False );
1451 : 0 : }
1452 : :
1453 : : /** method to assure that anchored object is registered at the correct
1454 : : page frame
1455 : :
1456 : : #i28701#
1457 : : takes over functionality of deleted method <SwFlyAtCntFrm::AssertPage()>
1458 : : */
1459 : 276 : void SwFlyAtCntFrm::RegisterAtCorrectPage()
1460 : : {
1461 : 276 : SwPageFrm* pPageFrm( 0L );
1462 [ + - ]: 276 : if ( GetVertPosOrientFrm() )
1463 : : {
1464 : 276 : pPageFrm = const_cast<SwPageFrm*>(GetVertPosOrientFrm()->FindPageFrm());
1465 : : }
1466 [ + - ][ - + ]: 276 : if ( pPageFrm && GetPageFrm() != pPageFrm )
[ - + ]
1467 : : {
1468 [ # # ]: 0 : if ( GetPageFrm() )
1469 : 0 : GetPageFrm()->MoveFly( this, pPageFrm );
1470 : : else
1471 : 0 : pPageFrm->AppendFlyToPage( this );
1472 : : }
1473 : 276 : }
1474 : :
1475 : : // #i26791#
1476 : : //void SwFlyAtCntFrm::MakeFlyPos()
1477 : 276 : void SwFlyAtCntFrm::MakeObjPos()
1478 : : {
1479 : : // if fly frame position is valid, nothing is to do. Thus, return
1480 [ + - ]: 276 : if ( bValidPos )
1481 : : {
1482 : : return;
1483 : : }
1484 : :
1485 : : // #i26791# - validate position flag here.
1486 : 276 : bValidPos = sal_True;
1487 : :
1488 : : // #i35911# - no calculation of new position, if
1489 : : // anchored object is marked that it clears its environment and its
1490 : : // environment is already cleared.
1491 : : // before checking for cleared environment
1492 : : // check, if member <mpVertPosOrientFrm> is set.
1493 [ + + ][ - + ]: 423 : if ( GetVertPosOrientFrm() &&
[ # # ][ + - ]
1494 [ + - ][ # # ]: 147 : ClearedEnvironment() && HasClearedEnvironment() )
1495 : : {
1496 : : return;
1497 : : }
1498 : :
1499 : : // use new class to position object
1500 : : objectpositioning::SwToCntntAnchoredObjectPosition
1501 [ + - ][ + - ]: 276 : aObjPositioning( *GetVirtDrawObj() );
1502 [ + - ]: 276 : aObjPositioning.CalcPosition();
1503 : :
1504 [ + - ][ + - ]: 276 : SetVertPosOrientFrm ( aObjPositioning.GetVertPosOrientFrm() );
[ + - ]
1505 : : }
1506 : :
1507 : : // #i28701#
1508 : 290 : bool SwFlyAtCntFrm::_InvalidationAllowed( const InvalidationType _nInvalid ) const
1509 : : {
1510 : 290 : bool bAllowed( SwFlyFreeFrm::_InvalidationAllowed( _nInvalid ) );
1511 : :
1512 : : // forbiddance of base instance can't be over ruled.
1513 [ + - ]: 290 : if ( bAllowed )
1514 : : {
1515 [ + + ][ - + ]: 290 : if ( _nInvalid == INVALID_POS ||
1516 : : _nInvalid == INVALID_ALL )
1517 : : {
1518 : 158 : bAllowed = InvalidationOfPosAllowed();
1519 : : }
1520 : : }
1521 : :
1522 : 290 : return bAllowed;
1523 : : }
1524 : :
1525 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|