xref: /trunk/main/sw/source/core/layout/flycnt.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 
31 #include <tools/bigint.hxx>
32 #include "pagefrm.hxx"
33 #include "cntfrm.hxx"
34 #include "flyfrm.hxx"
35 #include "txtfrm.hxx"
36 #include <doc.hxx>
37 #include <IDocumentUndoRedo.hxx>
38 #include "viewsh.hxx"
39 #include "viewimp.hxx"
40 #include "pam.hxx"
41 #include "frmfmt.hxx"
42 #include "frmtool.hxx"
43 #include "dflyobj.hxx"
44 #include "hints.hxx"
45 #include "ndtxt.hxx"
46 #include "swundo.hxx"
47 #include "errhdl.hxx"
48 #include <editeng/ulspitem.hxx>
49 #include <editeng/lrspitem.hxx>
50 #include <fmtanchr.hxx>
51 #include <fmtornt.hxx>
52 #include <fmtfsize.hxx>
53 #include <fmtsrnd.hxx>
54 
55 #include "tabfrm.hxx"
56 #include "flyfrms.hxx"
57 #include "crstate.hxx"
58 #include "sectfrm.hxx"
59 
60 // OD 29.10.2003 #113049#
61 #include <tocntntanchoredobjectposition.hxx>
62 // OD 2004-05-24 #i28701#
63 #include <dcontact.hxx>
64 #include <sortedobjs.hxx>
65 // --> OD 2005-09-29 #125370#,#125957#
66 #include <layouter.hxx>
67 // <--
68 // --> OD 2005-11-17 #i56300#
69 #include <objectformattertxtfrm.hxx>
70 // <--
71 // --> OD 2006-03-06 #125892#
72 #include <HandleAnchorNodeChg.hxx>
73 // <--
74 
75 using namespace ::com::sun::star;
76 
77 
78 /*************************************************************************
79 |*
80 |*  SwFlyAtCntFrm::SwFlyAtCntFrm()
81 |*
82 |*  Ersterstellung      MA 11. Nov. 92
83 |*  Letzte Aenderung    MA 09. Apr. 99
84 |*
85 |*************************************************************************/
86 
87 SwFlyAtCntFrm::SwFlyAtCntFrm( SwFlyFrmFmt *pFmt, SwFrm* pSib, SwFrm *pAnch ) :
88     SwFlyFreeFrm( pFmt, pSib, pAnch )
89 {
90     bAtCnt = sal_True;
91     bAutoPosition = (FLY_AT_CHAR == pFmt->GetAnchor().GetAnchorId());
92 }
93 
94 // --> OD 2004-06-29 #i28701#
95 TYPEINIT1(SwFlyAtCntFrm,SwFlyFreeFrm);
96 // <--
97 /*************************************************************************
98 |*
99 |*  SwFlyAtCntFrm::Modify()
100 |*
101 |*  Ersterstellung      MA 08. Feb. 93
102 |*  Letzte Aenderung    MA 23. Nov. 94
103 |*
104 |*************************************************************************/
105 
106 void SwFlyAtCntFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
107 {
108     sal_uInt16 nWhich = pNew ? pNew->Which() : 0;
109     const SwFmtAnchor *pAnch = 0;
110 
111     if( RES_ATTRSET_CHG == nWhich && SFX_ITEM_SET ==
112         ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( RES_ANCHOR, sal_False,
113             (const SfxPoolItem**)&pAnch ))
114         ;       // Beim GetItemState wird der AnkerPointer gesetzt !
115 
116     else if( RES_ANCHOR == nWhich )
117     {
118         //Ankerwechsel, ich haenge mich selbst um.
119         //Es darf sich nicht um einen Wechsel des Ankertyps handeln,
120         //dies ist nur ueber die SwFEShell moeglich.
121         pAnch = (const SwFmtAnchor*)pNew;
122     }
123 
124     if( pAnch )
125     {
126         ASSERT( pAnch->GetAnchorId() == GetFmt()->GetAnchor().GetAnchorId(),
127                 "Unzulaessiger Wechsel des Ankertyps." );
128 
129         //Abmelden, neuen Anker besorgen und 'dranhaengen.
130         SwRect aOld( GetObjRectWithSpaces() );
131         SwPageFrm *pOldPage = FindPageFrm();
132         const SwFrm *pOldAnchor = GetAnchorFrm();
133         SwCntntFrm *pCntnt = (SwCntntFrm*)GetAnchorFrm();
134         AnchorFrm()->RemoveFly( this );
135 
136         const sal_Bool bBodyFtn = (pCntnt->IsInDocBody() || pCntnt->IsInFtn());
137 
138         //Den neuen Anker anhand des NodeIdx suchen, am alten und
139         //neuen NodeIdx kann auch erkannt werden, in welche Richtung
140         //gesucht werden muss.
141         const SwNodeIndex aNewIdx( pAnch->GetCntntAnchor()->nNode );
142         SwNodeIndex aOldIdx( *pCntnt->GetNode() );
143 
144         //fix: Umstellung, ehemals wurde in der do-while-Schleife nach vorn bzw.
145         //nach hinten gesucht; je nachdem wie welcher Index kleiner war.
146         //Das kann aber u.U. zu einer Endlosschleife fuehren. Damit
147         //wenigstens die Schleife unterbunden wird suchen wir nur in eine
148         //Richtung. Wenn der neue Anker nicht gefunden wird koennen wir uns
149         //immer noch vom Node einen Frame besorgen. Die Change, dass dies dann
150         //der richtige ist, ist gut.
151         const bool bNext = aOldIdx < aNewIdx;
152         // --> OD 2006-02-28 #125892#
153         // consider the case that at found anchor frame candidate already a
154         // fly frame of the given fly format is registered.
155         // --> OD 2006-03-15 #133407# - consider, that <pCntnt> is the already
156         // the new anchor frame.
157         bool bFound( aOldIdx == aNewIdx );
158         // <--
159         while ( pCntnt && !bFound )
160         {
161             do
162             {
163                 if ( bNext )
164                     pCntnt = pCntnt->GetNextCntntFrm();
165                 else
166                     pCntnt = pCntnt->GetPrevCntntFrm();
167             } while ( pCntnt &&
168                       !( bBodyFtn == ( pCntnt->IsInDocBody() ||
169                                        pCntnt->IsInFtn() ) ) );
170             if ( pCntnt )
171                 aOldIdx = *pCntnt->GetNode();
172 
173             // --> OD 2006-02-28 #125892#
174             // check, if at found anchor frame candidate already a fly frame
175             // of the given fly frame format is registered.
176             bFound = aOldIdx == aNewIdx;
177             if ( bFound && pCntnt->GetDrawObjs() )
178             {
179                 SwFrmFmt* pMyFlyFrmFmt( &GetFrmFmt() );
180                 SwSortedObjs &rObjs = *pCntnt->GetDrawObjs();
181                 for( sal_uInt16 i = 0; i < rObjs.Count(); ++i)
182                 {
183                     SwFlyFrm* pFlyFrm = dynamic_cast<SwFlyFrm*>(rObjs[i]);
184                     if ( pFlyFrm &&
185                          &(pFlyFrm->GetFrmFmt()) == pMyFlyFrmFmt )
186                     {
187                         bFound = false;
188                         break;
189                     }
190                 }
191             }
192             // <--
193         }
194         // <--
195         if ( !pCntnt )
196         {
197             SwCntntNode *pNode = aNewIdx.GetNode().GetCntntNode();
198             pCntnt = pNode->getLayoutFrm( getRootFrm(), &pOldAnchor->Frm().Pos(), 0, sal_False );
199             ASSERT( pCntnt, "Neuen Anker nicht gefunden" );
200         }
201         //Flys haengen niemals an einem Follow sondern immer am
202         //Master, den suchen wir uns jetzt.
203         SwCntntFrm* pFlow = pCntnt;
204         while ( pFlow->IsFollow() )
205             pFlow = pFlow->FindMaster();
206         pCntnt = pFlow;
207 
208         //und schwupp angehaengt das teil...
209         pCntnt->AppendFly( this );
210         if ( pOldPage && pOldPage != FindPageFrm() )
211             NotifyBackground( pOldPage, aOld, PREP_FLY_LEAVE );
212 
213         //Fix(3495)
214         _InvalidatePos();
215         InvalidatePage();
216         SetNotifyBack();
217         // --> OD 2004-06-24 #i28701# - reset member <maLastCharRect> and
218         // <mnLastTopOfLine> for to-character anchored objects.
219         ClearCharRectAndTopOfLine();
220     }
221     else
222         SwFlyFrm::Modify( pOld, pNew );
223 }
224 
225 /*************************************************************************
226 |*
227 |*  SwFlyAtCntFrm::MakeAll()
228 |*
229 |*  Beschreibung        Bei einem Absatzgebunden Fly kann es durchaus sein,
230 |*      das der Anker auf die Veraenderung des Flys reagiert. Auf diese
231 |*      Reaktion hat der Fly natuerlich auch wieder zu reagieren.
232 |*      Leider kann dies zu Oszillationen fuehren z.b. Der Fly will nach
233 |*      unten, dadurch kann der Inhalt nach oben, der TxtFrm wird kleiner,
234 |*      der Fly muss wieder hoeher woduch der Text wieder nach unten
235 |*      verdraengt wird...
236 |*      Um derartige Oszillationen zu vermeiden, wird ein kleiner Positions-
237 |*      stack aufgebaut. Wenn der Fly ein Position erreicht, die er bereits
238 |*      einmal einnahm, so brechen wir den Vorgang ab. Um keine Risiken
239 |*      einzugehen, wird der Positionsstack so aufgebaut, dass er fuenf
240 |*      Positionen zurueckblickt.
241 |*      Wenn der Stack ueberlaeuft, wird ebenfalls abgebrochen.
242 |*      Der Abbruch fuer dazu, dass der Fly am Ende eine unguenste Position
243 |*      einnimmt. Damit es nicht durch einen wiederholten Aufruf von
244 |*      Aussen zu einer 'grossen Oszillation' kommen kann wird im Abbruch-
245 |*      fall das Attribut des Rahmens auf automatische Ausrichtung oben
246 |*      eingestellt.
247 |*
248 |*  Ersterstellung      MA 12. Nov. 92
249 |*  Letzte Aenderung    MA 20. Sep. 96
250 |*
251 |*************************************************************************/
252 //Wir brauchen ein Paar Hilfsklassen zur Kontrolle der Ozillation und ein paar
253 //Funktionen um die Uebersicht zu gewaehrleisten.
254 // OD 2004-08-25 #i3317# - re-factoring of the position stack
255 class SwOszControl
256 {
257     static const SwFlyFrm *pStk1;
258     static const SwFlyFrm *pStk2;
259     static const SwFlyFrm *pStk3;
260     static const SwFlyFrm *pStk4;
261     static const SwFlyFrm *pStk5;
262 
263     const SwFlyFrm *pFly;
264     // --> OD 2004-08-25 #i3317#
265     sal_uInt8 mnPosStackSize;
266     std::vector<Point*> maObjPositions;
267     // <--
268 
269 public:
270     SwOszControl( const SwFlyFrm *pFrm );
271     ~SwOszControl();
272     bool ChkOsz();
273     static sal_Bool IsInProgress( const SwFlyFrm *pFly );
274 };
275 const SwFlyFrm *SwOszControl::pStk1 = 0;
276 const SwFlyFrm *SwOszControl::pStk2 = 0;
277 const SwFlyFrm *SwOszControl::pStk3 = 0;
278 const SwFlyFrm *SwOszControl::pStk4 = 0;
279 const SwFlyFrm *SwOszControl::pStk5 = 0;
280 
281 SwOszControl::SwOszControl( const SwFlyFrm *pFrm )
282     : pFly( pFrm ),
283       // --> OD 2004-08-25 #i3317#
284       mnPosStackSize( 20 )
285       // <--
286 {
287     if ( !SwOszControl::pStk1 )
288         SwOszControl::pStk1 = pFly;
289     else if ( !SwOszControl::pStk2 )
290         SwOszControl::pStk2 = pFly;
291     else if ( !SwOszControl::pStk3 )
292         SwOszControl::pStk3 = pFly;
293     else if ( !SwOszControl::pStk4 )
294         SwOszControl::pStk4 = pFly;
295     else if ( !SwOszControl::pStk5 )
296         SwOszControl::pStk5 = pFly;
297 }
298 
299 SwOszControl::~SwOszControl()
300 {
301     if ( SwOszControl::pStk1 == pFly )
302         SwOszControl::pStk1 = 0;
303     else if ( SwOszControl::pStk2 == pFly )
304         SwOszControl::pStk2 = 0;
305     else if ( SwOszControl::pStk3 == pFly )
306         SwOszControl::pStk3 = 0;
307     else if ( SwOszControl::pStk4 == pFly )
308         SwOszControl::pStk4 = 0;
309     else if ( SwOszControl::pStk5 == pFly )
310         SwOszControl::pStk5 = 0;
311     // --> OD 2004-08-25 #i3317#
312     while ( !maObjPositions.empty() )
313     {
314         Point* pPos = maObjPositions.back();
315         delete pPos;
316 
317         maObjPositions.pop_back();
318     }
319     // <--
320 }
321 
322 sal_Bool SwOszControl::IsInProgress( const SwFlyFrm *pFly )
323 {
324     if ( SwOszControl::pStk1 && !pFly->IsLowerOf( SwOszControl::pStk1 ) )
325         return sal_True;
326     if ( SwOszControl::pStk2 && !pFly->IsLowerOf( SwOszControl::pStk2 ) )
327         return sal_True;
328     if ( SwOszControl::pStk3 && !pFly->IsLowerOf( SwOszControl::pStk3 ) )
329         return sal_True;
330     if ( SwOszControl::pStk4 && !pFly->IsLowerOf( SwOszControl::pStk4 ) )
331         return sal_True;
332     if ( SwOszControl::pStk5 && !pFly->IsLowerOf( SwOszControl::pStk5 ) )
333         return sal_True;
334     return sal_False;
335 }
336 
337 bool SwOszControl::ChkOsz()
338 {
339     bool bOscillationDetected = false;
340 
341     if ( maObjPositions.size() == mnPosStackSize )
342     {
343         // position stack is full -> oscillation
344         bOscillationDetected = true;
345     }
346     else
347     {
348         Point* pNewObjPos = new Point( pFly->GetObjRect().Pos() );
349         for ( std::vector<Point*>::iterator aObjPosIter = maObjPositions.begin();
350               aObjPosIter != maObjPositions.end();
351               ++aObjPosIter )
352         {
353             if ( *(pNewObjPos) == *(*aObjPosIter) )
354             {
355                 // position already occured -> oscillation
356                 bOscillationDetected = true;
357                 delete pNewObjPos;
358                 break;
359             }
360         }
361         if ( !bOscillationDetected )
362         {
363             maObjPositions.push_back( pNewObjPos );
364         }
365     }
366 
367     return bOscillationDetected;
368 }
369 
370 void SwFlyAtCntFrm::MakeAll()
371 {
372     // OD 2004-01-19 #110582#
373     if ( !GetFmt()->GetDoc()->IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) )
374     {
375         return;
376     }
377 
378     if ( !SwOszControl::IsInProgress( this ) && !IsLocked() && !IsColLocked() )
379     {
380         // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
381         if( !GetPageFrm() && GetAnchorFrm() && GetAnchorFrm()->IsInFly() )
382         {
383             SwFlyFrm* pFly = AnchorFrm()->FindFlyFrm();
384             SwPageFrm *pTmpPage = pFly ? pFly->FindPageFrm() : NULL;
385             if( pTmpPage )
386                 pTmpPage->AppendFlyToPage( this );
387         }
388         // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
389         if( GetPageFrm() )
390         {
391             bSetCompletePaintOnInvalidate = sal_True;
392             {
393                 SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt();
394                 const SwFmtFrmSize &rFrmSz = GetFmt()->GetFrmSize();
395                 if( rFrmSz.GetHeightPercent() != 0xFF &&
396                     rFrmSz.GetHeightPercent() >= 100 )
397                 {
398                     pFmt->LockModify();
399                     SwFmtSurround aMain( pFmt->GetSurround() );
400                     if ( aMain.GetSurround() == SURROUND_NONE )
401                     {
402                         aMain.SetSurround( SURROUND_THROUGHT );
403                         pFmt->SetFmtAttr( aMain );
404                     }
405                     pFmt->UnlockModify();
406                 }
407             }
408 
409             SwOszControl aOszCntrl( this );
410 
411             // --> OD 2005-02-22 #i43255#
412             // --> OD 2005-06-07 #i50356# - format the anchor frame, which
413             // contains the anchor position. E.g., for at-character anchored
414             // object this can be the follow frame of the anchor frame.
415             const bool bFormatAnchor =
416                     !static_cast<const SwTxtFrm*>( GetAnchorFrmContainingAnchPos() )->IsAnyJoinLocked() &&
417                     !ConsiderObjWrapInfluenceOnObjPos() &&
418                     !ConsiderObjWrapInfluenceOfOtherObjs();
419             // <--
420 
421             const SwFrm* pFooter = GetAnchorFrm()->FindFooterOrHeader();
422             if( pFooter && !pFooter->IsFooterFrm() )
423                 pFooter = NULL;
424             bool bOsz = false;
425             sal_Bool bExtra = Lower() && Lower()->IsColumnFrm();
426             // --> OD 2004-08-25 #i3317# - boolean, to apply temporarly the
427             // 'straightforward positioning process' for the frame due to its
428             // overlapping with a previous column.
429             bool bConsiderWrapInfluenceDueToOverlapPrevCol( false );
430             // <--
431             // --> OD 2004-10-22 #i35911# - boolean, to apply temporarly the
432             // 'straightforward positioning process' for the frame due to fact
433             // that it causes the complete content of its layout environment
434             // to move forward.
435             // --> OD 2005-01-14 #i40444# - extend usage of this boolean:
436             // apply temporarly the 'straightforward positioning process' for
437             // the frame due to the fact that the frame clears the area for
438             // the anchor frame, thus it has to move forward.
439             bool bConsiderWrapInfluenceDueToMovedFwdAnchor( false );
440             // <--
441             do {
442                 SWRECTFN( this )
443                 Point aOldPos( (Frm().*fnRect->fnGetPos)() );
444                 SwFlyFreeFrm::MakeAll();
445                 const bool bPosChgDueToOwnFormat =
446                                         aOldPos != (Frm().*fnRect->fnGetPos)();
447                 // --> OD 2004-08-25 #i3317#
448                 if ( !ConsiderObjWrapInfluenceOnObjPos() &&
449                      OverlapsPrevColumn() )
450                 {
451                     bConsiderWrapInfluenceDueToOverlapPrevCol = true;
452                 }
453                 // <--
454                 // OD 2004-05-12 #i28701# - no format of anchor frame, if
455                 // wrapping style influence is considered on object positioning
456                 if ( bFormatAnchor )
457                 {
458                     SwTxtFrm* pAnchPosAnchorFrm =
459                             dynamic_cast<SwTxtFrm*>(GetAnchorFrmContainingAnchPos());
460                     ASSERT( pAnchPosAnchorFrm,
461                             "<SwFlyAtCntFrm::MakeAll()> - anchor frame of wrong type -> crash" );
462                     // --> OD 2006-01-27 #i58182# - For the usage of new method
463                     // <SwObjectFormatterTxtFrm::CheckMovedFwdCondition(..)>
464                     // to check move forward of anchor frame due to the object
465                     // positioning it's needed to know, if the object is anchored
466                     // at the master frame before the anchor frame is formatted.
467                     const bool bAnchoredAtMaster( !pAnchPosAnchorFrm->IsFollow() );
468                     // <--
469 
470                     // --> OD 2005-11-17 #i56300#
471                     // perform complete format of anchor text frame and its
472                     // previous frames, which have become invalid due to the
473                     // fly frame format.
474                     SwObjectFormatterTxtFrm::FormatAnchorFrmAndItsPrevs( *pAnchPosAnchorFrm );
475                     // <--
476                     // --> OD 2004-10-22 #i35911#
477                     // --> OD 2005-01-14 #i40444#
478                     // --> OD 2006-01-27 #i58182# - usage of new method
479                     // <SwObjectFormatterTxtFrm::CheckMovedFwdCondition(..)>
480                     sal_uInt32 nToPageNum( 0L );
481                     bool bDummy( false );
482                     if ( SwObjectFormatterTxtFrm::CheckMovedFwdCondition(
483                                         *this, GetPageFrm()->GetPhyPageNum(),
484                                         bAnchoredAtMaster, nToPageNum, bDummy ) )
485                     {
486                         bConsiderWrapInfluenceDueToMovedFwdAnchor = true;
487                         // --> OD 2005-09-29 #125370#,#125957# - mark anchor text frame
488                         // directly, that it is moved forward by object positioning.
489                         SwTxtFrm* pAnchorTxtFrm( static_cast<SwTxtFrm*>(AnchorFrm()) );
490                         bool bInsert( true );
491                         sal_uInt32 nAnchorFrmToPageNum( 0L );
492                         const SwDoc& rDoc = *(GetFrmFmt().GetDoc());
493                         if ( SwLayouter::FrmMovedFwdByObjPos(
494                                                 rDoc, *pAnchorTxtFrm, nAnchorFrmToPageNum ) )
495                         {
496                             if ( nAnchorFrmToPageNum < nToPageNum )
497                                 SwLayouter::RemoveMovedFwdFrm( rDoc, *pAnchorTxtFrm );
498                             else
499                                 bInsert = false;
500                         }
501                         if ( bInsert )
502                         {
503                             SwLayouter::InsertMovedFwdFrm( rDoc, *pAnchorTxtFrm,
504                                                            nToPageNum );
505                         }
506                         // <--
507                     }
508                     // <--
509                 }
510 
511                 if ( aOldPos != (Frm().*fnRect->fnGetPos)() ||
512                      ( !GetValidPosFlag() &&
513                        ( pFooter || bPosChgDueToOwnFormat ) ) )
514                 {
515                     bOsz = aOszCntrl.ChkOsz();
516 
517                     // --> OD 2006-04-13 #b6403541#
518                     // special loop prevention for dedicated document:
519                     if ( bOsz &&
520                          HasFixSize() && IsClipped() &&
521                          GetAnchorFrm()->GetUpper()->IsCellFrm() )
522                     {
523                         SwFrmFmt* pFmt = GetFmt();
524                         const SwFmtFrmSize& rFrmSz = pFmt->GetFrmSize();
525                         if ( rFrmSz.GetWidthPercent() &&
526                              rFrmSz.GetHeightPercent() == 0xFF )
527                         {
528                             SwFmtSurround aSurround( pFmt->GetSurround() );
529                             if ( aSurround.GetSurround() == SURROUND_NONE )
530                             {
531                                 pFmt->LockModify();
532                                 aSurround.SetSurround( SURROUND_THROUGHT );
533                                 pFmt->SetFmtAttr( aSurround );
534                                 pFmt->UnlockModify();
535                                 bOsz = false;
536 #if OSL_DEBUG_LEVEL > 1
537                                 ASSERT( false,
538                                         "<SwFlyAtCntFrm::MakeAll()> - special loop prevention for dedicated document of b6403541 applied" );
539 #endif
540                             }
541                         }
542                     }
543                     // <--
544                 }
545 
546                 if ( bExtra && Lower() && !Lower()->GetValidPosFlag() )
547                 {
548                     // Wenn ein mehrspaltiger Rahmen wg. Positionswechsel ungueltige
549                     // Spalten hinterlaesst, so drehen wir lieber hier eine weitere
550                     // Runde und formatieren unseren Inhalt via FormatWidthCols nochmal.
551                         _InvalidateSize();
552                     bExtra = sal_False; // Sicherhaltshalber gibt es nur eine Ehrenrunde.
553                 }
554             } while ( !IsValid() && !bOsz &&
555                       // --> OD 2004-08-25 #i3317#
556                       !bConsiderWrapInfluenceDueToOverlapPrevCol &&
557                       // <--
558                       // --> OD 2005-01-14 #i40444#
559                       !bConsiderWrapInfluenceDueToMovedFwdAnchor &&
560                       // <--
561                       GetFmt()->GetDoc()->IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) );
562 
563             // --> OD 2004-08-25 #i3317# - instead of attribute change apply
564             // temporarly the 'straightforward positioning process'.
565             // --> OD 2007-11-29 #i80924#
566             // handle special case during splitting of table rows
567             if ( bConsiderWrapInfluenceDueToMovedFwdAnchor &&
568                  GetAnchorFrm()->IsInTab() &&
569                  GetAnchorFrm()->IsInFollowFlowRow() )
570             {
571                 const SwFrm* pCellFrm = GetAnchorFrm();
572                 while ( pCellFrm && !pCellFrm->IsCellFrm() )
573                 {
574                     pCellFrm = pCellFrm->GetUpper();
575                 }
576                 if ( pCellFrm )
577                 {
578                     SWRECTFN( pCellFrm )
579                     if ( (pCellFrm->Frm().*fnRect->fnGetTop)() == 0 &&
580                          (pCellFrm->Frm().*fnRect->fnGetHeight)() == 0 )
581                     {
582                         bConsiderWrapInfluenceDueToMovedFwdAnchor = false;
583                     }
584                 }
585             }
586             // <--
587             if ( bOsz || bConsiderWrapInfluenceDueToOverlapPrevCol ||
588                  // --> OD 2005-01-14 #i40444#
589                  bConsiderWrapInfluenceDueToMovedFwdAnchor )
590                  // <--
591             {
592                 SetTmpConsiderWrapInfluence( true );
593                 SetRestartLayoutProcess( true );
594                 // --> OD 2006-07-24 #b6449874#
595                 SetTmpConsiderWrapInfluenceOfOtherObjs( true );
596                 // <--
597             }
598             // <--
599             bSetCompletePaintOnInvalidate = sal_False;
600         }
601     }
602 }
603 
604 /** method to determine, if a <MakeAll()> on the Writer fly frame is possible
605 
606     OD 2004-05-11 #i28701#
607 
608     @author OD
609 */
610 bool SwFlyAtCntFrm::IsFormatPossible() const
611 {
612     return SwFlyFreeFrm::IsFormatPossible() &&
613            !SwOszControl::IsInProgress( this );
614 }
615 
616 /*************************************************************************
617 |*
618 |*  FindAnchor() und Hilfsfunktionen.
619 |*
620 |*  Beschreibung:       Sucht ausgehend von pOldAnch einen Anker fuer
621 |*      Absatzgebundene Objekte.
622 |*      Wird beim Draggen von Absatzgebundenen Objekten zur Ankeranzeige sowie
623 |*      fuer Ankerwechsel benoetigt.
624 |*  Ersterstellung      MA 22. Jun. 93
625 |*  Letzte Aenderung    MA 30. Jan. 95
626 |*
627 |*************************************************************************/
628 
629 class SwDistance
630 {
631 public:
632     SwTwips nMain, nSub;
633     SwDistance() { nMain = nSub = 0; }
634     SwDistance& operator=( const SwDistance &rTwo )
635         { nMain = rTwo.nMain; nSub = rTwo.nSub; return *this; }
636     sal_Bool operator<( const SwDistance& rTwo )
637         { return nMain < rTwo.nMain || ( nMain == rTwo.nMain && nSub &&
638           rTwo.nSub && nSub < rTwo.nSub ); }
639     sal_Bool operator<=( const SwDistance& rTwo )
640         { return nMain < rTwo.nMain || ( nMain == rTwo.nMain && ( !nSub ||
641           !rTwo.nSub || nSub <= rTwo.nSub ) ); }
642 };
643 
644 const SwFrm * MA_FASTCALL lcl_CalcDownDist( SwDistance &rRet,
645                                          const Point &rPt,
646                                          const SwCntntFrm *pCnt )
647 {
648     rRet.nSub = 0;
649     //Wenn der Point direkt innerhalb des Cnt steht ist die Sache klar und
650     //der Cntnt hat automatisch eine Entfernung von 0
651     if ( pCnt->Frm().IsInside( rPt ) )
652     {
653         rRet.nMain = 0;
654         return pCnt;
655     }
656     else
657     {
658         const SwLayoutFrm *pUp = pCnt->IsInTab() ? pCnt->FindTabFrm()->GetUpper() : pCnt->GetUpper();
659         // einspaltige Bereiche muessen zu ihrem Upper durchschalten
660         while( pUp->IsSctFrm() )
661             pUp = pUp->GetUpper();
662         const bool bVert = pUp->IsVertical();
663         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
664         const bool bVertL2R = pUp->IsVertLR();
665 
666         //Dem Textflus folgen.
667         // --> OD 2009-01-12 #i70582#
668         // --> OD 2009-03-05 - adopted for Support for Classical Mongolian Script
669         const SwTwips nTopForObjPos =
670             bVert
671             ? ( bVertL2R
672                 ? ( pCnt->Frm().Left() +
673                     pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() )
674                 : ( pCnt->Frm().Left() +
675                     pCnt->Frm().Width() -
676                     pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() ) )
677             : ( pCnt->Frm().Top() +
678                 pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() );
679         // <--
680         if ( pUp->Frm().IsInside( rPt ) )
681         {
682             // OD 26.09.2003 - <rPt> point is inside environment of given content frame
683             // --> OD 2009-01-12 #i70582#
684             if( bVert )
685             //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
686             {
687                 if ( bVertL2R )
688                     rRet.nMain =  rPt.X() - nTopForObjPos;
689                 else
690                     rRet.nMain =  nTopForObjPos - rPt.X();
691             }
692             else
693                 rRet.nMain =  rPt.Y() - nTopForObjPos;
694             // <--
695             return pCnt;
696         }
697         else if ( rPt.Y() <= pUp->Frm().Top() )
698         {
699             // OD 26.09.2003 - <rPt> point is above environment of given content frame
700             // OD: correct for vertical layout?
701             rRet.nMain = LONG_MAX;
702         }
703         else if( rPt.X() < pUp->Frm().Left() &&
704                  rPt.Y() <= ( bVert ? pUp->Frm().Top() : pUp->Frm().Bottom() ) )
705         {
706             // OD 26.09.2003 - <rPt> point is left of environment of given content frame
707             // OD: seems not to be correct for vertical layout!?
708             const SwFrm *pLay = pUp->GetLeaf( MAKEPAGE_NONE, sal_False, pCnt );
709             if( !pLay ||
710                 (bVert && (pLay->Frm().Top() + pLay->Prt().Bottom()) <rPt.Y())||
711                 (!bVert && (pLay->Frm().Left() + pLay->Prt().Right())<rPt.X()) )
712             {
713                 // OD 26.09.2003 - <rPt> point is in left border of environment
714                 // --> OD 2009-01-12 #i70582#
715                 if( bVert )
716                 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
717                 {
718                     if ( bVertL2R )
719                         rRet.nMain = rPt.X() - nTopForObjPos;
720                     else
721                         rRet.nMain =  nTopForObjPos - rPt.X();
722                 }
723                 else
724                     rRet.nMain = rPt.Y() - nTopForObjPos;
725                 // <--
726                 return pCnt;
727             }
728             else
729                 rRet.nMain = LONG_MAX;
730         }
731         else
732         {
733             //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
734             // --> OD 2009-01-12 #i70582#
735             rRet.nMain = bVert
736                 ? ( bVertL2R
737                     ? ( (pUp->Frm().Left() + pUp->Prt().Right()) - nTopForObjPos )
738                     : ( nTopForObjPos - (pUp->Frm().Left() + pUp->Prt().Left() ) ) )
739                 : ( (pUp->Frm().Top() + pUp->Prt().Bottom()) - nTopForObjPos );
740 
741             const SwFrm *pPre = pCnt;
742             const SwFrm *pLay = pUp->GetLeaf( MAKEPAGE_NONE, sal_True, pCnt );
743             SwTwips nFrmTop = 0;
744             SwTwips nPrtHeight = 0;
745             sal_Bool bSct = sal_False;
746             const SwSectionFrm *pSect = pUp->FindSctFrm();
747             if( pSect )
748             {
749                 rRet.nSub = rRet.nMain;
750                 rRet.nMain = 0;
751             }
752             if( pSect && !pSect->IsAnLower( pLay ) )
753             {
754                 bSct = sal_False;
755                 const SwSectionFrm* pNxtSect = pLay ? pLay->FindSctFrm() : 0;
756                 if( pSect->IsAnFollow( pNxtSect ) )
757                 {
758                     if( pLay->IsVertical() )
759                     {
760                         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
761                         if ( pLay->IsVertLR() )
762                             nFrmTop = pLay->Frm().Left();
763                         else
764                             nFrmTop = pLay->Frm().Left() + pLay->Frm().Width();
765                         nPrtHeight = pLay->Prt().Width();
766                     }
767                     else
768                     {
769                         nFrmTop = pLay->Frm().Top();
770                         nPrtHeight = pLay->Prt().Height();
771                     }
772                     pSect = pNxtSect;
773                 }
774                 else
775                 {
776                     pLay = pSect->GetUpper();
777                     if( pLay->IsVertical() )
778                     {
779                         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
780                         if ( pLay->IsVertLR() )
781                         {
782                             nFrmTop = pSect->Frm().Right();
783                             nPrtHeight = pLay->Frm().Left() + pLay->Prt().Left()
784                                          + pLay->Prt().Width() - pSect->Frm().Left()
785                                          - pSect->Frm().Width();
786                          }
787                          else
788                          {
789                             nFrmTop = pSect->Frm().Left();
790                             nPrtHeight = pSect->Frm().Left() - pLay->Frm().Left()
791                                      - pLay->Prt().Left();
792                           }
793                     }
794                     else
795                     {
796                         nFrmTop = pSect->Frm().Bottom();
797                         nPrtHeight = pLay->Frm().Top() + pLay->Prt().Top()
798                                      + pLay->Prt().Height() - pSect->Frm().Top()
799                                      - pSect->Frm().Height();
800                     }
801                     pSect = 0;
802                 }
803             }
804             else if( pLay )
805             {
806                 if( pLay->IsVertical() )
807                 {
808                     //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
809                     if ( pLay->IsVertLR() )
810                     {
811                         nFrmTop = pLay->Frm().Left();
812                         nPrtHeight = pLay->Prt().Width();
813                     }
814                     else
815                     {
816                         nFrmTop = pLay->Frm().Left() + pLay->Frm().Width();
817                         nPrtHeight = pLay->Prt().Width();
818                     }
819                 }
820                 else
821                 {
822                     nFrmTop = pLay->Frm().Top();
823                     nPrtHeight = pLay->Prt().Height();
824                 }
825                 bSct = 0 != pSect;
826             }
827             while ( pLay && !pLay->Frm().IsInside( rPt ) &&
828                     ( pLay->Frm().Top() <= rPt.Y() || pLay->IsInFly() ||
829                       ( pLay->IsInSct() &&
830                       pLay->FindSctFrm()->GetUpper()->Frm().Top() <= rPt.Y())) )
831             {
832                 if ( pLay->IsFtnContFrm() )
833                 {
834                     if ( !((SwLayoutFrm*)pLay)->Lower() )
835                     {
836                         SwFrm *pDel = (SwFrm*)pLay;
837                         pDel->Cut();
838                         delete pDel;
839                         return pPre;
840                     }
841                     return 0;
842                 }
843                 else
844                 {
845                     if( bSct || pSect )
846                         rRet.nSub += nPrtHeight;
847                     else
848                         rRet.nMain += nPrtHeight;
849                     pPre = pLay;
850                     pLay = pLay->GetLeaf( MAKEPAGE_NONE, sal_True, pCnt );
851                     if( pSect && !pSect->IsAnLower( pLay ) )
852                     {   // If we're leaving a SwSectionFrm, the next Leaf-Frm
853                         // is the part of the upper below the SectionFrm.
854                         const SwSectionFrm* pNxtSect = pLay ?
855                             pLay->FindSctFrm() : NULL;
856                         bSct = sal_False;
857                         if( pSect->IsAnFollow( pNxtSect ) )
858                         {
859                             pSect = pNxtSect;
860                             if( pLay->IsVertical() )
861                             {
862                                 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
863                                 if ( pLay->IsVertLR() )
864                                 {
865                                     nFrmTop = pLay->Frm().Left();
866                                     nPrtHeight = pLay->Prt().Width();
867                                 }
868                                 else
869                                 {
870                                     nFrmTop = pLay->Frm().Left() + pLay->Frm().Width();
871                                     nPrtHeight = pLay->Prt().Width();
872                                 }
873                             }
874                             else
875                             {
876                                 nFrmTop = pLay->Frm().Top();
877                                 nPrtHeight = pLay->Prt().Height();
878                             }
879                         }
880                         else
881                         {
882                             pLay = pSect->GetUpper();
883                             if( pLay->IsVertical() )
884                             {
885                                 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
886                                 if ( pLay->IsVertLR() )
887                                 {
888                                     nFrmTop = pSect->Frm().Right();
889                                     nPrtHeight = pLay->Frm().Left()+pLay->Prt().Left()
890                                             + pLay->Prt().Width() - pSect->Frm().Left()
891                                             - pSect->Frm().Width();
892                                 }
893                                 else
894                                 {
895                                     nFrmTop = pSect->Frm().Left();
896                                     nPrtHeight = pSect->Frm().Left() -
897                                             pLay->Frm().Left() - pLay->Prt().Left();
898                                 }
899                             }
900                             else
901                             {
902                                 nFrmTop = pSect->Frm().Bottom();
903                                 nPrtHeight = pLay->Frm().Top()+pLay->Prt().Top()
904                                      + pLay->Prt().Height() - pSect->Frm().Top()
905                                      - pSect->Frm().Height();
906                             }
907                             pSect = 0;
908                         }
909                     }
910                     else if( pLay )
911                     {
912                         if( pLay->IsVertical() )
913                         {
914                              //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
915                              if ( pLay->IsVertLR() )
916                              {
917                                 nFrmTop = pLay->Frm().Left();
918                                 nPrtHeight = pLay->Prt().Width();
919                              }
920                              else
921                              {
922                                 nFrmTop = pLay->Frm().Left() + pLay->Frm().Width();
923                                 nPrtHeight = pLay->Prt().Width();
924                              }
925                         }
926                         else
927                         {
928                             nFrmTop = pLay->Frm().Top();
929                             nPrtHeight = pLay->Prt().Height();
930                         }
931                         bSct = 0 != pSect;
932                     }
933                 }
934             }
935             if ( pLay )
936             {
937                 if ( pLay->Frm().IsInside( rPt ) )
938                 {
939                     //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
940                     SwTwips nDiff = pLay->IsVertical() ? ( pLay->IsVertLR() ? ( rPt.X() - nFrmTop ) : ( nFrmTop - rPt.X() ) )
941                                                        : ( rPt.Y() - nFrmTop );
942                     if( bSct || pSect )
943                         rRet.nSub += nDiff;
944                     else
945                         rRet.nMain += nDiff;
946                 }
947                 if ( pLay->IsFtnContFrm() && !((SwLayoutFrm*)pLay)->Lower() )
948                 {
949                     SwFrm *pDel = (SwFrm*)pLay;
950                     pDel->Cut();
951                     delete pDel;
952                     return 0;
953                 }
954                 return pLay;
955             }
956             else
957                 rRet.nMain = LONG_MAX;
958         }
959     }
960     return 0;
961 }
962 
963 sal_uLong MA_FASTCALL lcl_FindCntDiff( const Point &rPt, const SwLayoutFrm *pLay,
964                           const SwCntntFrm *& rpCnt,
965                           const sal_Bool bBody, const sal_Bool bFtn )
966 {
967     //Sucht unterhalb von pLay den dichtesten Cnt zum Point. Der Bezugspunkt
968     //der Cntnts ist immer die linke obere Ecke.
969     //Der Cnt soll moeglichst ueber dem Point liegen.
970 
971 #if OSL_DEBUG_LEVEL > 1
972     Point arPoint( rPt );
973 #endif
974 
975     rpCnt = 0;
976     sal_uLong nDistance = ULONG_MAX;
977     sal_uLong nNearest  = ULONG_MAX;
978     const SwCntntFrm *pCnt = pLay->ContainsCntnt();
979 
980     while ( pCnt && (bBody != pCnt->IsInDocBody() || bFtn != pCnt->IsInFtn()))
981     {
982         pCnt = pCnt->GetNextCntntFrm();
983         if ( !pLay->IsAnLower( pCnt ) )
984             pCnt = 0;
985     }
986     const SwCntntFrm *pNearest = pCnt;
987     if ( pCnt )
988     {
989         do
990         {
991             //Jetzt die Entfernung zwischen den beiden Punkten berechnen.
992             //'Delta' X^2 + 'Delta'Y^2 = 'Entfernung'^2
993             sal_uInt32 dX = Max( pCnt->Frm().Left(), rPt.X() ) -
994                        Min( pCnt->Frm().Left(), rPt.X() ),
995                   dY = Max( pCnt->Frm().Top(), rPt.Y() ) -
996                        Min( pCnt->Frm().Top(), rPt.Y() );
997             BigInt dX1( dX ), dY1( dY );
998             dX1 *= dX1; dY1 *= dY1;
999             const sal_uLong nDiff = ::SqRt( dX1 + dY1 );
1000             if ( pCnt->Frm().Top() <= rPt.Y() )
1001             {
1002                 if ( nDiff < nDistance )
1003                 {   //Der ist dichter dran
1004                     nDistance = nNearest = nDiff;
1005                     rpCnt = pNearest = pCnt;
1006                 }
1007             }
1008             else if ( nDiff < nNearest )
1009             {
1010                 nNearest = nDiff;
1011                 pNearest = pCnt;
1012             }
1013             pCnt = pCnt->GetNextCntntFrm();
1014             while ( pCnt &&
1015                     (bBody != pCnt->IsInDocBody() || bFtn != pCnt->IsInFtn()))
1016                 pCnt = pCnt->GetNextCntntFrm();
1017 
1018         }  while ( pCnt && pLay->IsAnLower( pCnt ) );
1019     }
1020     if ( nDistance == ULONG_MAX )
1021     {   rpCnt = pNearest;
1022         return nNearest;
1023     }
1024     return nDistance;
1025 }
1026 
1027 const SwCntntFrm * MA_FASTCALL lcl_FindCnt( const Point &rPt, const SwCntntFrm *pCnt,
1028                                   const sal_Bool bBody, const sal_Bool bFtn )
1029 {
1030     //Sucht ausgehen von pCnt denjenigen CntntFrm, dessen linke obere
1031     //Ecke am dichtesten am Point liegt.
1032     //Liefert _immer_ einen CntntFrm zurueck.
1033 
1034     //Zunaechst wird versucht den dichtesten Cntnt innerhalt derjenigen
1035     //Seite zu suchen innerhalb derer der Cntnt steht.
1036     //Ausgehend von der Seite muessen die Seiten in beide
1037     //Richtungen beruecksichtigt werden.
1038     //Falls moeglich wird ein Cntnt geliefert, dessen Y-Position ueber der
1039     //des Point sitzt.
1040     const SwCntntFrm  *pRet, *pNew;
1041     const SwLayoutFrm *pLay = pCnt->FindPageFrm();
1042     sal_uLong nDist;
1043 
1044     nDist = ::lcl_FindCntDiff( rPt, pLay, pNew, bBody, bFtn );
1045     if ( pNew )
1046         pRet = pNew;
1047     else
1048     {   pRet  = pCnt;
1049         nDist = ULONG_MAX;
1050     }
1051     const SwCntntFrm *pNearest = pRet;
1052     sal_uLong nNearest = nDist;
1053 
1054     if ( pLay )
1055     {
1056         const SwLayoutFrm *pPge = pLay;
1057         sal_uLong nOldNew = ULONG_MAX;
1058         for ( sal_uInt16 i = 0; pPge->GetPrev() && (i < 3); ++i )
1059         {
1060             pPge = (SwLayoutFrm*)pPge->GetPrev();
1061             const sal_uLong nNew = ::lcl_FindCntDiff( rPt, pPge, pNew, bBody, bFtn );
1062             if ( nNew < nDist )
1063             {
1064                 if ( pNew->Frm().Top() <= rPt.Y() )
1065                 {
1066                     pRet = pNearest = pNew;
1067                     nDist = nNearest = nNew;
1068                 }
1069                 else if ( nNew < nNearest )
1070                 {
1071                     pNearest = pNew;
1072                     nNearest = nNew;
1073                 }
1074             }
1075             else if ( nOldNew != ULONG_MAX && nNew > nOldNew )
1076                 break;
1077             else
1078                 nOldNew = nNew;
1079 
1080         }
1081         pPge = pLay;
1082         nOldNew = ULONG_MAX;
1083         for ( sal_uInt16 j = 0; pPge->GetNext() && (j < 3); ++j )
1084         {
1085             pPge = (SwLayoutFrm*)pPge->GetNext();
1086             const sal_uLong nNew = ::lcl_FindCntDiff( rPt, pPge, pNew, bBody, bFtn );
1087             if ( nNew < nDist )
1088             {
1089                 if ( pNew->Frm().Top() <= rPt.Y() )
1090                 {
1091                     pRet = pNearest = pNew;
1092                     nDist = nNearest = nNew;
1093                 }
1094                 else if ( nNew < nNearest )
1095                 {
1096                     pNearest = pNew;
1097                     nNearest = nNew;
1098                 }
1099             }
1100             else if ( nOldNew != ULONG_MAX && nNew > nOldNew )
1101                 break;
1102             else
1103                 nOldNew = nNew;
1104         }
1105     }
1106     if ( (pRet->Frm().Top() > rPt.Y()) )
1107         return pNearest;
1108     else
1109         return pRet;
1110 }
1111 
1112 void lcl_PointToPrt( Point &rPoint, const SwFrm *pFrm )
1113 {
1114     SwRect aTmp( pFrm->Prt() );
1115     aTmp += pFrm->Frm().Pos();
1116     if ( rPoint.X() < aTmp.Left() )
1117         rPoint.X() = aTmp.Left();
1118     else if ( rPoint.X() > aTmp.Right() )
1119         rPoint.X() = aTmp.Right();
1120     if ( rPoint.Y() < aTmp.Top() )
1121         rPoint.Y() = aTmp.Top();
1122     else if ( rPoint.Y() > aTmp.Bottom() )
1123         rPoint.Y() = aTmp.Bottom();
1124 
1125 }
1126 
1127 const SwCntntFrm *FindAnchor( const SwFrm *pOldAnch, const Point &rNew,
1128                               const sal_Bool bBodyOnly )
1129 {
1130     //Zu der angegebenen DokumentPosition wird der dichteste Cnt im
1131     //Textfluss gesucht. AusgangsFrm ist der uebergebene Anker.
1132     const SwCntntFrm* pCnt;
1133     if ( pOldAnch->IsCntntFrm() )
1134     {
1135         pCnt = (const SwCntntFrm*)pOldAnch;
1136     }
1137     else
1138     {
1139         Point aTmp( rNew );
1140         SwLayoutFrm *pTmpLay = (SwLayoutFrm*)pOldAnch;
1141         if( pTmpLay->IsRootFrm() )
1142         {
1143             SwRect aTmpRect( aTmp, Size(0,0) );
1144             pTmpLay = (SwLayoutFrm*)::FindPage( aTmpRect, pTmpLay->Lower() );
1145         }
1146         pCnt = pTmpLay->GetCntntPos( aTmp, sal_False, bBodyOnly );
1147     }
1148 
1149     //Beim Suchen darauf achten, dass die Bereiche sinnvoll erhalten
1150     //bleiben. D.h. in diesem Fall nicht in Header/Footer hinein und
1151     //nicht aus Header/Footer hinaus.
1152     const sal_Bool bBody = pCnt->IsInDocBody() || bBodyOnly;
1153     const sal_Bool bFtn  = !bBodyOnly && pCnt->IsInFtn();
1154 
1155     Point aNew( rNew );
1156     if ( bBody )
1157     {
1158         //#38848 Vom Seitenrand in den Body ziehen.
1159         const SwFrm *pPage = pCnt->FindPageFrm();
1160         ::lcl_PointToPrt( aNew, pPage->GetUpper() );
1161         SwRect aTmp( aNew, Size( 0, 0 ) );
1162         pPage = ::FindPage( aTmp, pPage );
1163         ::lcl_PointToPrt( aNew, pPage );
1164     }
1165 
1166     if ( pCnt->IsInDocBody() == bBody && pCnt->Frm().IsInside( aNew ) )
1167         return pCnt;
1168     else if ( pOldAnch->IsInDocBody() || pOldAnch->IsPageFrm() )
1169     {
1170         //Vielleicht befindet sich der gewuenschte Anker ja auf derselben
1171         //Seite wie der aktuelle Anker.
1172         //So gibt es kein Problem mit Spalten.
1173         Point aTmp( aNew );
1174         const SwCntntFrm *pTmp = pCnt->FindPageFrm()->
1175                                         GetCntntPos( aTmp, sal_False, sal_True, sal_False );
1176         if ( pTmp && pTmp->Frm().IsInside( aNew ) )
1177             return pTmp;
1178     }
1179 
1180     //Ausgehend vom Anker suche ich jetzt in beide Richtungen bis ich
1181     //den jeweils dichtesten gefunden habe.
1182     //Nicht die direkte Entfernung ist relevant sondern die Strecke die
1183     //im Textfluss zurueckgelegt werden muss.
1184     const SwCntntFrm *pUpLst;
1185     const SwCntntFrm *pUpFrm = pCnt;
1186     SwDistance nUp, nUpLst;
1187     ::lcl_CalcDownDist( nUp, aNew, pUpFrm );
1188     SwDistance nDown = nUp;
1189     sal_Bool bNegAllowed = sal_True;//Einmal aus dem negativen Bereich heraus lassen.
1190     do
1191     {
1192         pUpLst = pUpFrm; nUpLst = nUp;
1193         pUpFrm = pUpLst->GetPrevCntntFrm();
1194         while ( pUpFrm &&
1195                 (bBody != pUpFrm->IsInDocBody() || bFtn != pUpFrm->IsInFtn()))
1196             pUpFrm = pUpFrm->GetPrevCntntFrm();
1197         if ( pUpFrm )
1198         {
1199             ::lcl_CalcDownDist( nUp, aNew, pUpFrm );
1200             //Wenn die Distanz innnerhalb einer Tabelle waechst, so lohnt es
1201             //sich weiter zu suchen.
1202             if ( pUpLst->IsInTab() && pUpFrm->IsInTab() )
1203             {
1204                 while ( pUpFrm && ((nUpLst < nUp && pUpFrm->IsInTab()) ||
1205                         bBody != pUpFrm->IsInDocBody()) )
1206                 {
1207                     pUpFrm = pUpFrm->GetPrevCntntFrm();
1208                     if ( pUpFrm )
1209                         ::lcl_CalcDownDist( nUp, aNew, pUpFrm );
1210                 }
1211             }
1212         }
1213         if ( !pUpFrm )
1214             nUp.nMain = LONG_MAX;
1215         if ( nUp.nMain >= 0 && LONG_MAX != nUp.nMain )
1216         {
1217             bNegAllowed = sal_False;
1218             if ( nUpLst.nMain < 0 ) //nicht den falschen erwischen, wenn der Wert
1219                                     //gerade von negativ auf positiv gekippt ist.
1220             {   pUpLst = pUpFrm;
1221                 nUpLst = nUp;
1222             }
1223         }
1224     } while ( pUpFrm && ( ( bNegAllowed && nUp.nMain < 0 ) || ( nUp <= nUpLst ) ) );
1225 
1226     const SwCntntFrm *pDownLst;
1227     const SwCntntFrm *pDownFrm = pCnt;
1228     SwDistance nDownLst;
1229     if ( nDown.nMain < 0 )
1230         nDown.nMain = LONG_MAX;
1231     do
1232     {
1233         pDownLst = pDownFrm; nDownLst = nDown;
1234         pDownFrm = pDownLst->GetNextCntntFrm();
1235         while ( pDownFrm &&
1236                 (bBody != pDownFrm->IsInDocBody() || bFtn != pDownFrm->IsInFtn()))
1237             pDownFrm = pDownFrm->GetNextCntntFrm();
1238         if ( pDownFrm )
1239         {
1240             ::lcl_CalcDownDist( nDown, aNew, pDownFrm );
1241             if ( nDown.nMain < 0 )
1242                 nDown.nMain = LONG_MAX;
1243             //Wenn die Distanz innnerhalb einer Tabelle waechst, so lohnt es
1244             //sich weiter zu suchen.
1245             if ( pDownLst->IsInTab() && pDownFrm->IsInTab() )
1246             {
1247                 while ( pDownFrm && ( ( nDown.nMain != LONG_MAX && nDownLst < nDownLst
1248                         && pDownFrm->IsInTab()) || bBody != pDownFrm->IsInDocBody() ) )
1249                 {
1250                     pDownFrm = pDownFrm->GetNextCntntFrm();
1251                     if ( pDownFrm )
1252                         ::lcl_CalcDownDist( nDown, aNew, pDownFrm );
1253                     if ( nDown.nMain < 0 )
1254                         nDown.nMain = LONG_MAX;
1255                 }
1256             }
1257         }
1258         if ( !pDownFrm )
1259             nDown.nMain = LONG_MAX;
1260 
1261     } while ( pDownFrm && nDown <= nDownLst &&
1262               nDown.nMain != LONG_MAX && nDownLst.nMain != LONG_MAX );
1263 
1264     //Wenn ich in beide Richtungen keinen gefunden habe, so suche ich mir
1265     //denjenigen Cntnt dessen linke obere Ecke dem Point am naechsten liegt.
1266     //Eine derartige Situation tritt z.b. auf, wenn der Point nicht im Text-
1267     //fluss sondern in irgendwelchen Raendern steht.
1268     if ( nDownLst.nMain == LONG_MAX && nUpLst.nMain == LONG_MAX )
1269     {
1270         // #102861# If an OLE objects, which is contained in a fly frame
1271         // is resized in inplace mode and the new Position is outside the
1272         // fly frame, we do not want to leave our fly frame.
1273         if ( pCnt->IsInFly() )
1274             return pCnt;
1275 
1276         return ::lcl_FindCnt( aNew, pCnt, bBody, bFtn );
1277     }
1278     else
1279         return nDownLst < nUpLst ? pDownLst : pUpLst;
1280 }
1281 
1282 /*************************************************************************
1283 |*
1284 |*  SwFlyAtCntFrm::SetAbsPos()
1285 |*
1286 |*  Ersterstellung      MA 22. Jun. 93
1287 |*  Letzte Aenderung    MA 11. Sep. 98
1288 |*
1289 |*************************************************************************/
1290 
1291 void SwFlyAtCntFrm::SetAbsPos( const Point &rNew )
1292 {
1293     SwPageFrm *pOldPage = FindPageFrm();
1294     const SwRect aOld( GetObjRectWithSpaces() );
1295     Point aNew( rNew );
1296     //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1297       if( ( GetAnchorFrm()->IsVertical() && !GetAnchorFrm()->IsVertLR() ) || GetAnchorFrm()->IsRightToLeft() )
1298         aNew.X() += Frm().Width();
1299     SwCntntFrm *pCnt = (SwCntntFrm*)::FindAnchor( GetAnchorFrm(), aNew );
1300     if( pCnt->IsProtected() )
1301         pCnt = (SwCntntFrm*)GetAnchorFrm();
1302 
1303     SwPageFrm *pTmpPage = 0;
1304     const bool bVert = pCnt->IsVertical();
1305     //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1306     const bool bVertL2R = pCnt->IsVertLR();
1307     const sal_Bool bRTL = pCnt->IsRightToLeft();
1308 
1309     if( ( !bVert != !GetAnchorFrm()->IsVertical() ) ||
1310         ( !bRTL !=  !GetAnchorFrm()->IsRightToLeft() ) )
1311     {
1312         if( bVert || bRTL )
1313             aNew.X() += Frm().Width();
1314         else
1315             aNew.X() -= Frm().Width();
1316     }
1317 
1318     if ( pCnt->IsInDocBody() )
1319     {
1320         //#38848 Vom Seitenrand in den Body ziehen.
1321         pTmpPage = pCnt->FindPageFrm();
1322         ::lcl_PointToPrt( aNew, pTmpPage->GetUpper() );
1323         SwRect aTmp( aNew, Size( 0, 0 ) );
1324         pTmpPage = (SwPageFrm*)::FindPage( aTmp, pTmpPage );
1325         ::lcl_PointToPrt( aNew, pTmpPage );
1326     }
1327 
1328     //RelPos einstellen, nur auf Wunsch invalidieren.
1329     //rNew ist eine Absolute Position. Um die RelPos korrekt einzustellen
1330     //muessen wir uns die Entfernung von rNew zum Anker im Textfluss besorgen.
1331 //!!!!!Hier kann Optimiert werden: FindAnchor koennte die RelPos mitliefern!
1332     const SwFrm *pFrm = 0;
1333     SwTwips nY;
1334     if ( pCnt->Frm().IsInside( aNew ) )
1335     {
1336         // --> OD 2009-01-12 #i70582#
1337         const SwTwips nTopForObjPos =
1338                 bVert
1339                 ? ( bVertL2R
1340                     ? ( pCnt->Frm().Left() +
1341                         pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() )
1342                     : ( pCnt->Frm().Left() +
1343                         pCnt->Frm().Width() -
1344                         pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() ) )
1345                 : ( pCnt->Frm().Top() +
1346                     pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() );
1347         if( bVert )
1348         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1349         {
1350             if ( bVertL2R )
1351                 nY = rNew.X() - nTopForObjPos;
1352             else
1353                 nY = nTopForObjPos - rNew.X() - Frm().Width();
1354         }
1355         else
1356         {
1357             nY = rNew.Y() - nTopForObjPos;
1358         }
1359         // <--
1360     }
1361     else
1362     {
1363         SwDistance aDist;
1364         pFrm = ::lcl_CalcDownDist( aDist, aNew, pCnt );
1365         nY = aDist.nMain + aDist.nSub;
1366     }
1367 
1368     SwTwips nX = 0;
1369 
1370     if ( pCnt->IsFollow() )
1371     {
1372         //Flys haengen niemals an einem Follow sondern immer am
1373         //Master, den suchen wir uns jetzt.
1374         const SwCntntFrm *pOriginal = pCnt;
1375         const SwCntntFrm *pFollow = pCnt;
1376         while ( pCnt->IsFollow() )
1377         {
1378             do
1379             {   pCnt = pCnt->GetPrevCntntFrm();
1380             } while ( pCnt->GetFollow() != pFollow );
1381             pFollow = pCnt;
1382         }
1383         SwTwips nDiff = 0;
1384         do
1385         {   const SwFrm *pUp = pFollow->GetUpper();
1386             if( pUp->IsVertical() )
1387             //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1388             {
1389                 if ( pUp->IsVertLR()  )
1390                     nDiff += pUp->Prt().Width() - pFollow->GetRelPos().X();
1391                 else
1392                     nDiff += pFollow->Frm().Left() + pFollow->Frm().Width()
1393                              - pUp->Frm().Left() - pUp->Prt().Left();
1394             }
1395             else
1396                 nDiff += pUp->Prt().Height() - pFollow->GetRelPos().Y();
1397             pFollow = pFollow->GetFollow();
1398         } while ( pFollow != pOriginal );
1399         nY += nDiff;
1400         if( bVert )
1401             nX = pCnt->Frm().Top() - pOriginal->Frm().Top();
1402         else
1403             nX = pCnt->Frm().Left() - pOriginal->Frm().Left();
1404     }
1405 
1406     if ( nY == LONG_MAX )
1407     {
1408         // --> OD 2009-01-12 #i70582#
1409         const SwTwips nTopForObjPos =
1410                 bVert
1411                 ? ( bVertL2R
1412                     ? ( pCnt->Frm().Left() +
1413                         pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() )
1414                     : ( pCnt->Frm().Left() +
1415                         pCnt->Frm().Width() -
1416                         pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() ) )
1417                 : ( pCnt->Frm().Top() +
1418                     pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() );
1419         if( bVert )
1420         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1421         {
1422             if ( bVertL2R )
1423                 nY = rNew.X() - nTopForObjPos;
1424             else
1425                 nY = nTopForObjPos - rNew.X();
1426         }
1427         else
1428         {
1429             nY = rNew.Y() - nTopForObjPos;
1430         }
1431         // <--
1432     }
1433 
1434     SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt();
1435     const SwFmtSurround& rSurround = pFmt->GetSurround();
1436     const sal_Bool bWrapThrough =
1437         rSurround.GetSurround() == SURROUND_THROUGHT;
1438     SwTwips nBaseOfstForFly = 0;
1439     const SwFrm* pTmpFrm = pFrm ? pFrm : pCnt;
1440     if ( pTmpFrm->IsTxtFrm() )
1441         nBaseOfstForFly =
1442             ((SwTxtFrm*)pTmpFrm)->GetBaseOfstForFly( !bWrapThrough );
1443 
1444     if( bVert )
1445     {
1446         if( !pFrm )
1447             nX += rNew.Y() - pCnt->Frm().Top() - nBaseOfstForFly;
1448         else
1449             nX = rNew.Y() - pFrm->Frm().Top() - nBaseOfstForFly;
1450     }
1451     else
1452     {
1453         if( !pFrm )
1454         {
1455             if ( pCnt->IsRightToLeft() )
1456                 nX += pCnt->Frm().Right() - rNew.X() - Frm().Width() +
1457                       nBaseOfstForFly;
1458             else
1459                 nX += rNew.X() - pCnt->Frm().Left() - nBaseOfstForFly;
1460         }
1461         else
1462         {
1463             if ( pFrm->IsRightToLeft() )
1464                 nX += pFrm->Frm().Right() - rNew.X() - Frm().Width() +
1465                       nBaseOfstForFly;
1466             else
1467                 nX = rNew.X() - pFrm->Frm().Left() - nBaseOfstForFly;
1468         }
1469     }
1470     GetFmt()->GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
1471 
1472     if( pCnt != GetAnchorFrm() || ( IsAutoPos() && pCnt->IsTxtFrm() &&
1473                                   GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::HTML_MODE)) )
1474     {
1475         //Das Ankerattribut auf den neuen Cnt setzen.
1476         SwFmtAnchor aAnch( pFmt->GetAnchor() );
1477         SwPosition *pPos = (SwPosition*)aAnch.GetCntntAnchor();
1478         if( IsAutoPos() && pCnt->IsTxtFrm() )
1479         {
1480             SwCrsrMoveState eTmpState( MV_SETONLYTEXT );
1481             Point aPt( rNew );
1482             if( pCnt->GetCrsrOfst( pPos, aPt, &eTmpState )
1483                 && pPos->nNode == *pCnt->GetNode() )
1484             {
1485                 ResetLastCharRectHeight();
1486                 if( text::RelOrientation::CHAR == pFmt->GetVertOrient().GetRelationOrient() )
1487                     nY = LONG_MAX;
1488                 if( text::RelOrientation::CHAR == pFmt->GetHoriOrient().GetRelationOrient() )
1489                     nX = LONG_MAX;
1490             }
1491             else
1492             {
1493                 pPos->nNode = *pCnt->GetNode();
1494                 pPos->nContent.Assign( pCnt->GetNode(), 0 );
1495             }
1496         }
1497         else
1498         {
1499             pPos->nNode = *pCnt->GetNode();
1500             pPos->nContent.Assign( pCnt->GetNode(), 0 );
1501         }
1502 
1503         // --> OD 2006-02-27 #125892#
1504         // handle change of anchor node:
1505         // if count of the anchor frame also change, the fly frames have to be
1506         // re-created. Thus, delete all fly frames except the <this> before the
1507         // anchor attribute is change and re-create them afterwards.
1508         {
1509             SwHandleAnchorNodeChg aHandleAnchorNodeChg( *pFmt, aAnch, this );
1510             pFmt->GetDoc()->SetAttr( aAnch, *pFmt );
1511         }
1512         // <--
1513     }
1514     // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
1515     else if ( pTmpPage && pTmpPage != GetPageFrm() )
1516         GetPageFrm()->MoveFly( this, pTmpPage );
1517 
1518     const Point aRelPos = bVert ? Point( -nY, nX ) : Point( nX, nY );
1519 
1520     ChgRelPos( aRelPos );
1521 
1522     GetFmt()->GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
1523 
1524     if ( pOldPage != FindPageFrm() )
1525         ::Notify_Background( GetVirtDrawObj(), pOldPage, aOld, PREP_FLY_LEAVE,
1526                              sal_False );
1527 }
1528 
1529 // OD 2004-08-12 #i32795# - Note: method no longer used in <flyincnt.cxx>
1530 //void DeepCalc( const SwFrm *pFrm )
1531 //{
1532 //    if( pFrm->IsSctFrm() ||
1533 //        ( pFrm->IsFlyFrm() && ((SwFlyFrm*)pFrm)->IsFlyInCntFrm() ) )
1534 //      return;
1535 //    const SwFlowFrm *pFlow = SwFlowFrm::CastFlowFrm( pFrm );
1536 //    if( pFlow && pFlow->IsAnyJoinLocked() )
1537 //        return;
1538 
1539 //    sal_uInt16 nCnt = 0;
1540 
1541 //  sal_Bool bContinue = sal_False;
1542 //  do
1543 //    {
1544 //        if ( ++nCnt == 10 )
1545 //      {
1546 //          ASSERT( !nCnt, "DeepCalc: Loop detected1?" );
1547 //          break;
1548 //      }
1549 
1550 //      const sal_Bool bSetComplete = !pFrm->IsValid();
1551 //      const SwRect aOldFrm( pFrm->Frm() );
1552 //      const SwRect aOldPrt( pFrm->Prt() );
1553 
1554 //      const SwFrm *pUp = pFrm->GetUpper();
1555 //      if ( pUp )
1556 //      {
1557 //          //Nicht weiter wenn der Up ein Fly mit Spalten ist.
1558 //          if( ( !pUp->IsFlyFrm() || !((SwLayoutFrm*)pUp)->Lower() ||
1559 //               !((SwLayoutFrm*)pUp)->Lower()->IsColumnFrm() ) &&
1560 //               !pUp->IsSctFrm() )
1561 //          {
1562 //                SWRECTFN( pUp )
1563 //                const Point aPt( (pUp->Frm().*fnRect->fnGetPos)() );
1564 //              ::DeepCalc( pUp );
1565 //                bContinue = aPt != (pUp->Frm().*fnRect->fnGetPos)();
1566 //          }
1567 //      }
1568 //      else
1569 //          pUp = pFrm;
1570 
1571 //      pFrm->Calc();
1572 //      if ( bSetComplete && (aOldFrm != pFrm->Frm() || aOldPrt != pFrm->Prt()))
1573 //          pFrm->SetCompletePaint();
1574 
1575 //      if ( pUp->IsFlyFrm() )
1576 //      {
1577 //          if ( ((SwFlyFrm*)pUp)->IsLocked() ||
1578 //               (((SwFlyFrm*)pUp)->IsFlyAtCntFrm() &&
1579 //                SwOszControl::IsInProgress( (const SwFlyFrm*)pUp )) )
1580 //          {
1581 //              bContinue = sal_False;
1582 //          }
1583 //      }
1584 //  } while ( bContinue );
1585 //}
1586 
1587 /** method to assure that anchored object is registered at the correct
1588     page frame
1589 
1590     OD 2004-07-02 #i28701#
1591     takes over functionality of deleted method <SwFlyAtCntFrm::AssertPage()>
1592 
1593     @author OD
1594 */
1595 void SwFlyAtCntFrm::RegisterAtCorrectPage()
1596 {
1597     SwPageFrm* pPageFrm( 0L );
1598     if ( GetVertPosOrientFrm() )
1599     {
1600         pPageFrm = const_cast<SwPageFrm*>(GetVertPosOrientFrm()->FindPageFrm());
1601     }
1602     if ( pPageFrm && GetPageFrm() != pPageFrm )
1603     {
1604         if ( GetPageFrm() )
1605             GetPageFrm()->MoveFly( this, pPageFrm );
1606         else
1607             pPageFrm->AppendFlyToPage( this );
1608     }
1609 }
1610 
1611 // OD 2004-03-23 #i26791#
1612 //void SwFlyAtCntFrm::MakeFlyPos()
1613 void SwFlyAtCntFrm::MakeObjPos()
1614 {
1615     // OD 02.10.2002 #102646#
1616     // if fly frame position is valid, nothing is to do. Thus, return
1617     if ( bValidPos )
1618     {
1619         return;
1620     }
1621 
1622     // OD 2004-03-24 #i26791# - validate position flag here.
1623     bValidPos = sal_True;
1624 
1625     // --> OD 2004-10-22 #i35911# - no calculation of new position, if
1626     // anchored object is marked that it clears its environment and its
1627     // environment is already cleared.
1628     // --> OD 2006-01-02 #125977# - before checking for cleared environment
1629     // check, if member <mpVertPosOrientFrm> is set.
1630     if ( GetVertPosOrientFrm() &&
1631          ClearedEnvironment() && HasClearedEnvironment() )
1632     {
1633         return;
1634     }
1635     // <--
1636 
1637     // OD 29.10.2003 #113049# - use new class to position object
1638     objectpositioning::SwToCntntAnchoredObjectPosition
1639             aObjPositioning( *GetVirtDrawObj() );
1640     aObjPositioning.CalcPosition();
1641 
1642     SetVertPosOrientFrm ( aObjPositioning.GetVertPosOrientFrm() );
1643 }
1644 
1645 // OD 2004-05-12 #i28701#
1646 bool SwFlyAtCntFrm::_InvalidationAllowed( const InvalidationType _nInvalid ) const
1647 {
1648     bool bAllowed( SwFlyFreeFrm::_InvalidationAllowed( _nInvalid ) );
1649 
1650     // forbiddance of base instance can't be over ruled.
1651     if ( bAllowed )
1652     {
1653         if ( _nInvalid == INVALID_POS ||
1654              _nInvalid == INVALID_ALL )
1655         {
1656             bAllowed = InvalidationOfPosAllowed();
1657         }
1658     }
1659 
1660     return bAllowed;
1661 }
1662