xref: /aoo4110/main/sw/source/core/layout/fly.cxx (revision b1cdbd2c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 #include "hintids.hxx"
27 #include <svl/itemiter.hxx>
28 #include <svtools/imap.hxx>
29 #include <vcl/graph.hxx>
30 #include <tools/poly.hxx>
31 #include <svx/contdlg.hxx>
32 #include <editeng/protitem.hxx>
33 #include <editeng/opaqitem.hxx>
34 #include <editeng/ulspitem.hxx>
35 #include <editeng/lrspitem.hxx>
36 #include <editeng/frmdiritem.hxx>
37 #include <editeng/keepitem.hxx>
38 #include <fmtanchr.hxx>
39 #include <fmtfsize.hxx>
40 #include <fmtclds.hxx>
41 #include <fmtcntnt.hxx>
42 #include <fmturl.hxx>
43 #include <fmtsrnd.hxx>
44 #include <fmtornt.hxx>
45 #include <fmtpdsc.hxx>
46 #include <fmtcnct.hxx>
47 #include <layhelp.hxx>
48 #include <ndtxt.hxx>
49 #include <svx/svdogrp.hxx>
50 #include <ndgrf.hxx>
51 #include <tolayoutanchoredobjectposition.hxx>
52 #include <fmtfollowtextflow.hxx>
53 #include <sortedobjs.hxx>
54 #include <objectformatter.hxx>
55 #include <anchoredobject.hxx>
56 #include <ndole.hxx>
57 #include <swtable.hxx>
58 #include <svx/svdpage.hxx>
59 #include "doc.hxx"
60 #include "viewsh.hxx"
61 #include "layouter.hxx"
62 #include "pagefrm.hxx"
63 #include "rootfrm.hxx"
64 #include "cntfrm.hxx"
65 #include "pam.hxx"
66 #include "frmatr.hxx"
67 #include "viewimp.hxx"
68 #include "viewopt.hxx"
69 #include "errhdl.hxx"
70 #include "dcontact.hxx"
71 #include "dflyobj.hxx"
72 #include "dview.hxx"
73 #include "flyfrm.hxx"
74 #include "frmtool.hxx"
75 #include "frmfmt.hxx"
76 #include "hints.hxx"
77 #include "swregion.hxx"
78 #include "tabfrm.hxx"
79 #include "txtfrm.hxx"
80 #include "ndnotxt.hxx"
81 #include "notxtfrm.hxx"   // GetGrfArea
82 #include "flyfrms.hxx"
83 #include "ndindex.hxx"   // GetGrfArea
84 #include "sectfrm.hxx"
85 #include <vcl/svapp.hxx>
86 #include <vcl/salbtype.hxx>		// FRound
87 #include "switerator.hxx"
88 
89 using namespace ::com::sun::star;
90 
91 
92 // OD 2004-03-23 #i26791
93 TYPEINIT2(SwFlyFrm,SwLayoutFrm,SwAnchoredObject);
94 
95 /*************************************************************************
96 |*
97 |*	SwFlyFrm::SwFlyFrm()
98 |*
99 |*	Ersterstellung		MA 28. Sep. 92
100 |*	Letzte Aenderung	MA 09. Apr. 99
101 |*
102 |*************************************************************************/
103 
SwFlyFrm(SwFlyFrmFmt * pFmt,SwFrm * pSib,SwFrm * pAnch)104 SwFlyFrm::SwFlyFrm( SwFlyFrmFmt *pFmt, SwFrm* pSib, SwFrm *pAnch ) :
105 	SwLayoutFrm( pFmt, pSib ),
106     // OD 2004-03-22 #i26791#
107     SwAnchoredObject(),
108     // OD 2004-05-27 #i26791# - moved to <SwAnchoredObject>
109 //    aRelPos(),
110 	pPrevLink( 0 ),
111 	pNextLink( 0 ),
112 	bInCnt( sal_False ),
113 	bAtCnt( sal_False ),
114 	bLayout( sal_False ),
115     bAutoPosition( sal_False ),
116     bNoShrink( sal_False ),
117     bLockDeleteContent( sal_False )
118 {
119     nType = FRMC_FLY;
120 
121 	bInvalid = bNotifyBack = sal_True;
122 	bLocked  = bMinHeight =
123 	bHeightClipped = bWidthClipped = bFormatHeightOnly = sal_False;
124 
125 	//Grosseneinstellung, Fixe groesse ist immer die Breite
126 	const SwFmtFrmSize &rFrmSize = pFmt->GetFrmSize();
127     sal_Bool bVert = sal_False;
128     sal_uInt16 nDir =
129         ((SvxFrameDirectionItem&)pFmt->GetFmtAttr( RES_FRAMEDIR )).GetValue();
130     if( FRMDIR_ENVIRONMENT == nDir )
131     {
132         bDerivedVert = 1;
133         bDerivedR2L = 1;
134         if( pAnch && pAnch->IsVertical() )
135             bVert = sal_True;
136     }
137     else
138     {
139         bInvalidVert = 0;
140         bDerivedVert = 0;
141         bDerivedR2L = 0;
142         if( FRMDIR_HORI_LEFT_TOP == nDir || FRMDIR_HORI_RIGHT_TOP == nDir )
143         {
144             //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
145             bVertLR = 0;
146             bVertical = 0;
147 		}
148         else
149         {
150             const ViewShell *pSh = getRootFrm() ? getRootFrm()->GetCurrShell() : 0;
151             if( pSh && pSh->GetViewOptions()->getBrowseMode() )
152             {
153                 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
154                 bVertLR = 0;
155                 bVertical = 0;
156             }
157             else
158             {
159                 bVertical = 1;
160                 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
161             	if ( FRMDIR_VERT_TOP_LEFT == nDir )
162                 	bVertLR = 1;
163                 else
164                 	bVertLR = 0;
165             }
166         }
167 
168         bVert = bVertical;
169         bInvalidR2L = 0;
170         if( FRMDIR_HORI_RIGHT_TOP == nDir )
171             bRightToLeft = 1;
172         else
173             bRightToLeft = 0;
174     }
175 
176     Frm().Width( rFrmSize.GetWidth() );
177     Frm().Height( rFrmSize.GetHeightSizeType() == ATT_VAR_SIZE ? MINFLY : rFrmSize.GetHeight() );
178 
179 	//Hoehe Fix oder Variabel oder was?
180     if ( rFrmSize.GetHeightSizeType() == ATT_MIN_SIZE )
181 		bMinHeight = sal_True;
182     else if ( rFrmSize.GetHeightSizeType() == ATT_FIX_SIZE )
183         bFixSize = sal_True;
184 
185     // OD 2004-02-12 #110582#-2 - insert columns, if necessary
186     InsertColumns();
187 
188 	//Erst das Init, dann den Inhalt, denn zum Inhalt koennen  widerum
189 	//Objekte/Rahmen gehoeren die dann angemeldet werden.
190     InitDrawObj( sal_False );
191 
192     // OD 2004-01-19 #110582#
193     Chain( pAnch );
194 
195     // OD 2004-01-19 #110582#
196     InsertCnt();
197 
198 	//Und erstmal in den Wald stellen die Kiste, damit bei neuen Dokument nicht
199 	//unnoetig viel formatiert wird.
200 	Frm().Pos().X() = Frm().Pos().Y() = WEIT_WECH;
201 }
202 
203 // OD 2004-01-19 #110582#
Chain(SwFrm * _pAnch)204 void SwFlyFrm::Chain( SwFrm* _pAnch )
205 {
206     // Connect to chain neighboors.
207     // No problem, if a neighboor doesn't exist - the construction of the
208     // neighboor will make the connection
209     const SwFmtChain& rChain = GetFmt()->GetChain();
210     if ( rChain.GetPrev() || rChain.GetNext() )
211     {
212         if ( rChain.GetNext() )
213         {
214             SwFlyFrm* pFollow = FindChainNeighbour( *rChain.GetNext(), _pAnch );
215             if ( pFollow )
216             {
217                 ASSERT( !pFollow->GetPrevLink(), "wrong chain detected" );
218                 if ( !pFollow->GetPrevLink() )
219                     SwFlyFrm::ChainFrames( this, pFollow );
220             }
221         }
222         if ( rChain.GetPrev() )
223         {
224             SwFlyFrm *pMaster = FindChainNeighbour( *rChain.GetPrev(), _pAnch );
225             if ( pMaster )
226             {
227                 ASSERT( !pMaster->GetNextLink(), "wrong chain detected" );
228                 if ( !pMaster->GetNextLink() )
229                     SwFlyFrm::ChainFrames( pMaster, this );
230             }
231         }
232     }
233 }
234 
235 // OD 2004-01-19 #110582#
InsertCnt()236 void SwFlyFrm::InsertCnt()
237 {
238     if ( !GetPrevLink() )
239     {
240         const SwFmtCntnt& rCntnt = GetFmt()->GetCntnt();
241         ASSERT( rCntnt.GetCntntIdx(), ":-( no content prepared." );
242         sal_uLong nIndex = rCntnt.GetCntntIdx()->GetIndex();
243         // Lower() bedeutet SwColumnFrm, eingefuegt werden muss der Inhalt dann in den (Column)BodyFrm
244         ::_InsertCnt( Lower() ? (SwLayoutFrm*)((SwLayoutFrm*)Lower())->Lower() : (SwLayoutFrm*)this,
245                       GetFmt()->GetDoc(), nIndex );
246 
247         //NoTxt haben immer eine FixHeight.
248         if ( Lower() && Lower()->IsNoTxtFrm() )
249         {
250             bFixSize = sal_True;
251             bMinHeight = sal_False;
252         }
253     }
254 }
255 
256  // OD 2004-02-12 #110582#-2
InsertColumns()257  void SwFlyFrm::InsertColumns()
258  {
259     // --> OD 2009-08-12 #i97379#
260     // Check, if column are allowed.
261     // Columns are not allowed for fly frames, which represent graphics or embedded objects.
262     const SwFmtCntnt& rCntnt = GetFmt()->GetCntnt();
263     ASSERT( rCntnt.GetCntntIdx(), "<SwFlyFrm::InsertColumns()> - no content prepared." );
264     SwNodeIndex aFirstCntnt( *(rCntnt.GetCntntIdx()), 1 );
265     if ( aFirstCntnt.GetNode().IsNoTxtNode() )
266     {
267         return;
268     }
269     // <--
270 
271     const SwFmtCol &rCol = GetFmt()->GetCol();
272     if ( rCol.GetNumCols() > 1 )
273     {
274         //PrtArea ersteinmal so gross wie der Frm, damit die Spalten
275         //vernuenftig eingesetzt werden koennen; das schaukelt sich dann
276         //schon zurecht.
277         Prt().Width( Frm().Width() );
278         Prt().Height( Frm().Height() );
279         const SwFmtCol aOld; //ChgColumns() verlaesst sich darauf, dass auch ein
280                              //Old-Wert hereingereicht wird.
281         ChgColumns( aOld, rCol );
282     }
283  }
284 
285 /*************************************************************************
286 |*
287 |*	SwFlyFrm::~SwFlyFrm()
288 |*
289 |*	Ersterstellung		MA 28. Sep. 92
290 |*	Letzte Aenderung	MA 07. Jul. 95
291 |*
292 |*************************************************************************/
293 
~SwFlyFrm()294 SwFlyFrm::~SwFlyFrm()
295 {
296 	// Accessible objects for fly frames will be destroyed in this destructor.
297 	// For frames bound as char or frames that don't have an anchor we have
298 	// to do that ourselves. For any other frame the call RemoveFly at the
299 	// anchor will do that.
300     if( IsAccessibleFrm() && GetFmt() && (IsFlyInCntFrm() || !GetAnchorFrm()) )
301 	{
302 		SwRootFrm *pRootFrm = getRootFrm();
303 		if( pRootFrm && pRootFrm->IsAnyShellAccessible() )
304 		{
305 			ViewShell *pVSh = pRootFrm->GetCurrShell();
306 			if( pVSh && pVSh->Imp() )
307 			{
308 				// Lowers aren't disposed already, so we have to do a recursive
309 				// dispose
310 				pVSh->Imp()->DisposeAccessibleFrm( this, sal_True );
311 			}
312 		}
313 	}
314 
315 	if( GetFmt() && !GetFmt()->GetDoc()->IsInDtor() )
316 	{
317         // OD 2004-01-19 #110582#
318         Unchain();
319 
320         // OD 2004-01-19 #110582#
321         DeleteCnt();
322 
323 		//Tschuess sagen.
324         if ( GetAnchorFrm() )
325             AnchorFrm()->RemoveFly( this );
326 	}
327 
328     FinitDrawObj();
329 }
330 
331 // OD 2004-01-19 #110582#
Unchain()332 void SwFlyFrm::Unchain()
333 {
334     if ( GetPrevLink() )
335         UnchainFrames( GetPrevLink(), this );
336     if ( GetNextLink() )
337         UnchainFrames( this, GetNextLink() );
338 }
339 
340 // OD 2004-01-19 #110582#
DeleteCnt()341 void SwFlyFrm::DeleteCnt()
342 {
343     // #110582#-2
344     if ( IsLockDeleteContent() )
345         return;
346 
347     SwFrm* pFrm = pLower;
348     while ( pFrm )
349     {
350         while ( pFrm->GetDrawObjs() && pFrm->GetDrawObjs()->Count() )
351         {
352             SwAnchoredObject *pAnchoredObj = (*pFrm->GetDrawObjs())[0];
353             if ( pAnchoredObj->ISA(SwFlyFrm) )
354                 delete pAnchoredObj;
355             else if ( pAnchoredObj->ISA(SwAnchoredDrawObject) )
356             {
357                 // OD 23.06.2003 #108784# - consider 'virtual' drawing objects
358                 SdrObject* pObj = pAnchoredObj->DrawObj();
359                 if ( pObj->ISA(SwDrawVirtObj) )
360                 {
361                     SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(pObj);
362                     pDrawVirtObj->RemoveFromWriterLayout();
363                     pDrawVirtObj->RemoveFromDrawingPage();
364                 }
365                 else
366                 {
367                     SwDrawContact* pContact =
368                             static_cast<SwDrawContact*>(::GetUserCall( pObj ));
369                     if ( pContact )
370                     {
371                         pContact->DisconnectFromLayout();
372                     }
373                 }
374             }
375         }
376 
377         pFrm->Remove();
378         delete pFrm;
379         pFrm = pLower;
380     }
381 
382     InvalidatePage();
383 }
384 
385 /*************************************************************************
386 |*
387 |*	SwFlyFrm::InitDrawObj()
388 |*
389 |*	Ersterstellung		MA 02. Dec. 94
390 |*	Letzte Aenderung	MA 30. Nov. 95
391 |*
392 |*************************************************************************/
393 
_GetOrdNumForNewRef(const SwFlyDrawContact * pContact)394 sal_uInt32 SwFlyFrm::_GetOrdNumForNewRef( const SwFlyDrawContact* pContact )
395 {
396     sal_uInt32 nOrdNum( 0L );
397 
398     // search for another Writer fly frame registered at same frame format
399     SwIterator<SwFlyFrm,SwFmt> aIter( *pContact->GetFmt() );
400     const SwFlyFrm* pFlyFrm( 0L );
401     for ( pFlyFrm = aIter.First(); pFlyFrm; pFlyFrm = aIter.Next() )
402     {
403         if ( pFlyFrm != this )
404         {
405             break;
406         }
407     }
408 
409     if ( pFlyFrm )
410     {
411         // another Writer fly frame found. Take its order number
412         nOrdNum = pFlyFrm->GetVirtDrawObj()->GetOrdNum();
413     }
414     else
415     {
416         // no other Writer fly frame found. Take order number of 'master' object
417         // --> OD 2004-11-11 #i35748# - use method <GetOrdNumDirect()> instead
418         // of method <GetOrdNum()> to avoid a recalculation of the order number,
419         // which isn't intended.
420         nOrdNum = pContact->GetMaster()->GetOrdNumDirect();
421         // <--
422     }
423 
424     return nOrdNum;
425 }
426 
CreateNewRef(SwFlyDrawContact * pContact)427 SwVirtFlyDrawObj* SwFlyFrm::CreateNewRef( SwFlyDrawContact *pContact )
428 {
429 	SwVirtFlyDrawObj *pDrawObj = new SwVirtFlyDrawObj( *pContact->GetMaster(), this );
430 	pDrawObj->SetModel( pContact->GetMaster()->GetModel() );
431 	pDrawObj->SetUserCall( pContact );
432 
433     //Der Reader erzeugt die Master und setzt diese, um die Z-Order zu
434 	//transportieren, in die Page ein. Beim erzeugen der ersten Referenz werden
435 	//die Master aus der Liste entfernt und fuehren von da an ein
436 	//Schattendasein.
437     SdrPage* pPg( 0L );
438 	if ( 0 != ( pPg = pContact->GetMaster()->GetPage() ) )
439 	{
440 		const sal_uInt32 nOrdNum = pContact->GetMaster()->GetOrdNum();
441 		pPg->ReplaceObject( pDrawObj, nOrdNum );
442 	}
443     // --> OD 2004-08-16 #i27030# - insert new <SwVirtFlyDrawObj> instance
444     // into drawing page with correct order number
445     else
446     {
447         pContact->GetFmt()->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage( 0 )->
448                         InsertObject( pDrawObj, _GetOrdNumForNewRef( pContact ) );
449     }
450     // <--
451     // --> OD 2004-12-13 #i38889# - assure, that new <SwVirtFlyDrawObj> instance
452     // is in a visible layer.
453     pContact->MoveObjToVisibleLayer( pDrawObj );
454     // <--
455     return pDrawObj;
456 }
457 
458 
459 
InitDrawObj(sal_Bool bNotify)460 void SwFlyFrm::InitDrawObj( sal_Bool bNotify )
461 {
462 	//ContactObject aus dem Format suchen. Wenn bereits eines existiert, so
463 	//braucht nur eine neue Ref erzeugt werden, anderfalls ist es jetzt an
464 	//der Zeit das Contact zu erzeugen.
465 
466     IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess();
467 	SwFlyDrawContact *pContact = SwIterator<SwFlyDrawContact,SwFmt>::FirstElement( *GetFmt() );
468 	if ( !pContact )
469     {
470         // --> OD 2005-08-08 #i52858# - method name changed
471 		pContact = new SwFlyDrawContact( (SwFlyFrmFmt*)GetFmt(),
472                                           pIDDMA->GetOrCreateDrawModel() );
473         // <--
474     }
475 	ASSERT( pContact, "InitDrawObj failed" );
476     // OD 2004-03-22 #i26791#
477     SetDrawObj( *(CreateNewRef( pContact )) );
478 
479     //Den richtigen Layer setzen.
480     // OD 2004-01-19 #110582#
481     SdrLayerID nHeavenId = pIDDMA->GetHeavenId();
482     SdrLayerID nHellId = pIDDMA->GetHellId();
483     // OD 2004-03-22 #i26791#
484     GetVirtDrawObj()->SetLayer( GetFmt()->GetOpaque().GetValue()
485                                 ? nHeavenId
486                                 : nHellId );
487 	if ( bNotify )
488 		NotifyDrawObj();
489 }
490 
491 /*************************************************************************
492 |*
493 |*	SwFlyFrm::FinitDrawObj()
494 |*
495 |*	Ersterstellung		MA 12. Dec. 94
496 |*	Letzte Aenderung	MA 15. May. 95
497 |*
498 |*************************************************************************/
499 
FinitDrawObj()500 void SwFlyFrm::FinitDrawObj()
501 {
502     if ( !GetVirtDrawObj() )
503 		return;
504 
505 	//Bei den SdrPageViews abmelden falls das Objekt dort noch selektiert ist.
506 	if ( !GetFmt()->GetDoc()->IsInDtor() )
507 	{
508 		ViewShell *p1St = getRootFrm()->GetCurrShell();
509 		if ( p1St )
510 		{
511 			ViewShell *pSh = p1St;
512 			do
513 			{	//z.Zt. kann das Drawing nur ein Unmark auf alles, weil das
514 				//Objekt bereits Removed wurde.
515 				if( pSh->HasDrawView() )
516 					pSh->Imp()->GetDrawView()->UnmarkAll();
517 				pSh = (ViewShell*)pSh->GetNext();
518 
519 			} while ( pSh != p1St );
520 		}
521 	}
522 
523 	//VirtObject mit in das Grab nehmen. Wenn das letzte VirObject
524 	//zerstoert wird, mussen das DrawObject und DrawContact ebenfalls
525 	//zerstoert werden.
526 	SwFlyDrawContact *pMyContact = 0;
527 	if ( GetFmt() )
528 	{
529         bool bContinue = true;
530         SwIterator<SwFrm,SwFmt> aFrmIter( *GetFmt() );
531         for ( SwFrm* pFrm = aFrmIter.First(); pFrm; pFrm = aFrmIter.Next() )
532             if ( pFrm != this )
533             {
534                 // don't delete Contact if there is still a Frm
535                 bContinue = false;
536                 break;
537             }
538 
539         if ( bContinue )
540             // no Frm left, find Contact object to destroy
541             pMyContact = SwIterator<SwFlyDrawContact,SwFmt>::FirstElement( *GetFmt() );
542 	}
543 
544     // OD, OS 2004-03-31 #116203# - clear user call of Writer fly frame 'master'
545     // <SdrObject> to assure, that a <SwXFrame::dispose()> doesn't delete the
546     // Writer fly frame again.
547     if ( pMyContact )
548     {
549         pMyContact->GetMaster()->SetUserCall( 0 );
550     }
551     GetVirtDrawObj()->SetUserCall( 0 ); //Ruft sonst Delete des ContactObj
552     delete GetVirtDrawObj();			//Meldet sich selbst beim Master ab.
553 	if ( pMyContact )
554 		delete pMyContact;		//zerstoert den Master selbst.
555 }
556 
557 /*************************************************************************
558 |*
559 |*	SwFlyFrm::ChainFrames()
560 |*
561 |*	Ersterstellung		MA 29. Oct. 97
562 |*	Letzte Aenderung	MA 20. Jan. 98
563 |*
564 |*************************************************************************/
565 
ChainFrames(SwFlyFrm * pMaster,SwFlyFrm * pFollow)566 void SwFlyFrm::ChainFrames( SwFlyFrm *pMaster, SwFlyFrm *pFollow )
567 {
568 	ASSERT( pMaster && pFollow, "uncomplete chain" );
569 	ASSERT( !pMaster->GetNextLink(), "link can not be changed" );
570 	ASSERT( !pFollow->GetPrevLink(), "link can not be changed" );
571 
572 	pMaster->pNextLink = pFollow;
573 	pFollow->pPrevLink = pMaster;
574 
575 	if ( pMaster->ContainsCntnt() )
576 	{
577 		//Damit ggf. ein Textfluss zustande kommt muss invalidiert werden.
578 		SwFrm *pInva = pMaster->FindLastLower();
579         SWRECTFN( pMaster )
580         const long nBottom = (pMaster->*fnRect->fnGetPrtBottom)();
581 		while ( pInva )
582 		{
583             if( (pInva->Frm().*fnRect->fnBottomDist)( nBottom ) <= 0 )
584 			{
585 				pInva->InvalidateSize();
586 				pInva->Prepare( PREP_CLEAR );
587 				pInva = pInva->FindPrev();
588 			}
589 			else
590 				pInva = 0;
591 		}
592 	}
593 
594 	if ( pFollow->ContainsCntnt() )
595 	{
596 		//Es gibt nur noch den Inhalt des Masters, der Inhalt vom Follow
597 		//hat keine Frames mehr (sollte immer nur genau ein leerer TxtNode sein).
598 		SwFrm *pFrm = pFollow->ContainsCntnt();
599 		ASSERT( !pFrm->IsTabFrm() && !pFrm->FindNext(), "follow in chain contains content" );
600 		pFrm->Cut();
601 		delete pFrm;
602 	}
603 
604     // invalidate accessible relation set (accessibility wrapper)
605     ViewShell* pSh = pMaster->getRootFrm()->GetCurrShell();
606     if( pSh )
607     {
608         SwRootFrm* pLayout = pMaster->getRootFrm();
609         if( pLayout && pLayout->IsAnyShellAccessible() )
610         pSh->Imp()->InvalidateAccessibleRelationSet( pMaster, pFollow );
611     }
612 }
613 
UnchainFrames(SwFlyFrm * pMaster,SwFlyFrm * pFollow)614 void SwFlyFrm::UnchainFrames( SwFlyFrm *pMaster, SwFlyFrm *pFollow )
615 {
616 	pMaster->pNextLink = 0;
617 	pFollow->pPrevLink = 0;
618 
619 	if ( pFollow->ContainsCntnt() )
620 	{
621 		//Der Master saugt den Inhalt vom Follow auf
622 		SwLayoutFrm *pUpper = pMaster;
623 		if ( pUpper->Lower()->IsColumnFrm() )
624 		{
625             pUpper = static_cast<SwLayoutFrm*>(pUpper->GetLastLower());
626             pUpper = static_cast<SwLayoutFrm*>(pUpper->Lower()); // der (Column)BodyFrm
627 			ASSERT( pUpper && pUpper->IsColBodyFrm(), "Missing ColumnBody" );
628 		}
629 		SwFlyFrm *pFoll = pFollow;
630 		while ( pFoll )
631 		{
632 			SwFrm *pTmp = ::SaveCntnt( pFoll );
633 			if ( pTmp )
634                 ::RestoreCntnt( pTmp, pUpper, pMaster->FindLastLower(), true );
635             pFoll->SetCompletePaint();
636 			pFoll->InvalidateSize();
637 			pFoll = pFoll->GetNextLink();
638 		}
639 	}
640 
641 	//Der Follow muss mit seinem eigenen Inhalt versorgt werden.
642 	const SwFmtCntnt &rCntnt = pFollow->GetFmt()->GetCntnt();
643 	ASSERT( rCntnt.GetCntntIdx(), ":-( Kein Inhalt vorbereitet." );
644 	sal_uLong nIndex = rCntnt.GetCntntIdx()->GetIndex();
645 	// Lower() bedeutet SwColumnFrm, dieser beinhaltet wieder einen SwBodyFrm
646 	::_InsertCnt( pFollow->Lower() ? (SwLayoutFrm*)((SwLayoutFrm*)pFollow->Lower())->Lower()
647 								   : (SwLayoutFrm*)pFollow,
648 				  pFollow->GetFmt()->GetDoc(), ++nIndex );
649 
650     // invalidate accessible relation set (accessibility wrapper)
651     ViewShell* pSh = pMaster->getRootFrm()->GetCurrShell();
652     if( pSh )
653     {
654         SwRootFrm* pLayout = pMaster->getRootFrm();
655         if( pLayout && pLayout->IsAnyShellAccessible() )
656         pSh->Imp()->InvalidateAccessibleRelationSet( pMaster, pFollow );
657 }
658 }
659 
660 /*************************************************************************
661 |*
662 |*	SwFlyFrm::FindChainNeighbour()
663 |*
664 |*	Ersterstellung		MA 11. Nov. 97
665 |*	Letzte Aenderung	MA 09. Apr. 99
666 |*
667 |*************************************************************************/
668 
FindChainNeighbour(SwFrmFmt & rChain,SwFrm * pAnch)669 SwFlyFrm *SwFlyFrm::FindChainNeighbour( SwFrmFmt &rChain, SwFrm *pAnch )
670 {
671 	//Wir suchen denjenigen Fly, der in dem selben Bereich steht.
672 	//Bereiche koennen zunaechst nur Kopf-/Fusszeilen oder Flys sein.
673 
674 	if ( !pAnch )			//Wenn ein Anchor uebergeben Wurde zaehlt dieser: Ctor!
675         pAnch = AnchorFrm();
676 
677 	SwLayoutFrm *pLay;
678 	if ( pAnch->IsInFly() )
679 		pLay = pAnch->FindFlyFrm();
680 	else
681 	{
682 		//FindFooterOrHeader taugt hier nicht, weil evtl. noch keine Verbindung
683 		//zum Anker besteht.
684 		pLay = pAnch->GetUpper();
685 		while ( pLay && !(pLay->GetType() & (FRM_HEADER|FRM_FOOTER)) )
686 			pLay = pLay->GetUpper();
687 	}
688 
689 	SwIterator<SwFlyFrm,SwFmt> aIter( rChain );
690 	SwFlyFrm *pFly = aIter.First();
691 	if ( pLay )
692 	{
693 		while ( pFly )
694 		{
695             if ( pFly->GetAnchorFrm() )
696 			{
697                 if ( pFly->GetAnchorFrm()->IsInFly() )
698 				{
699                     if ( pFly->AnchorFrm()->FindFlyFrm() == pLay )
700 						break;
701 				}
702 				else if ( pLay == pFly->FindFooterOrHeader() )
703 					break;
704 			}
705 			pFly = aIter.Next();
706 		}
707 	}
708 	else if ( pFly )
709 	{
710 		ASSERT( !aIter.Next(), "chain with more than one inkarnation" );
711 	}
712 	return pFly;
713 }
714 
715 
716 /*************************************************************************
717 |*
718 |*	SwFlyFrm::FindLastLower()
719 |*
720 |*	Ersterstellung		MA 29. Oct. 97
721 |*	Letzte Aenderung	MA 29. Oct. 97
722 |*
723 |*************************************************************************/
724 
FindLastLower()725 SwFrm *SwFlyFrm::FindLastLower()
726 {
727 	SwFrm *pRet = ContainsAny();
728 	if ( pRet && pRet->IsInTab() )
729 		pRet = pRet->FindTabFrm();
730 	SwFrm *pNxt = pRet;
731 	while ( pNxt && IsAnLower( pNxt ) )
732 	{	pRet = pNxt;
733 		pNxt = pNxt->FindNext();
734 	}
735 	return pRet;
736 }
737 
738 
739 /*************************************************************************
740 |*
741 |*	SwFlyFrm::FrmSizeChg()
742 |*
743 |*	Ersterstellung		MA 17. Dec. 92
744 |*	Letzte Aenderung	MA 24. Jul. 96
745 |*
746 |*************************************************************************/
747 
FrmSizeChg(const SwFmtFrmSize & rFrmSize)748 sal_Bool SwFlyFrm::FrmSizeChg( const SwFmtFrmSize &rFrmSize )
749 {
750 	sal_Bool bRet = sal_False;
751 	SwTwips nDiffHeight = Frm().Height();
752     if ( rFrmSize.GetHeightSizeType() == ATT_VAR_SIZE )
753         bFixSize = bMinHeight = sal_False;
754 	else
755 	{
756         if ( rFrmSize.GetHeightSizeType() == ATT_FIX_SIZE )
757         {
758             bFixSize = sal_True;
759 			bMinHeight = sal_False;
760 		}
761         else if ( rFrmSize.GetHeightSizeType() == ATT_MIN_SIZE )
762         {
763             bFixSize = sal_False;
764 			bMinHeight = sal_True;
765 		}
766 		nDiffHeight -= rFrmSize.GetHeight();
767 	}
768 	//Wenn der Fly Spalten enthaehlt muessen der Fly und
769 	//die Spalten schon einmal auf die Wunschwerte gebracht
770 	//werden, sonst haben wir ein kleines Problem.
771 	if ( Lower() )
772 	{
773 		if ( Lower()->IsColumnFrm() )
774 		{
775             const SwRect aOld( GetObjRectWithSpaces() );
776 			const Size	 aOldSz( Prt().SSize() );
777 			const SwTwips nDiffWidth = Frm().Width() - rFrmSize.GetWidth();
778 			aFrm.Height( aFrm.Height() - nDiffHeight );
779 			aFrm.Width ( aFrm.Width()  - nDiffWidth  );
780             // --> OD 2006-08-16 #i68520#
781             InvalidateObjRectWithSpaces();
782             // <--
783 			aPrt.Height( aPrt.Height() - nDiffHeight );
784 			aPrt.Width ( aPrt.Width()  - nDiffWidth  );
785 			ChgLowersProp( aOldSz );
786 			::Notify( this, FindPageFrm(), aOld );
787 			bValidPos = sal_False;
788 			bRet = sal_True;
789 		}
790 		else if ( Lower()->IsNoTxtFrm() )
791 		{
792             bFixSize = sal_True;
793 			bMinHeight = sal_False;
794 		}
795 	}
796 	return bRet;
797 }
798 
799 /*************************************************************************
800 |*
801 |*	SwFlyFrm::Modify()
802 |*
803 |*	Ersterstellung		MA 17. Dec. 92
804 |*	Letzte Aenderung	MA 17. Jan. 97
805 |*
806 |*************************************************************************/
807 
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)808 void SwFlyFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew )
809 {
810 	sal_uInt8 nInvFlags = 0;
811 
812 	if( pNew && RES_ATTRSET_CHG == pNew->Which() )
813 	{
814 		SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
815 		SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
816 		SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
817 		SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
818 		while( sal_True )
819 		{
820 			_UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(),
821 						 (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags,
822 						 &aOldSet, &aNewSet );
823 			if( aNIter.IsAtEnd() )
824 				break;
825 			aNIter.NextItem();
826 			aOIter.NextItem();
827 		}
828 		if ( aOldSet.Count() || aNewSet.Count() )
829 			SwLayoutFrm::Modify( &aOldSet, &aNewSet );
830 	}
831 	else
832 		_UpdateAttr( pOld, pNew, nInvFlags );
833 
834 	if ( nInvFlags != 0 )
835 	{
836 		_Invalidate();
837 		if ( nInvFlags & 0x01 )
838         {
839 			_InvalidatePos();
840             // --> OD 2006-08-16 #i68520#
841             InvalidateObjRectWithSpaces();
842             // <--
843         }
844 		if ( nInvFlags & 0x02 )
845         {
846 			_InvalidateSize();
847             // --> OD 2006-08-16 #i68520#
848             InvalidateObjRectWithSpaces();
849             // <--
850         }
851         if ( nInvFlags & 0x04 )
852 			_InvalidatePrt();
853 		if ( nInvFlags & 0x08 )
854 			SetNotifyBack();
855 		if ( nInvFlags & 0x10 )
856 			SetCompletePaint();
857 		if ( ( nInvFlags & 0x40 ) && Lower() && Lower()->IsNoTxtFrm() )
858             ClrContourCache( GetVirtDrawObj() );
859 		SwRootFrm *pRoot;
860 		if ( nInvFlags & 0x20 && 0 != (pRoot = getRootFrm()) )
861 			pRoot->InvalidateBrowseWidth();
862         // --> OD 2004-06-28 #i28701#
863         if ( nInvFlags & 0x80 )
864         {
865             // update sorted object lists, the Writer fly frame is registered at.
866             UpdateObjInSortedList();
867         }
868         // <--
869         // --> OD #i87645# - reset flags for the layout process (only if something has been invalidated)
870         ResetLayoutProcessBools();
871         // <--
872 	}
873 }
874 
_UpdateAttr(const SfxPoolItem * pOld,const SfxPoolItem * pNew,sal_uInt8 & rInvFlags,SwAttrSetChg * pOldSet,SwAttrSetChg * pNewSet)875 void SwFlyFrm::_UpdateAttr( const SfxPoolItem *pOld, const SfxPoolItem *pNew,
876 							sal_uInt8 &rInvFlags,
877 							SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
878 {
879 	sal_Bool bClear = sal_True;
880 	const sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
881 	ViewShell *pSh = getRootFrm()->GetCurrShell();
882 	switch( nWhich )
883 	{
884         case RES_VERT_ORIENT:
885 		case RES_HORI_ORIENT:
886         // OD 22.09.2003 #i18732# - consider new option 'follow text flow'
887         case RES_FOLLOW_TEXT_FLOW:
888         {
889             //Achtung! _immer_ Aktion in ChgRePos() mitpflegen.
890 			rInvFlags |= 0x09;
891         }
892         break;
893         // OD 2004-07-01 #i28701# - consider new option 'wrap influence on position'
894         case RES_WRAP_INFLUENCE_ON_OBJPOS:
895         {
896             rInvFlags |= 0x89;
897         }
898         break;
899         case RES_SURROUND:
900         {
901             // OD 2004-05-13 #i28701# - invalidate position on change of
902             // wrapping style.
903             //rInvFlags |= 0x40;
904             rInvFlags |= 0x41;
905 			//Der Hintergrund muss benachrichtigt und Invalidiert werden.
906             const SwRect aTmp( GetObjRectWithSpaces() );
907 			NotifyBackground( FindPageFrm(), aTmp, PREP_FLY_ATTR_CHG );
908 
909 			// Durch eine Umlaufaenderung von rahmengebundenen Rahmen kann eine
910 			// vertikale Ausrichtung aktiviert/deaktiviert werden => MakeFlyPos
911 			if( FLY_AT_FLY == GetFmt()->GetAnchor().GetAnchorId() )
912 				rInvFlags |= 0x09;
913 
914 			//Ggf. die Kontur am Node loeschen.
915 			if ( Lower() && Lower()->IsNoTxtFrm() &&
916 				 !GetFmt()->GetSurround().IsContour() )
917 			{
918 				SwNoTxtNode *pNd = (SwNoTxtNode*)((SwCntntFrm*)Lower())->GetNode();
919 				if ( pNd->HasContour() )
920 					pNd->SetContour( 0 );
921 			}
922             // --> OD 2004-06-28 #i28701# - perform reorder of object lists
923             // at anchor frame and at page frame.
924             rInvFlags |= 0x80;
925         }
926         break;
927 
928 		case RES_PROTECT:
929 			{
930 			const SvxProtectItem *pP = (SvxProtectItem*)pNew;
931             GetVirtDrawObj()->SetMoveProtect( pP->IsPosProtected()   );
932             GetVirtDrawObj()->SetResizeProtect( pP->IsSizeProtected() );
933             if( pSh )
934             {
935                 SwRootFrm* pLayout = getRootFrm();
936                 if( pLayout && pLayout->IsAnyShellAccessible() )
937 				pSh->Imp()->InvalidateAccessibleEditableState( sal_True, this );
938             }
939 			break;
940 			}
941 
942 		case RES_COL:
943 			{
944 				ChgColumns( *(const SwFmtCol*)pOld, *(const SwFmtCol*)pNew );
945 				const SwFmtFrmSize &rNew = GetFmt()->GetFrmSize();
946 				if ( FrmSizeChg( rNew ) )
947 					NotifyDrawObj();
948 				rInvFlags |= 0x1A;
949 				break;
950 			}
951 
952 		case RES_FRM_SIZE:
953 		case RES_FMT_CHG:
954 		{
955 			const SwFmtFrmSize &rNew = GetFmt()->GetFrmSize();
956 			if ( FrmSizeChg( rNew ) )
957 				NotifyDrawObj();
958 			rInvFlags |= 0x7F;
959 			if ( RES_FMT_CHG == nWhich )
960 			{
961                 SwRect aNew( GetObjRectWithSpaces() );
962 				SwRect aOld( aFrm );
963 				const SvxULSpaceItem &rUL = ((SwFmtChg*)pOld)->pChangedFmt->GetULSpace();
964 				aOld.Top( Max( aOld.Top() - long(rUL.GetUpper()), 0L ) );
965 				aOld.SSize().Height()+= rUL.GetLower();
966 				const SvxLRSpaceItem &rLR = ((SwFmtChg*)pOld)->pChangedFmt->GetLRSpace();
967 				aOld.Left  ( Max( aOld.Left() - long(rLR.GetLeft()), 0L ) );
968 				aOld.SSize().Width() += rLR.GetRight();
969 				aNew.Union( aOld );
970 				NotifyBackground( FindPageFrm(), aNew, PREP_CLEAR );
971 
972 				//Dummer Fall. Bei der Zusweisung einer Vorlage k?nnen wir uns
973 				//nicht auf das alte Spaltenattribut verlassen. Da diese
974 				//wenigstens anzahlgemass fuer ChgColumns vorliegen muessen,
975 				//bleibt uns nur einen temporaeres Attribut zu basteln.
976 				SwFmtCol aCol;
977 				if ( Lower() && Lower()->IsColumnFrm() )
978 				{
979 					sal_uInt16 nCol = 0;
980 					SwFrm *pTmp = Lower();
981 					do
982 					{	++nCol;
983 						pTmp = pTmp->GetNext();
984 					} while ( pTmp );
985 					aCol.Init( nCol, 0, 1000 );
986 				}
987 				ChgColumns( aCol, GetFmt()->GetCol() );
988 			}
989 
990 			SwFmtURL aURL( GetFmt()->GetURL() );
991 			if ( aURL.GetMap() )
992 			{
993 				const SwFmtFrmSize &rOld = nWhich == RES_FRM_SIZE ?
994 								*(SwFmtFrmSize*)pNew :
995 								((SwFmtChg*)pOld)->pChangedFmt->GetFrmSize();
996 				//#35091# Kann beim Laden von Vorlagen mal 0 sein
997 				if ( rOld.GetWidth() && rOld.GetHeight() )
998 				{
999 
1000 					Fraction aScaleX( rOld.GetWidth(), rNew.GetWidth() );
1001 					Fraction aScaleY( rOld.GetHeight(), rOld.GetHeight() );
1002 					aURL.GetMap()->Scale( aScaleX, aScaleY );
1003 					SwFrmFmt *pFmt = GetFmt();
1004 					pFmt->LockModify();
1005                     pFmt->SetFmtAttr( aURL );
1006 					pFmt->UnlockModify();
1007 				}
1008 			}
1009 			const SvxProtectItem &rP = GetFmt()->GetProtect();
1010             GetVirtDrawObj()->SetMoveProtect( rP.IsPosProtected()    );
1011             GetVirtDrawObj()->SetResizeProtect( rP.IsSizeProtected() );
1012 
1013 			if ( pSh )
1014 				pSh->InvalidateWindows( Frm() );
1015             const IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess();
1016 			const sal_uInt8 nId = GetFmt()->GetOpaque().GetValue() ?
1017                              pIDDMA->GetHeavenId() :
1018                              pIDDMA->GetHellId();
1019             GetVirtDrawObj()->SetLayer( nId );
1020 
1021 			if ( Lower() )
1022 			{
1023 				//Ggf. die Kontur am Node loeschen.
1024 				if( Lower()->IsNoTxtFrm() &&
1025 					 !GetFmt()->GetSurround().IsContour() )
1026 				{
1027 					SwNoTxtNode *pNd = (SwNoTxtNode*)((SwCntntFrm*)Lower())->GetNode();
1028 					if ( pNd->HasContour() )
1029 						pNd->SetContour( 0 );
1030 				}
1031 				else if( !Lower()->IsColumnFrm() )
1032 				{
1033                     SwFrm* pFrm = GetLastLower();
1034                     if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
1035 						pFrm->Prepare( PREP_ADJUST_FRM );
1036 				}
1037 			}
1038 
1039             // --> OD 2004-06-28 #i28701# - perform reorder of object lists
1040             // at anchor frame and at page frame.
1041             rInvFlags |= 0x80;
1042 
1043             break;
1044 		}
1045 		case RES_UL_SPACE:
1046 		case RES_LR_SPACE:
1047         {
1048             rInvFlags |= 0x41;
1049             if( pSh && pSh->GetViewOptions()->getBrowseMode() )
1050 				getRootFrm()->InvalidateBrowseWidth();
1051             SwRect aNew( GetObjRectWithSpaces() );
1052 			SwRect aOld( aFrm );
1053 			if ( RES_UL_SPACE == nWhich )
1054 			{
1055 				const SvxULSpaceItem &rUL = *(SvxULSpaceItem*)pNew;
1056 				aOld.Top( Max( aOld.Top() - long(rUL.GetUpper()), 0L ) );
1057 				aOld.SSize().Height()+= rUL.GetLower();
1058 			}
1059 			else
1060 			{
1061 				const SvxLRSpaceItem &rLR = *(SvxLRSpaceItem*)pNew;
1062 				aOld.Left  ( Max( aOld.Left() - long(rLR.GetLeft()), 0L ) );
1063 				aOld.SSize().Width() += rLR.GetRight();
1064 			}
1065 			aNew.Union( aOld );
1066 			NotifyBackground( FindPageFrm(), aNew, PREP_CLEAR );
1067         }
1068         break;
1069 
1070 		case RES_BOX:
1071 		case RES_SHADOW:
1072 			rInvFlags |= 0x17;
1073 			break;
1074 
1075         case RES_FRAMEDIR :
1076             SetDerivedVert( sal_False );
1077             SetDerivedR2L( sal_False );
1078             CheckDirChange();
1079             break;
1080 
1081         case RES_OPAQUE:
1082             {
1083                 if ( pSh )
1084                     pSh->InvalidateWindows( Frm() );
1085 
1086                 const IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess();
1087                 const sal_uInt8 nId = ((SvxOpaqueItem*)pNew)->GetValue() ?
1088                                     pIDDMA->GetHeavenId() :
1089                                     pIDDMA->GetHellId();
1090                 GetVirtDrawObj()->SetLayer( nId );
1091                 if( pSh )
1092                 {
1093                     SwRootFrm* pLayout = getRootFrm();
1094                     if( pLayout && pLayout->IsAnyShellAccessible() )
1095                 {
1096                     pSh->Imp()->DisposeAccessibleFrm( this );
1097                     pSh->Imp()->AddAccessibleFrm( this );
1098                 }
1099                 }
1100                 // --> OD 2004-06-28 #i28701# - perform reorder of object lists
1101                 // at anchor frame and at page frame.
1102                 rInvFlags |= 0x80;
1103             }
1104 			break;
1105 
1106 		case RES_URL:
1107 			//Das Interface arbeitet bei Textrahmen auf der Rahmengroesse,
1108 			//die Map muss sich aber auf die FrmSize beziehen
1109 			if ( (!Lower() || !Lower()->IsNoTxtFrm()) &&
1110 				 ((SwFmtURL*)pNew)->GetMap() && ((SwFmtURL*)pOld)->GetMap() )
1111 			{
1112 				const SwFmtFrmSize &rSz = GetFmt()->GetFrmSize();
1113 				if ( rSz.GetHeight() != Frm().Height() ||
1114 					 rSz.GetWidth()  != Frm().Width() )
1115 				{
1116 					SwFmtURL aURL( GetFmt()->GetURL() );
1117 					Fraction aScaleX( Frm().Width(),  rSz.GetWidth() );
1118 					Fraction aScaleY( Frm().Height(), rSz.GetHeight() );
1119 					aURL.GetMap()->Scale( aScaleX, aScaleY );
1120 					SwFrmFmt *pFmt = GetFmt();
1121 					pFmt->LockModify();
1122                     pFmt->SetFmtAttr( aURL );
1123 					pFmt->UnlockModify();
1124 				}
1125 			}
1126 			/* Keine Invalidierung notwendig */
1127 			break;
1128 
1129 		case RES_CHAIN:
1130 			{
1131 				SwFmtChain *pChain = (SwFmtChain*)pNew;
1132 				if ( pChain->GetNext() )
1133 				{
1134 					SwFlyFrm *pFollow = FindChainNeighbour( *pChain->GetNext() );
1135 					if ( GetNextLink() && pFollow != GetNextLink() )
1136 						SwFlyFrm::UnchainFrames( this, GetNextLink());
1137 					if ( pFollow )
1138 					{
1139 						if ( pFollow->GetPrevLink() &&
1140 							 pFollow->GetPrevLink() != this )
1141 							SwFlyFrm::UnchainFrames( pFollow->GetPrevLink(),
1142 													 pFollow );
1143 						if ( !GetNextLink() )
1144 							SwFlyFrm::ChainFrames( this, pFollow );
1145 					}
1146 				}
1147 				else if ( GetNextLink() )
1148 					SwFlyFrm::UnchainFrames( this, GetNextLink() );
1149 				if ( pChain->GetPrev() )
1150 				{
1151 					SwFlyFrm *pMaster = FindChainNeighbour( *pChain->GetPrev() );
1152 					if ( GetPrevLink() && pMaster != GetPrevLink() )
1153 						SwFlyFrm::UnchainFrames( GetPrevLink(), this );
1154 					if ( pMaster )
1155 					{
1156 						if ( pMaster->GetNextLink() &&
1157 							 pMaster->GetNextLink() != this )
1158 							SwFlyFrm::UnchainFrames( pMaster,
1159 													 pMaster->GetNextLink() );
1160 						if ( !GetPrevLink() )
1161 							SwFlyFrm::ChainFrames( pMaster, this );
1162 					}
1163 				}
1164 				else if ( GetPrevLink() )
1165 					SwFlyFrm::UnchainFrames( GetPrevLink(), this );
1166 			}
1167 
1168 		default:
1169 			bClear = sal_False;
1170 	}
1171 	if ( bClear )
1172 	{
1173 		if ( pOldSet || pNewSet )
1174 		{
1175 			if ( pOldSet )
1176 				pOldSet->ClearItem( nWhich );
1177 			if ( pNewSet )
1178 				pNewSet->ClearItem( nWhich );
1179 		}
1180 		else
1181 			SwLayoutFrm::Modify( pOld, pNew );
1182 	}
1183 }
1184 
1185 /*************************************************************************
1186 |*
1187 |*				  SwFlyFrm::GetInfo()
1188 |*
1189 |*	  Beschreibung		erfragt Informationen
1190 |*	  Ersterstellung	JP 31.03.94
1191 |*	  Letzte Aenderung	JP 31.03.94
1192 |*
1193 *************************************************************************/
1194 
1195 	// erfrage vom Modify Informationen
GetInfo(SfxPoolItem & rInfo) const1196 sal_Bool SwFlyFrm::GetInfo( SfxPoolItem & rInfo ) const
1197 {
1198 	if( RES_AUTOFMT_DOCNODE == rInfo.Which() )
1199 		return sal_False;	// es gibt einen FlyFrm also wird er benutzt
1200 	return sal_True;		// weiter suchen
1201 }
1202 
1203 /*************************************************************************
1204 |*
1205 |*	SwFlyFrm::_Invalidate()
1206 |*
1207 |*	Ersterstellung		MA 15. Oct. 92
1208 |*	Letzte Aenderung	MA 26. Jun. 96
1209 |*
1210 |*************************************************************************/
1211 
_Invalidate(SwPageFrm * pPage)1212 void SwFlyFrm::_Invalidate( SwPageFrm *pPage )
1213 {
1214 	InvalidatePage( pPage );
1215 	bNotifyBack = bInvalid = sal_True;
1216 
1217 	SwFlyFrm *pFrm;
1218     if ( GetAnchorFrm() && 0 != (pFrm = AnchorFrm()->FindFlyFrm()) )
1219 	{
1220 		//Gaanz dumm: Wenn der Fly innerhalb eines Fly gebunden ist, der
1221 		//Spalten enthaehlt, sollte das Format von diesem ausgehen.
1222 		if ( !pFrm->IsLocked() && !pFrm->IsColLocked() &&
1223 			 pFrm->Lower() && pFrm->Lower()->IsColumnFrm() )
1224 			pFrm->InvalidateSize();
1225 	}
1226 
1227     // --> OD 2008-01-21 #i85216#
1228     // if vertical position is oriented at a layout frame inside a ghost section,
1229     // assure that the position is invalidated and that the information about
1230     // the vertical position oriented frame is cleared
1231     if ( GetVertPosOrientFrm() && GetVertPosOrientFrm()->IsLayoutFrm() )
1232     {
1233         const SwSectionFrm* pSectFrm( GetVertPosOrientFrm()->FindSctFrm() );
1234         if ( pSectFrm && pSectFrm->GetSection() == 0 )
1235         {
1236             InvalidatePos();
1237             ClearVertPosOrientFrm();
1238         }
1239     }
1240     // <--
1241 }
1242 
1243 /*************************************************************************
1244 |*
1245 |*	SwFlyFrm::ChgRelPos()
1246 |*
1247 |*	Beschreibung		Aenderung der relativen Position, die Position wird
1248 |*		damit automatisch Fix, das Attribut wird entprechend angepasst.
1249 |*	Ersterstellung		MA 25. Aug. 92
1250 |*	Letzte Aenderung	MA 09. Aug. 95
1251 |*
1252 |*************************************************************************/
1253 
ChgRelPos(const Point & rNewPos)1254 void SwFlyFrm::ChgRelPos( const Point &rNewPos )
1255 {
1256     if ( GetCurrRelPos() != rNewPos )
1257 	{
1258 		SwFrmFmt *pFmt = GetFmt();
1259         const bool bVert = GetAnchorFrm()->IsVertical();
1260         const SwTwips nNewY = bVert ? rNewPos.X() : rNewPos.Y();
1261         SwTwips nTmpY = nNewY == LONG_MAX ? 0 : nNewY;
1262         if( bVert )
1263             nTmpY = -nTmpY;
1264 		SfxItemSet aSet( pFmt->GetDoc()->GetAttrPool(),
1265 						 RES_VERT_ORIENT, RES_HORI_ORIENT);
1266 
1267 		SwFmtVertOrient aVert( pFmt->GetVertOrient() );
1268 		SwTxtFrm *pAutoFrm = NULL;
1269         // --> OD 2004-11-12 #i34948# - handle also at-page and at-fly anchored
1270         // Writer fly frames
1271         const RndStdIds eAnchorType = GetFrmFmt().GetAnchor().GetAnchorId();
1272         if ( eAnchorType == FLY_AT_PAGE )
1273         {
1274             aVert.SetVertOrient( text::VertOrientation::NONE );
1275             aVert.SetRelationOrient( text::RelOrientation::PAGE_FRAME );
1276         }
1277         else if ( eAnchorType == FLY_AT_FLY )
1278         {
1279             aVert.SetVertOrient( text::VertOrientation::NONE );
1280             aVert.SetRelationOrient( text::RelOrientation::FRAME );
1281         }
1282         // <--
1283         else if ( IsFlyAtCntFrm() || text::VertOrientation::NONE != aVert.GetVertOrient() )
1284 		{
1285             if( text::RelOrientation::CHAR == aVert.GetRelationOrient() && IsAutoPos() )
1286 			{
1287                 if( LONG_MAX != nNewY )
1288 				{
1289                     aVert.SetVertOrient( text::VertOrientation::NONE );
1290 					xub_StrLen nOfs =
1291 						pFmt->GetAnchor().GetCntntAnchor()->nContent.GetIndex();
1292                     ASSERT( GetAnchorFrm()->IsTxtFrm(), "TxtFrm expected" );
1293                     pAutoFrm = (SwTxtFrm*)GetAnchorFrm();
1294 					while( pAutoFrm->GetFollow() &&
1295 						   pAutoFrm->GetFollow()->GetOfst() <= nOfs )
1296 					{
1297                         if( pAutoFrm == GetAnchorFrm() )
1298 							nTmpY += pAutoFrm->GetRelPos().Y();
1299 						nTmpY -= pAutoFrm->GetUpper()->Prt().Height();
1300 						pAutoFrm = pAutoFrm->GetFollow();
1301 					}
1302 					nTmpY = ((SwFlyAtCntFrm*)this)->GetRelCharY(pAutoFrm)-nTmpY;
1303 				}
1304 				else
1305                     aVert.SetVertOrient( text::VertOrientation::CHAR_BOTTOM );
1306 			}
1307 			else
1308 			{
1309                 aVert.SetVertOrient( text::VertOrientation::NONE );
1310                 aVert.SetRelationOrient( text::RelOrientation::FRAME );
1311 			}
1312 		}
1313 		aVert.SetPos( nTmpY );
1314 		aSet.Put( aVert );
1315 
1316         //Fuer Flys im Cnt ist die horizontale Ausrichtung uninteressant,
1317 		//den sie ist stets 0.
1318 		if ( !IsFlyInCntFrm() )
1319 		{
1320             const SwTwips nNewX = bVert ? rNewPos.Y() : rNewPos.X();
1321             SwTwips nTmpX = nNewX == LONG_MAX ? 0 : nNewX;
1322 			SwFmtHoriOrient aHori( pFmt->GetHoriOrient() );
1323             // --> OD 2004-11-12 #i34948# - handle also at-page and at-fly anchored
1324             // Writer fly frames
1325             if ( eAnchorType == FLY_AT_PAGE )
1326             {
1327                 aHori.SetHoriOrient( text::HoriOrientation::NONE );
1328                 aHori.SetRelationOrient( text::RelOrientation::PAGE_FRAME );
1329                 aHori.SetPosToggle( sal_False );
1330             }
1331             else if ( eAnchorType == FLY_AT_FLY )
1332             {
1333                 aHori.SetHoriOrient( text::HoriOrientation::NONE );
1334                 aHori.SetRelationOrient( text::RelOrientation::FRAME );
1335                 aHori.SetPosToggle( sal_False );
1336             }
1337             // <--
1338             else if ( IsFlyAtCntFrm() || text::HoriOrientation::NONE != aHori.GetHoriOrient() )
1339 			{
1340                 aHori.SetHoriOrient( text::HoriOrientation::NONE );
1341                 if( text::RelOrientation::CHAR == aHori.GetRelationOrient() && IsAutoPos() )
1342 				{
1343                     if( LONG_MAX != nNewX )
1344 					{
1345 						if( !pAutoFrm )
1346 						{
1347 							xub_StrLen nOfs = pFmt->GetAnchor().GetCntntAnchor()
1348 										  ->nContent.GetIndex();
1349                             ASSERT( GetAnchorFrm()->IsTxtFrm(), "TxtFrm expected");
1350                             pAutoFrm = (SwTxtFrm*)GetAnchorFrm();
1351 							while( pAutoFrm->GetFollow() &&
1352 								   pAutoFrm->GetFollow()->GetOfst() <= nOfs )
1353 								pAutoFrm = pAutoFrm->GetFollow();
1354 						}
1355 						nTmpX -= ((SwFlyAtCntFrm*)this)->GetRelCharX(pAutoFrm);
1356 					}
1357 				}
1358 				else
1359                     aHori.SetRelationOrient( text::RelOrientation::FRAME );
1360 				aHori.SetPosToggle( sal_False );
1361 			}
1362 			aHori.SetPos( nTmpX );
1363 			aSet.Put( aHori );
1364 		}
1365         SetCurrRelPos( rNewPos );
1366 		pFmt->GetDoc()->SetAttr( aSet, *pFmt );
1367 	}
1368 }
1369 /*************************************************************************
1370 |*
1371 |*	SwFlyFrm::Format()
1372 |*
1373 |*	Beschreibung:		"Formatiert" den Frame; Frm und PrtArea.
1374 |*						Die Fixsize wird hier nicht eingestellt.
1375 |*	Ersterstellung		MA 14. Jun. 93
1376 |*	Letzte Aenderung	MA 13. Jun. 96
1377 |*
1378 |*************************************************************************/
1379 
Format(const SwBorderAttrs * pAttrs)1380 void SwFlyFrm::Format( const SwBorderAttrs *pAttrs )
1381 {
1382 	ASSERT( pAttrs, "FlyFrm::Format, pAttrs ist 0." );
1383 
1384 	ColLock();
1385 
1386 	if ( !bValidSize )
1387 	{
1388 		if ( Frm().Top() == WEIT_WECH && Frm().Left() == WEIT_WECH )
1389         {
1390 			//Sicherheitsschaltung wegnehmen (siehe SwFrm::CTor)
1391 			Frm().Pos().X() = Frm().Pos().Y() = 0;
1392             // --> OD 2006-08-16 #i68520#
1393             InvalidateObjRectWithSpaces();
1394             // <--
1395         }
1396 
1397 		//Breite der Spalten pruefen und ggf. einstellen.
1398 		if ( Lower() && Lower()->IsColumnFrm() )
1399 			AdjustColumns( 0, sal_False );
1400 
1401 		bValidSize = sal_True;
1402 
1403         const SwTwips nUL = pAttrs->CalcTopLine()  + pAttrs->CalcBottomLine();
1404         const SwTwips nLR = pAttrs->CalcLeftLine() + pAttrs->CalcRightLine();
1405         const SwFmtFrmSize &rFrmSz = GetFmt()->GetFrmSize();
1406               Size aRelSize( CalcRel( rFrmSz ) );
1407 
1408         ASSERT( pAttrs->GetSize().Height() != 0 || rFrmSz.GetHeightPercent(), "Hoehe des RahmenAttr ist 0." );
1409         ASSERT( pAttrs->GetSize().Width()  != 0 || rFrmSz.GetWidthPercent(), "Breite des RahmenAttr ist 0." );
1410 
1411         SWRECTFN( this )
1412         if( !HasFixSize() )
1413 		{
1414             SwTwips nRemaining = 0;
1415 
1416             long nMinHeight = 0;
1417             if( IsMinHeight() )
1418                 nMinHeight = bVert ? aRelSize.Width() : aRelSize.Height();
1419 
1420             if ( Lower() )
1421 			{
1422 				if ( Lower()->IsColumnFrm() )
1423 				{
1424 					FormatWidthCols( *pAttrs, nUL, nMinHeight );
1425                     nRemaining = (Lower()->Frm().*fnRect->fnGetHeight)();
1426 				}
1427 				else
1428 				{
1429 					SwFrm *pFrm = Lower();
1430 					while ( pFrm )
1431                     {
1432                         nRemaining += (pFrm->Frm().*fnRect->fnGetHeight)();
1433 						if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
1434 							// Dieser TxtFrm waere gern ein bisschen groesser
1435 							nRemaining += ((SwTxtFrm*)pFrm)->GetParHeight()
1436                                     - (pFrm->Prt().*fnRect->fnGetHeight)();
1437 						else if( pFrm->IsSctFrm() && ((SwSectionFrm*)pFrm)->IsUndersized() )
1438 							nRemaining += ((SwSectionFrm*)pFrm)->Undersize();
1439 						pFrm = pFrm->GetNext();
1440 					}
1441                     // --> OD 2006-02-09 #130878#
1442                     // Do not keep old height, if content has no height.
1443                     // The old height could be wrong due to wrong layout cache
1444                     // and isn't corrected in the further formatting, because
1445                     // the fly frame doesn't become invalid anymore.
1446 //                    if( !nRemaining )
1447 //                        nRemaining = nOldHeight - nUL;
1448                     // <--
1449 				}
1450 				if ( GetDrawObjs() )
1451 				{
1452                     sal_uInt32 nCnt = GetDrawObjs()->Count();
1453                     SwTwips nTop = (Frm().*fnRect->fnGetTop)();
1454                     SwTwips nBorder = (Frm().*fnRect->fnGetHeight)() -
1455                                       (Prt().*fnRect->fnGetHeight)();
1456 					for ( sal_uInt16 i = 0; i < nCnt; ++i )
1457 					{
1458                         SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[i];
1459                         if ( pAnchoredObj->ISA(SwFlyFrm) )
1460 						{
1461                             SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
1462                             // OD 06.11.2003 #i22305# - consider
1463                             // only Writer fly frames, which follow the text flow.
1464                             if ( pFly->IsFlyLayFrm() &&
1465                                  pFly->Frm().Top() != WEIT_WECH &&
1466                                  pFly->GetFmt()->GetFollowTextFlow().GetValue() )
1467 							{
1468                                 SwTwips nDist = -(pFly->Frm().*fnRect->
1469                                     fnBottomDist)( nTop );
1470                                 if( nDist > nBorder + nRemaining )
1471                                     nRemaining = nDist - nBorder;
1472 							}
1473 						}
1474 					}
1475 				}
1476 			}
1477 
1478             if( IsMinHeight() && (nRemaining + nUL) < nMinHeight )
1479 				nRemaining = nMinHeight - nUL;
1480 			//Weil das Grow/Shrink der Flys die Groessen nicht direkt
1481 			//einstellt, sondern indirekt per Invalidate ein Format
1482 			//ausloesst, muessen die Groessen hier direkt eingestellt
1483 			//werden. Benachrichtung laeuft bereits mit.
1484 			//Weil bereits haeufiger 0en per Attribut hereinkamen wehre
1485 			//ich mich ab sofort dagegen.
1486 			if ( nRemaining < MINFLY )
1487 				nRemaining = MINFLY;
1488             (Prt().*fnRect->fnSetHeight)( nRemaining );
1489             nRemaining -= (Frm().*fnRect->fnGetHeight)();
1490             (Frm().*fnRect->fnAddBottom)( nRemaining + nUL );
1491             // --> OD 2006-08-16 #i68520#
1492             if ( nRemaining + nUL != 0 )
1493             {
1494                 InvalidateObjRectWithSpaces();
1495             }
1496             // <--
1497 			bValidSize = sal_True;
1498 		}
1499 		else
1500 		{
1501 			bValidSize = sal_True;	//Fixe Frms formatieren sich nicht.
1502 								//Flys stellen ihre Groesse anhand des Attr ein.
1503             SwTwips nNewSize = bVert ? aRelSize.Width() : aRelSize.Height();
1504             nNewSize -= nUL;
1505             if( nNewSize < MINFLY )
1506                 nNewSize = MINFLY;
1507             (Prt().*fnRect->fnSetHeight)( nNewSize );
1508             nNewSize += nUL - (Frm().*fnRect->fnGetHeight)();
1509             (Frm().*fnRect->fnAddBottom)( nNewSize );
1510             // --> OD 2006-08-16 #i68520#
1511             if ( nNewSize != 0 )
1512             {
1513                 InvalidateObjRectWithSpaces();
1514             }
1515             // <--
1516         }
1517 
1518 		if ( !bFormatHeightOnly )
1519 		{
1520             ASSERT( aRelSize == CalcRel( rFrmSz ), "SwFlyFrm::Format CalcRel problem" )
1521             SwTwips nNewSize = bVert ? aRelSize.Height() : aRelSize.Width();
1522 
1523             if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
1524             {
1525                 // #i9046# Autowidth for fly frames
1526                 const SwTwips nAutoWidth = CalcAutoWidth();
1527                 if ( nAutoWidth )
1528                 {
1529                     if( ATT_MIN_SIZE == rFrmSz.GetWidthSizeType() )
1530                         nNewSize = Max( nNewSize - nLR, nAutoWidth );
1531                     else
1532                         nNewSize = nAutoWidth;
1533                 }
1534             }
1535             /*else
1536                 nNewSize -= nLR;*/
1537 			else
1538 			{//Bug 120881:For enlarging fixed size Pagenumber frame,kangjian
1539 				if(nNewSize <= 500 && IsPageNumberingFrm())
1540 					nNewSize = nNewSize - nLR + 150;
1541 
1542 				else
1543 					nNewSize -= nLR;
1544 			//Bug 120881(End)
1545 			}
1546 
1547             if( nNewSize < MINFLY )
1548                 nNewSize = MINFLY;
1549             (Prt().*fnRect->fnSetWidth)( nNewSize );
1550             nNewSize += nLR - (Frm().*fnRect->fnGetWidth)();
1551             (Frm().*fnRect->fnAddRight)( nNewSize );
1552             // --> OD 2006-08-16 #i68520#
1553             if ( nNewSize != 0 )
1554             {
1555                 InvalidateObjRectWithSpaces();
1556             }
1557             // <--
1558         }
1559 	}
1560 	ColUnlock();
1561 }
1562 
1563 // OD 14.03.2003 #i11760# - change parameter <bNoColl>: type <bool>;
1564 //                          default value = false.
1565 // OD 14.03.2003 #i11760# - add new parameter <bNoCalcFollow> with
1566 //                          default value = false.
1567 // OD 11.04.2003 #108824# - new parameter <bNoCalcFollow> was used by method
1568 //                          <FormatWidthCols(..)> to avoid follow formatting
1569 //                          for text frames. But, unformatted follows causes
1570 //                          problems in method <SwCntntFrm::_WouldFit(..)>,
1571 //                          which assumes that the follows are formatted.
1572 //                          Thus, <bNoCalcFollow> no longer used by <FormatWidthCols(..)>.
1573 //void CalcCntnt( SwLayoutFrm *pLay, sal_Bool bNoColl )
CalcCntnt(SwLayoutFrm * pLay,bool bNoColl,bool bNoCalcFollow)1574 void CalcCntnt( SwLayoutFrm *pLay,
1575                 bool bNoColl,
1576                 bool bNoCalcFollow )
1577 {
1578 	SwSectionFrm* pSect;
1579 	sal_Bool bCollect = sal_False;
1580 	if( pLay->IsSctFrm() )
1581 	{
1582 		pSect = (SwSectionFrm*)pLay;
1583 		if( pSect->IsEndnAtEnd() && !bNoColl )
1584 		{
1585 			bCollect = sal_True;
1586 			SwLayouter::CollectEndnotes( pLay->GetFmt()->GetDoc(), pSect );
1587 		}
1588 		pSect->CalcFtnCntnt();
1589 	}
1590 	else
1591 		pSect = NULL;
1592 	SwFrm *pFrm = pLay->ContainsAny();
1593 	if ( !pFrm )
1594 	{
1595 		if( pSect )
1596 		{
1597 			if( pSect->HasFollow() )
1598 				pFrm = pSect->GetFollow()->ContainsAny();
1599 			if( !pFrm )
1600 			{
1601 				if( pSect->IsEndnAtEnd() )
1602 				{
1603 					if( bCollect )
1604 						pLay->GetFmt()->GetDoc()->GetLayouter()->
1605 							InsertEndnotes( pSect );
1606 					sal_Bool bLock = pSect->IsFtnLock();
1607 					pSect->SetFtnLock( sal_True );
1608 					pSect->CalcFtnCntnt();
1609 					pSect->CalcFtnCntnt();
1610 					pSect->SetFtnLock( bLock );
1611 				}
1612 				return;
1613 			}
1614 			pFrm->_InvalidatePos();
1615 		}
1616 		else
1617 			return;
1618 	}
1619 	pFrm->InvalidatePage();
1620 
1621 	do
1622 	{
1623         // local variables to avoid loops caused by anchored object positioning
1624         SwAnchoredObject* pAgainObj1 = 0;
1625         SwAnchoredObject* pAgainObj2 = 0;
1626 
1627         // FME 2007-08-30 #i81146# new loop control
1628         sal_uInt16 nLoopControlRuns = 0;
1629         const sal_uInt16 nLoopControlMax = 20;
1630         const SwFrm* pLoopControlCond = 0;
1631 
1632         SwFrm* pLast;
1633 		do
1634 		{
1635 			pLast = pFrm;
1636             if( pFrm->IsVertical() ?
1637                 ( pFrm->GetUpper()->Prt().Height() != pFrm->Frm().Height() )
1638                 : ( pFrm->GetUpper()->Prt().Width() != pFrm->Frm().Width() ) )
1639 			{
1640 				pFrm->Prepare( PREP_FIXSIZE_CHG );
1641 				pFrm->_InvalidateSize();
1642 			}
1643 
1644 			if ( pFrm->IsTabFrm() )
1645 			{
1646 				((SwTabFrm*)pFrm)->bCalcLowers = sal_True;
1647                 // OD 26.08.2003 #i18103# - lock move backward of follow table,
1648                 // if no section content is formatted or follow table belongs
1649                 // to the section, which content is formatted.
1650                 if ( ((SwTabFrm*)pFrm)->IsFollow() &&
1651                      ( !pSect || pSect == pFrm->FindSctFrm() ) )
1652                 {
1653 					((SwTabFrm*)pFrm)->bLockBackMove = sal_True;
1654                 }
1655 			}
1656 
1657             // OD 14.03.2003 #i11760# - forbid format of follow, if requested.
1658             if ( bNoCalcFollow && pFrm->IsTxtFrm() )
1659                 static_cast<SwTxtFrm*>(pFrm)->ForbidFollowFormat();
1660 
1661             pFrm->Calc();
1662 
1663             // OD 14.03.2003 #i11760# - reset control flag for follow format.
1664             if ( pFrm->IsTxtFrm() )
1665             {
1666                 static_cast<SwTxtFrm*>(pFrm)->AllowFollowFormat();
1667             }
1668 
1669             // #111937# The keep-attribute can cause the position
1670             // of the prev to be invalid:
1671             // OD 2004-03-15 #116560# - Do not consider invalid previous frame
1672             // due to its keep-attribute, if current frame is a follow or is locked.
1673             // --> OD 2005-03-08 #i44049# - do not consider invalid previous
1674             // frame due to its keep-attribute, if it can't move forward.
1675             // --> OD 2006-01-27 #i57765# - do not consider invalid previous
1676             // frame, if current frame has a column/page break before attribute.
1677             SwFrm* pTmpPrev = pFrm->FindPrev();
1678             SwFlowFrm* pTmpPrevFlowFrm = pTmpPrev && pTmpPrev->IsFlowFrm() ? SwFlowFrm::CastFlowFrm(pTmpPrev) : 0;
1679             SwFlowFrm* pTmpFlowFrm     = pFrm->IsFlowFrm() ? SwFlowFrm::CastFlowFrm(pFrm) : 0;
1680 
1681             bool bPrevInvalid = pTmpPrevFlowFrm && pTmpFlowFrm &&
1682                                !pTmpFlowFrm->IsFollow() &&
1683                                !StackHack::IsLocked() && // #i76382#
1684                                !pTmpFlowFrm->IsJoinLocked() &&
1685                                !pTmpPrev->GetValidPosFlag() &&
1686                                 pLay->IsAnLower( pTmpPrev ) &&
1687                                 pTmpPrevFlowFrm->IsKeep( *pTmpPrev->GetAttrSet() ) &&
1688                                 pTmpPrevFlowFrm->IsKeepFwdMoveAllowed();
1689             // <--
1690 
1691             // format floating screen objects anchored to the frame.
1692             bool bRestartLayoutProcess = false;
1693             if ( !bPrevInvalid && pFrm->GetDrawObjs() && pLay->IsAnLower( pFrm ) )
1694 			{
1695                 bool bAgain = false;
1696                 SwPageFrm* pPageFrm = pFrm->FindPageFrm();
1697                 sal_uInt32 nCnt = pFrm->GetDrawObjs()->Count();
1698 				for ( sal_uInt16 i = 0; i < nCnt; ++i )
1699 				{
1700                     // --> OD 2004-07-01 #i28701#
1701                     SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i];
1702                     // determine, if anchored object has to be formatted.
1703                     if ( pAnchoredObj->PositionLocked() )
1704                     {
1705                         continue;
1706                     }
1707 
1708                     // format anchored object
1709                     if ( pAnchoredObj->IsFormatPossible() )
1710                     {
1711                         // --> OD 2005-05-17 #i43737# - no invalidation of
1712                         // anchored object needed - causes loops for as-character
1713                         // anchored objects.
1714                         //pAnchoredObj->InvalidateObjPos();
1715                         // <--
1716                         SwRect aRect( pAnchoredObj->GetObjRect() );
1717                         if ( !SwObjectFormatter::FormatObj( *pAnchoredObj, pFrm, pPageFrm ) )
1718                         {
1719                             bRestartLayoutProcess = true;
1720                             break;
1721                         }
1722                         // --> OD 2004-08-25 #i3317# - restart layout process,
1723                         // if the position of the anchored object is locked now.
1724                         if ( pAnchoredObj->PositionLocked() )
1725                         {
1726                             bRestartLayoutProcess = true;
1727                             break;
1728                         }
1729                         // <--
1730 
1731                         if ( aRect != pAnchoredObj->GetObjRect() )
1732                         {
1733                             bAgain = true;
1734                             if ( pAgainObj2 == pAnchoredObj )
1735                             {
1736                                 ASSERT( false,
1737                                         "::CalcCntnt(..) - loop detected, perform attribute changes to avoid the loop" );
1738                                 //Oszillation unterbinden.
1739                                 SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt();
1740                                 SwFmtSurround aAttr( rFmt.GetSurround() );
1741                                 if( SURROUND_THROUGHT != aAttr.GetSurround() )
1742                                 {
1743                                     // Bei autopositionierten hilft manchmal nur
1744                                     // noch, auf Durchlauf zu schalten
1745                                     if ((rFmt.GetAnchor().GetAnchorId() ==
1746                                             FLY_AT_CHAR) &&
1747                                         (SURROUND_PARALLEL ==
1748                                             aAttr.GetSurround()))
1749                                     {
1750                                         aAttr.SetSurround( SURROUND_THROUGHT );
1751                                     }
1752                                     else
1753                                     {
1754                                         aAttr.SetSurround( SURROUND_PARALLEL );
1755                                     }
1756                                     rFmt.LockModify();
1757                                     rFmt.SetFmtAttr( aAttr );
1758                                     rFmt.UnlockModify();
1759                                 }
1760                             }
1761                             else
1762                             {
1763                                 if ( pAgainObj1 == pAnchoredObj )
1764                                     pAgainObj2 = pAnchoredObj;
1765                                 pAgainObj1 = pAnchoredObj;
1766                             }
1767                         }
1768 
1769                         if ( !pFrm->GetDrawObjs() )
1770                             break;
1771                         if ( pFrm->GetDrawObjs()->Count() < nCnt )
1772                         {
1773                             --i;
1774                             --nCnt;
1775                         }
1776                     }
1777 				}
1778 
1779                 // --> OD 2004-06-11 #i28701# - restart layout process, if
1780                 // requested by floating screen object formatting
1781                 if ( bRestartLayoutProcess )
1782                 {
1783                     pFrm = pLay->ContainsAny();
1784                     pAgainObj1 = 0L;
1785                     pAgainObj2 = 0L;
1786                     continue;
1787                 }
1788 
1789                 // OD 2004-05-17 #i28701# - format anchor frame after its objects
1790                 // are formatted, if the wrapping style influence has to be considered.
1791                 if ( pLay->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) )
1792                 {
1793                     pFrm->Calc();
1794                 }
1795                 // <--
1796 
1797                 if ( bAgain )
1798 				{
1799 					pFrm = pLay->ContainsCntnt();
1800 					if ( pFrm && pFrm->IsInTab() )
1801 						pFrm = pFrm->FindTabFrm();
1802 					if( pFrm && pFrm->IsInSct() )
1803 					{
1804 						SwSectionFrm* pTmp = pFrm->FindSctFrm();
1805 						if( pTmp != pLay && pLay->IsAnLower( pTmp ) )
1806 							pFrm = pTmp;
1807 					}
1808 
1809                     if ( pFrm == pLoopControlCond )
1810                         ++nLoopControlRuns;
1811                     else
1812                     {
1813                         nLoopControlRuns = 0;
1814                         pLoopControlCond = pFrm;
1815                     }
1816 
1817                     if ( nLoopControlRuns < nLoopControlMax )
1818                         continue;
1819 
1820 #if OSL_DEBUG_LEVEL > 1
1821                     ASSERT( false, "LoopControl in CalcCntnt" )
1822 #endif
1823 				}
1824 			}
1825 			if ( pFrm->IsTabFrm() )
1826 			{
1827 				if ( ((SwTabFrm*)pFrm)->IsFollow() )
1828 					((SwTabFrm*)pFrm)->bLockBackMove = sal_False;
1829 			}
1830 
1831             pFrm = bPrevInvalid ? pTmpPrev : pFrm->FindNext();
1832             if( !bPrevInvalid && pFrm && pFrm->IsSctFrm() && pSect )
1833 			{
1834 				// Es koennen hier leere SectionFrms herumspuken
1835 				while( pFrm && pFrm->IsSctFrm() && !((SwSectionFrm*)pFrm)->GetSection() )
1836 					pFrm = pFrm->FindNext();
1837 				// Wenn FindNext den Follow des urspruenglichen Bereichs liefert,
1838 				// wollen wir mit dessen Inhalt weitermachen, solange dieser
1839 				// zurueckfliesst.
1840 				if( pFrm && pFrm->IsSctFrm() && ( pFrm == pSect->GetFollow() ||
1841 					((SwSectionFrm*)pFrm)->IsAnFollow( pSect ) ) )
1842 				{
1843 					pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
1844 					if( pFrm )
1845 						pFrm->_InvalidatePos();
1846 				}
1847 			}
1848 			// Im pLay bleiben, Ausnahme, bei SectionFrms mit Follow wird der erste
1849 			// CntntFrm des Follows anformatiert, damit er die Chance erhaelt, in
1850 			// pLay zu landen. Solange diese Frames in pLay landen, geht's weiter.
1851         } while ( pFrm &&
1852                   ( pLay->IsAnLower( pFrm ) ||
1853                     ( pSect &&
1854                       ( ( pSect->HasFollow() &&
1855                           ( pLay->IsAnLower( pLast ) ||
1856                             ( pLast->IsInSct() &&
1857                               pLast->FindSctFrm()->IsAnFollow(pSect) ) ) &&
1858                           pSect->GetFollow()->IsAnLower( pFrm )  ) ||
1859                         ( pFrm->IsInSct() &&
1860                           pFrm->FindSctFrm()->IsAnFollow( pSect ) ) ) ) ) );
1861 		if( pSect )
1862 		{
1863 			if( bCollect )
1864 			{
1865 				pLay->GetFmt()->GetDoc()->GetLayouter()->InsertEndnotes(pSect);
1866 				pSect->CalcFtnCntnt();
1867 			}
1868 			if( pSect->HasFollow() )
1869 			{
1870 				SwSectionFrm* pNxt = pSect->GetFollow();
1871 				while( pNxt && !pNxt->ContainsCntnt() )
1872 					pNxt = pNxt->GetFollow();
1873 				if( pNxt )
1874 					pNxt->CalcFtnCntnt();
1875 			}
1876 			if( bCollect )
1877 			{
1878 				pFrm = pLay->ContainsAny();
1879 				bCollect = sal_False;
1880 				if( pFrm )
1881 					continue;
1882 			}
1883 		}
1884 		break;
1885 	}
1886 	while( sal_True );
1887 }
1888 
1889 /*************************************************************************
1890 |*
1891 |*	SwFlyFrm::MakeFlyPos()
1892 |*
1893 |*	Ersterstellung		MA ??
1894 |*	Letzte Aenderung	MA 14. Nov. 96
1895 |*
1896 |*************************************************************************/
1897 // OD 2004-03-23 #i26791#
1898 //void SwFlyFrm::MakeFlyPos()
MakeObjPos()1899 void SwFlyFrm::MakeObjPos()
1900 {
1901     if ( !bValidPos )
1902     {
1903         bValidPos = sal_True;
1904 
1905         // OD 29.10.2003 #113049# - use new class to position object
1906         GetAnchorFrm()->Calc();
1907         objectpositioning::SwToLayoutAnchoredObjectPosition
1908                 aObjPositioning( *GetVirtDrawObj() );
1909         aObjPositioning.CalcPosition();
1910 
1911         // --> OD 2006-10-05 #i58280#
1912         // update relative position
1913         SetCurrRelPos( aObjPositioning.GetRelPos() );
1914         // <--
1915 
1916         SWRECTFN( GetAnchorFrm() );
1917         aFrm.Pos( aObjPositioning.GetRelPos() );
1918         aFrm.Pos() += (GetAnchorFrm()->Frm().*fnRect->fnGetPos)();
1919         // --> OD 2006-09-11 #i69335#
1920         InvalidateObjRectWithSpaces();
1921         // <--
1922     }
1923 }
1924 
1925 /*************************************************************************
1926 |*
1927 |*	SwFlyFrm::MakePrtArea()
1928 |*
1929 |*	Ersterstellung		MA 23. Jun. 93
1930 |*	Letzte Aenderung	MA 23. Jun. 93
1931 |*
1932 |*************************************************************************/
MakePrtArea(const SwBorderAttrs & rAttrs)1933 void SwFlyFrm::MakePrtArea( const SwBorderAttrs &rAttrs )
1934 {
1935 
1936 	if ( !bValidPrtArea )
1937 	{
1938 		bValidPrtArea = sal_True;
1939 
1940         // OD 31.07.2003 #110978# - consider vertical layout
1941         SWRECTFN( this )
1942         (this->*fnRect->fnSetXMargins)( rAttrs.CalcLeftLine(),
1943                                         rAttrs.CalcRightLine() );
1944         (this->*fnRect->fnSetYMargins)( rAttrs.CalcTopLine(),
1945                                         rAttrs.CalcBottomLine() );
1946 	}
1947 }
1948 
1949 /*************************************************************************
1950 |*
1951 |*	SwFlyFrm::_Grow(), _Shrink()
1952 |*
1953 |*	Ersterstellung		MA 05. Oct. 92
1954 |*	Letzte Aenderung	MA 05. Sep. 96
1955 |*
1956 |*************************************************************************/
1957 
_Grow(SwTwips nDist,sal_Bool bTst)1958 SwTwips SwFlyFrm::_Grow( SwTwips nDist, sal_Bool bTst )
1959 {
1960     SWRECTFN( this )
1961     if ( Lower() && !IsColLocked() && !HasFixSize() )
1962 	{
1963         SwTwips nSize = (Frm().*fnRect->fnGetHeight)();
1964         if( nSize > 0 && nDist > ( LONG_MAX - nSize ) )
1965             nDist = LONG_MAX - nSize;
1966 
1967 		if ( nDist <= 0L )
1968 			return 0L;
1969 
1970 		if ( Lower()->IsColumnFrm() )
1971 		{	//Bei Spaltigkeit ubernimmt das Format die Kontrolle ueber
1972 			//das Wachstum (wg. des Ausgleichs).
1973 			if ( !bTst )
1974             {
1975                 // --> OD 2004-06-09 #i28701# - unlock position of Writer fly frame
1976                 UnlockPosition();
1977                 _InvalidatePos();
1978 				InvalidateSize();
1979 			}
1980 			return 0L;
1981 		}
1982 
1983 		if ( !bTst )
1984 		{
1985             const SwRect aOld( GetObjRectWithSpaces() );
1986 			_InvalidateSize();
1987 			const sal_Bool bOldLock = bLocked;
1988 			Unlock();
1989             if ( IsFlyFreeFrm() )
1990             {
1991                 // --> OD 2004-11-12 #i37068# - no format of position here
1992                 // and prevent move in method <CheckClip(..)>.
1993                 // This is needed to prevent layout loop caused by nested
1994                 // Writer fly frames - inner Writer fly frames format its
1995                 // anchor, which grows/shrinks the outer Writer fly frame.
1996                 // Note: position will be invalidated below.
1997                 bValidPos = sal_True;
1998                 // --> OD 2005-10-10 #i55416#
1999                 // Suppress format of width for autowidth frame, because the
2000                 // format of the width would call <SwTxtFrm::CalcFitToContent()>
2001                 // for the lower frame, which initiated this grow.
2002                 const sal_Bool bOldFormatHeightOnly = bFormatHeightOnly;
2003                 const SwFmtFrmSize& rFrmSz = GetFmt()->GetFrmSize();
2004                 if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
2005                 {
2006                     bFormatHeightOnly = sal_True;
2007                 }
2008                 // <--
2009                 static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( true );
2010                 ((SwFlyFreeFrm*)this)->SwFlyFreeFrm::MakeAll();
2011                 static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( false );
2012                 // --> OD 2005-10-10 #i55416#
2013                 if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
2014                 {
2015                     bFormatHeightOnly = bOldFormatHeightOnly;
2016                 }
2017                 // <--
2018                 // <--
2019             }
2020             else
2021 				MakeAll();
2022 			_InvalidateSize();
2023 			InvalidatePos();
2024 			if ( bOldLock )
2025 				Lock();
2026             const SwRect aNew( GetObjRectWithSpaces() );
2027 			if ( aOld != aNew )
2028 				::Notify( this, FindPageFrm(), aOld );
2029             return (aNew.*fnRect->fnGetHeight)()-(aOld.*fnRect->fnGetHeight)();
2030 		}
2031 		return nDist;
2032 	}
2033 	return 0L;
2034 }
2035 
_Shrink(SwTwips nDist,sal_Bool bTst)2036 SwTwips SwFlyFrm::_Shrink( SwTwips nDist, sal_Bool bTst )
2037 {
2038     if( Lower() && !IsColLocked() && !HasFixSize() && !IsNoShrink() )
2039 	{
2040         SWRECTFN( this )
2041         SwTwips nHeight = (Frm().*fnRect->fnGetHeight)();
2042         if ( nDist > nHeight )
2043             nDist = nHeight;
2044 
2045         SwTwips nVal = nDist;
2046 		if ( IsMinHeight() )
2047 		{
2048             const SwFmtFrmSize& rFmtSize = GetFmt()->GetFrmSize();
2049             SwTwips nFmtHeight = bVert ? rFmtSize.GetWidth() : rFmtSize.GetHeight();
2050 
2051             nVal = Min( nDist, nHeight - nFmtHeight );
2052 		}
2053 
2054 		if ( nVal <= 0L )
2055 			return 0L;
2056 
2057 		if ( Lower()->IsColumnFrm() )
2058 		{	//Bei Spaltigkeit ubernimmt das Format die Kontrolle ueber
2059 			//das Wachstum (wg. des Ausgleichs).
2060 			if ( !bTst )
2061 			{
2062                 SwRect aOld( GetObjRectWithSpaces() );
2063                 (Frm().*fnRect->fnSetHeight)( nHeight - nVal );
2064                 // --> OD 2006-08-16 #i68520#
2065                 if ( nHeight - nVal != 0 )
2066                 {
2067                     InvalidateObjRectWithSpaces();
2068                 }
2069                 // <--
2070                 nHeight = (Prt().*fnRect->fnGetHeight)();
2071                 (Prt().*fnRect->fnSetHeight)( nHeight - nVal );
2072 				_InvalidatePos();
2073 				InvalidateSize();
2074 				::Notify( this, FindPageFrm(), aOld );
2075 				NotifyDrawObj();
2076                 if ( GetAnchorFrm()->IsInFly() )
2077                     AnchorFrm()->FindFlyFrm()->Shrink( nDist, bTst );
2078 			}
2079 			return 0L;
2080 		}
2081 
2082 		if ( !bTst )
2083 		{
2084             const SwRect aOld( GetObjRectWithSpaces() );
2085 			_InvalidateSize();
2086 			const sal_Bool bOldLocked = bLocked;
2087 			Unlock();
2088             if ( IsFlyFreeFrm() )
2089             {
2090                 // --> OD 2004-11-12 #i37068# - no format of position here
2091                 // and prevent move in method <CheckClip(..)>.
2092                 // This is needed to prevent layout loop caused by nested
2093                 // Writer fly frames - inner Writer fly frames format its
2094                 // anchor, which grows/shrinks the outer Writer fly frame.
2095                 // Note: position will be invalidated below.
2096                 bValidPos = sal_True;
2097                 // --> OD 2005-10-10 #i55416#
2098                 // Suppress format of width for autowidth frame, because the
2099                 // format of the width would call <SwTxtFrm::CalcFitToContent()>
2100                 // for the lower frame, which initiated this shrink.
2101                 const sal_Bool bOldFormatHeightOnly = bFormatHeightOnly;
2102                 const SwFmtFrmSize& rFrmSz = GetFmt()->GetFrmSize();
2103                 if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
2104                 {
2105                     bFormatHeightOnly = sal_True;
2106                 }
2107                 // <--
2108                 static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( true );
2109                 ((SwFlyFreeFrm*)this)->SwFlyFreeFrm::MakeAll();
2110                 static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( false );
2111                 // --> OD 2005-10-10 #i55416#
2112                 if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
2113                 {
2114                     bFormatHeightOnly = bOldFormatHeightOnly;
2115                 }
2116                 // <--
2117                 // <--
2118             }
2119             else
2120 				MakeAll();
2121 			_InvalidateSize();
2122 			InvalidatePos();
2123 			if ( bOldLocked )
2124 				Lock();
2125             const SwRect aNew( GetObjRectWithSpaces() );
2126 			if ( aOld != aNew )
2127 			{
2128 				::Notify( this, FindPageFrm(), aOld );
2129                 if ( GetAnchorFrm()->IsInFly() )
2130                     AnchorFrm()->FindFlyFrm()->Shrink( nDist, bTst );
2131 			}
2132             return (aOld.*fnRect->fnGetHeight)() -
2133                    (aNew.*fnRect->fnGetHeight)();
2134 		}
2135 		return nVal;
2136 	}
2137 	return 0L;
2138 }
2139 
2140 /*************************************************************************
2141 |*
2142 |*	SwFlyFrm::ChgSize()
2143 |*
2144 |*	Ersterstellung		MA 05. Oct. 92
2145 |*	Letzte Aenderung	MA 04. Sep. 96
2146 |*
2147 |*************************************************************************/
2148 
ChgSize(const Size & aNewSize)2149 Size SwFlyFrm::ChgSize( const Size& aNewSize )
2150 {
2151     // --> OD 2006-01-19 #i53298#
2152     // If the fly frame anchored at-paragraph or at-character contains an OLE
2153     // object, assure that the new size fits into the current clipping area
2154     // of the fly frame
2155     Size aAdjustedNewSize( aNewSize );
2156     {
2157         if ( dynamic_cast<SwFlyAtCntFrm*>(this) &&
2158              Lower() && dynamic_cast<SwNoTxtFrm*>(Lower()) &&
2159              static_cast<SwNoTxtFrm*>(Lower())->GetNode()->GetOLENode() )
2160         {
2161             SwRect aClipRect;
2162             ::CalcClipRect( GetVirtDrawObj(), aClipRect, sal_False );
2163             if ( aAdjustedNewSize.Width() > aClipRect.Width() )
2164             {
2165                 aAdjustedNewSize.setWidth( aClipRect.Width() );
2166             }
2167             if ( aAdjustedNewSize.Height() > aClipRect.Height() )
2168             {
2169                 aAdjustedNewSize.setWidth( aClipRect.Height() );
2170             }
2171         }
2172     }
2173     // <--
2174     if ( aAdjustedNewSize != Frm().SSize() )
2175 	{
2176 		SwFrmFmt *pFmt = GetFmt();
2177 		SwFmtFrmSize aSz( pFmt->GetFrmSize() );
2178         aSz.SetWidth( aAdjustedNewSize.Width() );
2179         // --> OD 2006-01-19 #i53298# - no tolerance any more.
2180         // If it reveals that the tolerance is still needed, then suppress a
2181         // <SetAttr> call, if <aSz> equals the current <SwFmtFrmSize> attribute.
2182 //        if ( Abs(aAdjustedNewSize.Height() - aSz.GetHeight()) > 1 )
2183         aSz.SetHeight( aAdjustedNewSize.Height() );
2184         // <--
2185 		// uebers Doc fuers Undo!
2186 		pFmt->GetDoc()->SetAttr( aSz, *pFmt );
2187 		return aSz.GetSize();
2188 	}
2189 	else
2190 		return Frm().SSize();
2191 }
2192 
2193 /*************************************************************************
2194 |*
2195 |*	SwFlyFrm::IsLowerOf()
2196 |*
2197 |*	Ersterstellung		MA 27. Dec. 93
2198 |*	Letzte Aenderung	MA 27. Dec. 93
2199 |*
2200 |*************************************************************************/
2201 
IsLowerOf(const SwLayoutFrm * pUpperFrm) const2202 sal_Bool SwFlyFrm::IsLowerOf( const SwLayoutFrm* pUpperFrm ) const
2203 {
2204     ASSERT( GetAnchorFrm(), "8-( Fly is lost in Space." );
2205     const SwFrm* pFrm = GetAnchorFrm();
2206     do
2207     {
2208         if ( pFrm == pUpperFrm )
2209             return sal_True;
2210         pFrm = pFrm->IsFlyFrm()
2211                ? ((const SwFlyFrm*)pFrm)->GetAnchorFrm()
2212                : pFrm->GetUpper();
2213     } while ( pFrm );
2214     return sal_False;
2215 }
2216 
2217 /*************************************************************************
2218 |*
2219 |*	SwFlyFrm::Cut()
2220 |*
2221 |*	Ersterstellung		MA 23. Feb. 94
2222 |*	Letzte Aenderung	MA 23. Feb. 94
2223 |*
2224 |*************************************************************************/
2225 
Cut()2226 void SwFlyFrm::Cut()
2227 {
2228 }
2229 
2230 /*************************************************************************
2231 |*
2232 |*	SwFrm::AppendFly(), RemoveFly()
2233 |*
2234 |*	Ersterstellung		MA 25. Aug. 92
2235 |*	Letzte Aenderung	MA 09. Jun. 95
2236 |*
2237 |*************************************************************************/
2238 
AppendFly(SwFlyFrm * pNew)2239 void SwFrm::AppendFly( SwFlyFrm *pNew )
2240 {
2241     if ( !pDrawObjs )
2242         pDrawObjs = new SwSortedObjs();
2243     pDrawObjs->Insert( *pNew );
2244     pNew->ChgAnchorFrm( this );
2245 
2246     SwPageFrm* pPage = FindPageFrm();
2247     if ( pPage != NULL )
2248     {
2249         pPage->AppendFlyToPage( pNew );
2250     }
2251 }
2252 
RemoveFly(SwFlyFrm * pToRemove)2253 void SwFrm::RemoveFly( SwFlyFrm *pToRemove )
2254 {
2255 	//Bei der Seite Abmelden - kann schon passiert sein weil die Seite
2256 	//bereits destruiert wurde.
2257 	SwPageFrm *pPage = pToRemove->FindPageFrm();
2258 	if ( pPage && pPage->GetSortedObjs() )
2259     {
2260         pPage->RemoveFlyFromPage( pToRemove );
2261     }
2262     // --> OD 2008-05-19 #i73201#
2263     else
2264     {
2265         if ( pToRemove->IsAccessibleFrm() &&
2266              pToRemove->GetFmt() &&
2267              !pToRemove->IsFlyInCntFrm() )
2268         {
2269             SwRootFrm *pRootFrm = getRootFrm();
2270             if( pRootFrm && pRootFrm->IsAnyShellAccessible() )
2271             {
2272                 ViewShell *pVSh = pRootFrm->GetCurrShell();
2273                 if( pVSh && pVSh->Imp() )
2274                 {
2275                     pVSh->Imp()->DisposeAccessibleFrm( pToRemove );
2276                 }
2277             }
2278         }
2279     }
2280     // <--
2281 
2282     pDrawObjs->Remove( *pToRemove );
2283 	if ( !pDrawObjs->Count() )
2284 		DELETEZ( pDrawObjs );
2285 
2286     pToRemove->ChgAnchorFrm( 0 );
2287 
2288 	if ( !pToRemove->IsFlyInCntFrm() && GetUpper() && IsInTab() )//MA_FLY_HEIGHT
2289 		GetUpper()->InvalidateSize();
2290 }
2291 
2292 /*************************************************************************
2293 |*
2294 |*	SwFrm::AppendDrawObj(), RemoveDrawObj()
2295 |*
2296 |*  --> OD 2004-07-06 #i28701# - new methods
2297 |*
2298 |*************************************************************************/
AppendDrawObj(SwAnchoredObject & _rNewObj)2299 void SwFrm::AppendDrawObj( SwAnchoredObject& _rNewObj )
2300 {
2301     if ( !_rNewObj.ISA(SwAnchoredDrawObject) )
2302     {
2303         ASSERT( false,
2304                 "SwFrm::AppendDrawObj(..) - anchored object of unexcepted type -> object not appended" );
2305         return;
2306     }
2307 
2308     if ( !_rNewObj.GetDrawObj()->ISA(SwDrawVirtObj) &&
2309          _rNewObj.GetAnchorFrm() && _rNewObj.GetAnchorFrm() != this )
2310     {
2311         // perform disconnect from layout, if 'master' drawing object is appended
2312         // to a new frame.
2313         static_cast<SwDrawContact*>(::GetUserCall( _rNewObj.GetDrawObj() ))->
2314                                                 DisconnectFromLayout( false );
2315     }
2316 
2317     if ( _rNewObj.GetAnchorFrm() != this )
2318     {
2319         if ( !pDrawObjs )
2320             pDrawObjs = new SwSortedObjs();
2321         pDrawObjs->Insert( _rNewObj );
2322         _rNewObj.ChgAnchorFrm( this );
2323     }
2324 
2325     // --> OD 2010-09-14 #i113730#
2326     // Assure the control objects and group objects containing controls are on the control layer
2327     if ( ::CheckControlLayer( _rNewObj.DrawObj() ) )
2328     {
2329         const IDocumentDrawModelAccess* pIDDMA = (IsFlyFrm())
2330             ? static_cast<SwFlyFrm*>(this)->GetFmt()->
2331                     getIDocumentDrawModelAccess()
2332             : GetUpper()->GetFmt()->getIDocumentDrawModelAccess();
2333         const SdrLayerID aCurrentLayer(_rNewObj.DrawObj()->GetLayer());
2334         const SdrLayerID aControlLayerID(pIDDMA->GetControlsId());
2335         const SdrLayerID aInvisibleControlLayerID(pIDDMA->GetInvisibleControlsId());
2336 
2337         if(aCurrentLayer != aControlLayerID && aCurrentLayer != aInvisibleControlLayerID)
2338         {
2339             if ( aCurrentLayer == pIDDMA->GetInvisibleHellId() ||
2340                  aCurrentLayer == pIDDMA->GetInvisibleHeavenId() )
2341             {
2342                 _rNewObj.DrawObj()->SetLayer(aInvisibleControlLayerID);
2343             }
2344             else
2345             {
2346                 _rNewObj.DrawObj()->SetLayer(aControlLayerID);
2347             }
2348         }
2349     }
2350     // <--
2351 
2352     // no direct positioning needed, but invalidate the drawing object position
2353     _rNewObj.InvalidateObjPos();
2354 
2355     // register at page frame
2356     SwPageFrm* pPage = FindPageFrm();
2357     if ( pPage )
2358     {
2359         pPage->AppendDrawObjToPage( _rNewObj );
2360     }
2361 
2362     // Notify accessible layout.
2363     ViewShell* pSh = getRootFrm()->GetCurrShell();
2364     if( pSh )
2365     {
2366         SwRootFrm* pLayout = getRootFrm();
2367         if( pLayout && pLayout->IsAnyShellAccessible() )
2368         pSh->Imp()->AddAccessibleObj( _rNewObj.GetDrawObj() );
2369     }
2370 }
2371 
RemoveDrawObj(SwAnchoredObject & _rToRemoveObj)2372 void SwFrm::RemoveDrawObj( SwAnchoredObject& _rToRemoveObj )
2373 {
2374     // Notify accessible layout.
2375     ViewShell* pSh = getRootFrm()->GetCurrShell();
2376     if( pSh )
2377     {
2378         SwRootFrm* pLayout = getRootFrm();
2379         if( pLayout && pLayout->IsAnyShellAccessible() )
2380         pSh->Imp()->DisposeAccessibleObj( _rToRemoveObj.GetDrawObj() );
2381     }
2382 
2383     // deregister from page frame
2384     SwPageFrm* pPage = _rToRemoveObj.GetPageFrm();
2385     if ( pPage && pPage->GetSortedObjs() )
2386         pPage->RemoveDrawObjFromPage( _rToRemoveObj );
2387 
2388     pDrawObjs->Remove( _rToRemoveObj );
2389     if ( !pDrawObjs->Count() )
2390         DELETEZ( pDrawObjs );
2391 
2392     _rToRemoveObj.ChgAnchorFrm( 0 );
2393 }
2394 
2395 /*************************************************************************
2396 |*
2397 |*  SwFrm::InvalidateObjs()
2398 |*
2399 |*	Ersterstellung		MA 29. Nov. 96
2400 |*	Letzte Aenderung	MA 29. Nov. 96
2401 |*
2402 |*************************************************************************/
2403 // --> OD 2004-07-01 #i28701# - change purpose of method and adjust its name
InvalidateObjs(const bool _bInvaPosOnly,const bool _bNoInvaOfAsCharAnchoredObjs)2404 void SwFrm::InvalidateObjs( const bool _bInvaPosOnly,
2405                             const bool _bNoInvaOfAsCharAnchoredObjs )
2406 {
2407 	if ( GetDrawObjs() )
2408 	{
2409         // --> OD 2004-10-08 #i26945# - determine page the frame is on,
2410         // in order to check, if anchored object is registered at the same
2411         // page.
2412         const SwPageFrm* pPageFrm = FindPageFrm();
2413         // <--
2414         // --> OD 2004-07-01 #i28701# - re-factoring
2415         sal_uInt32 i = 0;
2416         for ( ; i < GetDrawObjs()->Count(); ++i )
2417         {
2418             SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[i];
2419             if ( _bNoInvaOfAsCharAnchoredObjs &&
2420                  (pAnchoredObj->GetFrmFmt().GetAnchor().GetAnchorId()
2421                     == FLY_AS_CHAR) )
2422             {
2423                 continue;
2424             }
2425             // --> OD 2004-10-08 #i26945# - no invalidation, if anchored object
2426             // isn't registered at the same page and instead is registered at
2427             // the page, where its anchor character text frame is on.
2428             if ( pAnchoredObj->GetPageFrm() &&
2429                  pAnchoredObj->GetPageFrm() != pPageFrm )
2430             {
2431                 SwTxtFrm* pAnchorCharFrm = pAnchoredObj->FindAnchorCharFrm();
2432                 if ( pAnchorCharFrm &&
2433                      pAnchoredObj->GetPageFrm() == pAnchorCharFrm->FindPageFrm() )
2434                 {
2435                     continue;
2436                 }
2437                 // --> OD 2004-11-24 #115759# - unlock its position, if anchored
2438                 // object isn't registered at the page, where its anchor
2439                 // character text frame is on, respectively if it has no
2440                 // anchor character text frame.
2441                 else
2442                 {
2443                     pAnchoredObj->UnlockPosition();
2444                 }
2445                 // <--
2446             }
2447             // <--
2448             // --> OD 2005-07-18 #i51474# - reset flag, that anchored object
2449             // has cleared environment, and unlock its position, if the anchored
2450             // object is registered at the same page as the anchor frame is on.
2451             if ( pAnchoredObj->ClearedEnvironment() &&
2452                  pAnchoredObj->GetPageFrm() &&
2453                  pAnchoredObj->GetPageFrm() == pPageFrm )
2454             {
2455                 pAnchoredObj->UnlockPosition();
2456                 pAnchoredObj->SetClearedEnvironment( false );
2457             }
2458             // <--
2459             // distinguish between writer fly frames and drawing objects
2460             if ( pAnchoredObj->ISA(SwFlyFrm) )
2461             {
2462                 SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
2463                 pFly->_Invalidate();
2464                 pFly->_InvalidatePos();
2465                 if ( !_bInvaPosOnly )
2466                     pFly->_InvalidateSize();
2467             }
2468             else
2469             {
2470                 pAnchoredObj->InvalidateObjPos();
2471             } // end of distinction between writer fly frames and drawing objects
2472 
2473         } // end of loop on objects, which are connected to the frame
2474 	}
2475 }
2476 
2477 /*************************************************************************
2478 |*
2479 |*  SwLayoutFrm::NotifyLowerObjs()
2480 |*
2481 |*************************************************************************/
2482 // --> OD 2004-07-01 #i28701# - change purpose of method and its name
2483 // --> OD 2004-10-08 #i26945# - correct check, if anchored object is a lower
2484 // of the layout frame. E.g., anchor character text frame can be a follow text
2485 // frame.
2486 // --> OD 2005-03-11 #i44016# - add parameter <_bUnlockPosOfObjs> to
2487 // force an unlockposition call for the lower objects.
NotifyLowerObjs(const bool _bUnlockPosOfObjs)2488 void SwLayoutFrm::NotifyLowerObjs( const bool _bUnlockPosOfObjs )
2489 {
2490     // invalidate lower floating screen objects
2491     SwPageFrm* pPageFrm = FindPageFrm();
2492     if ( pPageFrm && pPageFrm->GetSortedObjs() )
2493 	{
2494         SwSortedObjs& rObjs = *(pPageFrm->GetSortedObjs());
2495         for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i )
2496 		{
2497             SwAnchoredObject* pObj = rObjs[i];
2498             // --> OD 2004-10-08 #i26945# - check, if anchored object is a lower
2499             // of the layout frame is changed to check, if its anchor frame
2500             // is a lower of the layout frame.
2501             // determine the anchor frame - usually it's the anchor frame,
2502             // for at-character/as-character anchored objects the anchor character
2503             // text frame is taken.
2504             const SwFrm* pAnchorFrm = pObj->GetAnchorFrmContainingAnchPos();
2505             // <--
2506             if ( pObj->ISA(SwFlyFrm) )
2507 			{
2508                 SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pObj);
2509 
2510 				if ( pFly->Frm().Left() == WEIT_WECH )
2511 					continue;
2512 
2513                 if ( pFly->IsAnLower( this ) )
2514 					continue;
2515 
2516                 // --> OD 2004-10-08 #i26945# - use <pAnchorFrm> to check, if
2517                 // fly frame is lower of layout frame resp. if fly frame is
2518                 // at a different page registered as its anchor frame is on.
2519                 const bool bLow = IsAnLower( pAnchorFrm );
2520                 if ( bLow || pAnchorFrm->FindPageFrm() != pPageFrm )
2521                 // <--
2522 				{
2523                     pFly->_Invalidate( pPageFrm );
2524 					if ( !bLow || pFly->IsFlyAtCntFrm() )
2525                     {
2526                         // --> OD 2005-03-11 #i44016#
2527                         if ( _bUnlockPosOfObjs )
2528                         {
2529                             pFly->UnlockPosition();
2530                         }
2531                         // <--
2532                         pFly->_InvalidatePos();
2533                     }
2534 					else
2535 						pFly->_InvalidatePrt();
2536 				}
2537 			}
2538             else
2539             {
2540                 ASSERT( pObj->ISA(SwAnchoredDrawObject),
2541                         "<SwLayoutFrm::NotifyFlys() - anchored object of unexcepted type" );
2542                 // --> OD 2004-10-08 #i26945# - use <pAnchorFrm> to check, if
2543                 // fly frame is lower of layout frame resp. if fly frame is
2544                 // at a different page registered as its anchor frame is on.
2545                 if ( IsAnLower( pAnchorFrm ) ||
2546                      pAnchorFrm->FindPageFrm() != pPageFrm )
2547                 // <--
2548                 {
2549                     // --> OD 2005-03-11 #i44016#
2550                     if ( _bUnlockPosOfObjs )
2551                     {
2552                         pObj->UnlockPosition();
2553                     }
2554                     // <--
2555                     pObj->InvalidateObjPos();
2556                 }
2557             }
2558 		}
2559 	}
2560 }
2561 
2562 /*************************************************************************
2563 |*
2564 |*	SwFlyFrm::NotifyDrawObj()
2565 |*
2566 |*	Ersterstellung		OK 22. Nov. 94
2567 |*	Letzte Aenderung	MA 10. Jan. 97
2568 |*
2569 |*************************************************************************/
2570 
NotifyDrawObj()2571 void SwFlyFrm::NotifyDrawObj()
2572 {
2573     SwVirtFlyDrawObj* pObj = GetVirtDrawObj();
2574     pObj->SetRect();
2575     pObj->SetRectsDirty();
2576     pObj->SetChanged();
2577     pObj->BroadcastObjectChange();
2578 	if ( GetFmt()->GetSurround().IsContour() )
2579         ClrContourCache( pObj );
2580 }
2581 
2582 /*************************************************************************
2583 |*
2584 |*  SwFlyFrm::CalcRel()
2585 |*
2586 |*	Ersterstellung		MA 13. Jun. 96
2587 |*	Letzte Aenderung	MA 10. Oct. 96
2588 |*
2589 |*************************************************************************/
2590 
CalcRel(const SwFmtFrmSize & rSz) const2591 Size SwFlyFrm::CalcRel( const SwFmtFrmSize &rSz ) const
2592 {
2593 	Size aRet( rSz.GetSize() );
2594 
2595     const SwFrm *pRel = IsFlyLayFrm() ? GetAnchorFrm() : GetAnchorFrm()->GetUpper();
2596 	if( pRel ) // LAYER_IMPL
2597 	{
2598 		long nRelWidth = LONG_MAX, nRelHeight = LONG_MAX;
2599 		const ViewShell *pSh = getRootFrm()->GetCurrShell();
2600 		if ( ( pRel->IsBodyFrm() || pRel->IsPageFrm() ) &&
2601              pSh && pSh->GetViewOptions()->getBrowseMode() &&
2602 			 pSh->VisArea().HasArea() )
2603 		{
2604 			nRelWidth  = pSh->GetBrowseWidth();
2605 			nRelHeight = pSh->VisArea().Height();
2606 			Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() );
2607 			long nDiff = nRelWidth - pRel->Prt().Width();
2608 			if ( nDiff > 0 )
2609 				nRelWidth -= nDiff;
2610 			nRelHeight -= 2*aBorder.Height();
2611 			nDiff = nRelHeight - pRel->Prt().Height();
2612 			if ( nDiff > 0 )
2613 				nRelHeight -= nDiff;
2614 		}
2615 		nRelWidth  = Min( nRelWidth,  pRel->Prt().Width() );
2616 		nRelHeight = Min( nRelHeight, pRel->Prt().Height() );
2617         if( !pRel->IsPageFrm() )
2618         {
2619             const SwPageFrm* pPage = FindPageFrm();
2620             if( pPage )
2621             {
2622                 nRelWidth  = Min( nRelWidth,  pPage->Prt().Width() );
2623                 nRelHeight = Min( nRelHeight, pPage->Prt().Height() );
2624             }
2625         }
2626 
2627 		if ( rSz.GetWidthPercent() && rSz.GetWidthPercent() != 0xFF )
2628 			aRet.Width() = nRelWidth * rSz.GetWidthPercent() / 100;
2629 		if ( rSz.GetHeightPercent() && rSz.GetHeightPercent() != 0xFF )
2630 			aRet.Height() = nRelHeight * rSz.GetHeightPercent() / 100;
2631 
2632 		if ( rSz.GetWidthPercent() == 0xFF )
2633 		{
2634 			aRet.Width() *= aRet.Height();
2635 			aRet.Width() /= rSz.GetHeight();
2636 		}
2637 		else if ( rSz.GetHeightPercent() == 0xFF )
2638 		{
2639 			aRet.Height() *= aRet.Width();
2640 			aRet.Height() /= rSz.GetWidth();
2641 		}
2642     }
2643 	return aRet;
2644 }
2645 
2646 /*************************************************************************
2647 |*
2648 |*  SwFlyFrm::CalcAutoWidth()
2649 |*
2650 |*************************************************************************/
2651 
lcl_CalcAutoWidth(const SwLayoutFrm & rFrm)2652 SwTwips lcl_CalcAutoWidth( const SwLayoutFrm& rFrm )
2653 {
2654     SwTwips nRet = 0;
2655     SwTwips nMin = 0;
2656     const SwFrm* pFrm = rFrm.Lower();
2657 
2658     // No autowidth defined for columned frames
2659     if ( !pFrm || pFrm->IsColumnFrm() )
2660         return nRet;
2661 
2662     while ( pFrm )
2663     {
2664         if ( pFrm->IsSctFrm() )
2665         {
2666             nMin = lcl_CalcAutoWidth( *(SwSectionFrm*)pFrm );
2667         }
2668         if ( pFrm->IsTxtFrm() )
2669         {
2670             nMin = ((SwTxtFrm*)pFrm)->CalcFitToContent();
2671             const SvxLRSpaceItem &rSpace =
2672                 ((SwTxtFrm*)pFrm)->GetTxtNode()->GetSwAttrSet().GetLRSpace();
2673             if (!((SwTxtFrm*)pFrm)->IsLocked())
2674                 nMin += rSpace.GetRight() + rSpace.GetTxtLeft() + rSpace.GetTxtFirstLineOfst();
2675         }
2676         else if ( pFrm->IsTabFrm() )
2677         {
2678             const SwFmtFrmSize& rTblFmtSz = ((SwTabFrm*)pFrm)->GetTable()->GetFrmFmt()->GetFrmSize();
2679             if ( USHRT_MAX == rTblFmtSz.GetSize().Width() ||
2680                  text::HoriOrientation::NONE == ((SwTabFrm*)pFrm)->GetFmt()->GetHoriOrient().GetHoriOrient() )
2681             {
2682                 const SwPageFrm* pPage = rFrm.FindPageFrm();
2683                 // auto width table
2684                 nMin = pFrm->GetUpper()->IsVertical() ?
2685                     pPage->Prt().Height() :
2686                     pPage->Prt().Width();
2687             }
2688             else
2689             {
2690                 nMin = rTblFmtSz.GetSize().Width();
2691             }
2692         }
2693 
2694         if ( nMin > nRet )
2695             nRet = nMin;
2696 
2697         pFrm = pFrm->GetNext();
2698     }
2699 
2700     return nRet;
2701 }
2702 
CalcAutoWidth() const2703 SwTwips SwFlyFrm::CalcAutoWidth() const
2704 {
2705     return lcl_CalcAutoWidth( *this );
2706 }
2707 
2708 /*************************************************************************
2709 |*
2710 |*	SwFlyFrm::AddSpacesToFrm
2711 |*
2712 |*	Ersterstellung		MA 11. Nov. 96
2713 |*	Letzte Aenderung	MA 10. Mar. 97
2714 |*
2715 |*************************************************************************/
2716 
2717 //SwRect SwFlyFrm::AddSpacesToFrm() const
2718 //{
2719 //  SwRect aRect( Frm() );
2720 //  const SvxULSpaceItem &rUL = GetFmt()->GetULSpace();
2721 //  const SvxLRSpaceItem &rLR = GetFmt()->GetLRSpace();
2722 //  aRect.Left( Max( aRect.Left() - long(rLR.GetLeft()), 0L ) );
2723 //  aRect.SSize().Width() += rLR.GetRight();
2724 //  aRect.Top( Max( aRect.Top() - long(rUL.GetUpper()), 0L ) );
2725 //  aRect.SSize().Height()+= rUL.GetLower();
2726 //  return aRect;
2727 //}
2728 
2729 /*************************************************************************
2730 |*
2731 |*	SwFlyFrm::GetContour()
2732 |*
2733 |*	Ersterstellung		MA 09. Jan. 97
2734 |*	Letzte Aenderung	MA 10. Jan. 97
2735 |*
2736 |*************************************************************************/
2737 /// OD 16.04.2003 #i13147# - If called for paint and the <SwNoTxtFrm> contains
2738 /// a graphic, load of intrinsic graphic has to be avoided.
GetContour(PolyPolygon & rContour,const sal_Bool _bForPaint) const2739 sal_Bool SwFlyFrm::GetContour( PolyPolygon&   rContour,
2740                            const sal_Bool _bForPaint ) const
2741 {
2742 	sal_Bool bRet = sal_False;
2743 	if( GetFmt()->GetSurround().IsContour() && Lower() &&
2744 		Lower()->IsNoTxtFrm() )
2745 	{
2746 		SwNoTxtNode *pNd = (SwNoTxtNode*)((SwCntntFrm*)Lower())->GetNode();
2747         // OD 16.04.2003 #i13147# - determine <GraphicObject> instead of <Graphic>
2748         // in order to avoid load of graphic, if <SwNoTxtNode> contains a graphic
2749         // node and method is called for paint.
2750         const GraphicObject* pGrfObj = NULL;
2751         sal_Bool bGrfObjCreated = sal_False;
2752         const SwGrfNode* pGrfNd = pNd->GetGrfNode();
2753         if ( pGrfNd && _bForPaint )
2754         {
2755             pGrfObj = &(pGrfNd->GetGrfObj());
2756         }
2757         else
2758         {
2759             pGrfObj = new GraphicObject( pNd->GetGraphic() );
2760             bGrfObjCreated = sal_True;
2761         }
2762         ASSERT( pGrfObj, "SwFlyFrm::GetContour() - No Graphic/GraphicObject found at <SwNoTxtNode>." );
2763         if ( pGrfObj && pGrfObj->GetType() != GRAPHIC_NONE )
2764         {
2765             if( !pNd->HasContour() )
2766             {
2767                 // OD 16.04.2003 #i13147# - no <CreateContour> for a graphic
2768                 // during paint. Thus, return (value of <bRet> should be <sal_False>).
2769                 if ( pGrfNd && _bForPaint )
2770                 {
2771                     ASSERT( false, "SwFlyFrm::GetContour() - No Contour found at <SwNoTxtNode> during paint." );
2772                     return bRet;
2773                 }
2774                 pNd->CreateContour();
2775             }
2776             pNd->GetContour( rContour );
2777 			//Der Node haelt das Polygon passend zur Originalgroesse der Grafik
2778 			//hier muss die Skalierung einkalkuliert werden.
2779 			SwRect aClip;
2780 			SwRect aOrig;
2781 			Lower()->Calc();
2782 			((SwNoTxtFrm*)Lower())->GetGrfArea( aClip, &aOrig, sal_False );
2783             // OD 16.04.2003 #i13147# - copy method code <SvxContourDlg::ScaleContour(..)>
2784             // in order to avoid that graphic has to be loaded for contour scale.
2785             //SvxContourDlg::ScaleContour( rContour, aGrf, MAP_TWIP, aOrig.SSize() );
2786             {
2787                 OutputDevice*   pOutDev = Application::GetDefaultDevice();
2788                 const MapMode   aDispMap( MAP_TWIP );
2789                 const MapMode   aGrfMap( pGrfObj->GetPrefMapMode() );
2790                 const Size      aGrfSize( pGrfObj->GetPrefSize() );
2791                 double          fScaleX;
2792                 double          fScaleY;
2793                 Size            aOrgSize;
2794                 Point           aNewPoint;
2795                 sal_Bool            bPixelMap = aGrfMap.GetMapUnit() == MAP_PIXEL;
2796 
2797                 if ( bPixelMap )
2798                     aOrgSize = pOutDev->PixelToLogic( aGrfSize, aDispMap );
2799                 else
2800                     aOrgSize = pOutDev->LogicToLogic( aGrfSize, aGrfMap, aDispMap );
2801 
2802                 if ( aOrgSize.Width() && aOrgSize.Height() )
2803                 {
2804                     fScaleX = (double) aOrig.Width() / aOrgSize.Width();
2805                     fScaleY = (double) aOrig.Height() / aOrgSize.Height();
2806 
2807                     for ( sal_uInt16 j = 0, nPolyCount = rContour.Count(); j < nPolyCount; j++ )
2808                     {
2809                         Polygon& rPoly = rContour[ j ];
2810 
2811                         for ( sal_uInt16 i = 0, nCount = rPoly.GetSize(); i < nCount; i++ )
2812                         {
2813                             if ( bPixelMap )
2814                                 aNewPoint = pOutDev->PixelToLogic( rPoly[ i ], aDispMap  );
2815                             else
2816                                 aNewPoint = pOutDev->LogicToLogic( rPoly[ i ], aGrfMap, aDispMap  );
2817 
2818                             rPoly[ i ] = Point( FRound( aNewPoint.X() * fScaleX ), FRound( aNewPoint.Y() * fScaleY ) );
2819                         }
2820                     }
2821                 }
2822             }
2823             // OD 17.04.2003 #i13147# - destroy created <GraphicObject>.
2824             if ( bGrfObjCreated )
2825             {
2826                 delete pGrfObj;
2827             }
2828             rContour.Move( aOrig.Left(), aOrig.Top() );
2829             if( !aClip.Width() )
2830                 aClip.Width( 1 );
2831             if( !aClip.Height() )
2832                 aClip.Height( 1 );
2833             rContour.Clip( aClip.SVRect() );
2834 			rContour.Optimize(POLY_OPTIMIZE_CLOSE);
2835 			bRet = sal_True;
2836 		}
2837 	}
2838 	return bRet;
2839 }
2840 
2841 // OD 2004-03-25 #i26791#
GetVirtDrawObj() const2842 const SwVirtFlyDrawObj* SwFlyFrm::GetVirtDrawObj() const
2843 {
2844     return static_cast<const SwVirtFlyDrawObj*>(GetDrawObj());
2845 }
GetVirtDrawObj()2846 SwVirtFlyDrawObj* SwFlyFrm::GetVirtDrawObj()
2847 {
2848     return static_cast<SwVirtFlyDrawObj*>(DrawObj());
2849 }
2850 
2851 // =============================================================================
2852 // OD 2004-03-24 #i26791# - implementation of pure virtual method declared in
2853 // base class <SwAnchoredObject>
2854 // =============================================================================
InvalidateObjPos()2855 void SwFlyFrm::InvalidateObjPos()
2856 {
2857     InvalidatePos();
2858     // --> OD 2006-08-10 #i68520#
2859     InvalidateObjRectWithSpaces();
2860     // <--
2861 }
2862 
GetFrmFmt()2863 SwFrmFmt& SwFlyFrm::GetFrmFmt()
2864 {
2865     ASSERT( GetFmt(),
2866             "<SwFlyFrm::GetFrmFmt()> - missing frame format -> crash." );
2867     return *GetFmt();
2868 }
GetFrmFmt() const2869 const SwFrmFmt& SwFlyFrm::GetFrmFmt() const
2870 {
2871     ASSERT( GetFmt(),
2872             "<SwFlyFrm::GetFrmFmt()> - missing frame format -> crash." );
2873     return *GetFmt();
2874 }
2875 
GetObjRect() const2876 const SwRect SwFlyFrm::GetObjRect() const
2877 {
2878     return Frm();
2879 }
2880 
2881 // --> OD 2006-10-05 #i70122#
2882 // for Writer fly frames the bounding rectangle equals the object rectangles
GetObjBoundRect() const2883 const SwRect SwFlyFrm::GetObjBoundRect() const
2884 {
2885     return GetObjRect();
2886 }
2887 // <--
2888 
2889 // --> OD 2006-08-10 #i68520#
_SetObjTop(const SwTwips _nTop)2890 bool SwFlyFrm::_SetObjTop( const SwTwips _nTop )
2891 {
2892     const bool bChanged( Frm().Pos().Y() != _nTop );
2893 
2894     Frm().Pos().Y() = _nTop;
2895 
2896     return bChanged;
2897 }
_SetObjLeft(const SwTwips _nLeft)2898 bool SwFlyFrm::_SetObjLeft( const SwTwips _nLeft )
2899 {
2900     const bool bChanged( Frm().Pos().X() != _nLeft );
2901 
2902     Frm().Pos().X() = _nLeft;
2903 
2904     return bChanged;
2905 }
2906 // <--
2907 
2908 /** method to assure that anchored object is registered at the correct
2909     page frame
2910 
2911     OD 2004-07-02 #i28701#
2912 
2913     @author OD
2914 */
RegisterAtCorrectPage()2915 void SwFlyFrm::RegisterAtCorrectPage()
2916 {
2917     // default behaviour is to do nothing.
2918 }
2919 
2920 /** method to determine, if a <MakeAll()> on the Writer fly frame is possible
2921 
2922     OD 2004-05-11 #i28701#
2923 
2924     @author OD
2925 */
IsFormatPossible() const2926 bool SwFlyFrm::IsFormatPossible() const
2927 {
2928     return SwAnchoredObject::IsFormatPossible() &&
2929            !IsLocked() && !IsColLocked();
2930 }
2931 
GetAnchoredObjects(std::list<SwAnchoredObject * > & aList,const SwFmt & rFmt)2932 void SwFlyFrm::GetAnchoredObjects( std::list<SwAnchoredObject*>& aList, const SwFmt& rFmt )
2933 {
2934     SwIterator<SwFlyFrm,SwFmt> aIter( rFmt );
2935     for( SwFlyFrm* pFlyFrm = aIter.First(); pFlyFrm; pFlyFrm = aIter.Next() )
2936         aList.push_back( pFlyFrm );
2937 }
2938 
GetFmt() const2939 const SwFlyFrmFmt * SwFlyFrm::GetFmt() const
2940 {
2941     return static_cast< const SwFlyFrmFmt * >( GetDep() );
2942 }
2943 
GetFmt()2944 SwFlyFrmFmt * SwFlyFrm::GetFmt()
2945 {
2946     return static_cast< SwFlyFrmFmt * >( GetDep() );
2947 }
2948 
2949 //Bug 120881:Modify here for Directly Page Numbering
IsPageNumberingFrm()2950 sal_Bool SwFlyFrm::IsPageNumberingFrm()
2951 {
2952 	if (!GetAnchorFrm())//Invalidate frame...
2953 		return false;
2954 	if (bInCnt || bLayout)//Incorrect anchor type...
2955 		return false;
2956 	if (!(GetAnchorFrm()->IsTxtFrm() && GetAnchorFrm()->GetUpper()
2957 		&& (GetAnchorFrm()->GetUpper()->FindFooterOrHeader())))//Not in header or footer frame
2958 		return false;
2959 
2960 	if (pNextLink || pPrevLink)//Linked...
2961 		return false;
2962 
2963 	SwFrmFmt* pFmt = NULL;
2964 	if ((pFmt = GetFmt()))
2965 	{
2966 		if (pLower && pLower->GetNext() && pFmt->GetCol().GetNumCols()>1)//Has more than 1 column...
2967 			return false;
2968 	}
2969 
2970 	if (!pLower)//Do not has even 1 child frame?
2971 		return false;
2972 
2973 	for (SwFrm* pIter = pLower;pIter!=NULL;pIter=pIter->GetNext())
2974 	{
2975 		if (pIter->IsTxtFrm() && ((SwTxtFrm*)pIter)->HasPageNumberField())
2976 		{
2977 			return true;
2978 		}
2979 	}
2980 	return false;
2981 }
2982 
2983 //Bug 120881(End)
2984 
2985