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