merge the formfield patch from ooo-build
[ooovba.git] / sw / source / core / layout / fly.cxx
blob8899002e4e976d3a0ed0b100ed0fbce3ccac4841
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: fly.cxx,v $
10 * $Revision: 1.92.110.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 #include "hintids.hxx"
34 #include <svtools/itemiter.hxx>
35 #include <svtools/imap.hxx>
36 #ifndef _GRAPH_HXX //autogen
37 #include <vcl/graph.hxx>
38 #endif
39 #include <tools/poly.hxx>
40 #include <svx/contdlg.hxx>
41 #include <svx/protitem.hxx>
42 #include <svx/opaqitem.hxx>
43 #include <svx/ulspitem.hxx>
44 #include <svx/lrspitem.hxx>
45 #include <svx/frmdiritem.hxx>
46 #include <svx/keepitem.hxx>
47 #include <fmtanchr.hxx>
48 #include <fmtfsize.hxx>
49 #include <fmtclds.hxx>
50 #include <fmtcntnt.hxx>
51 #include <fmturl.hxx>
52 #include <fmtsrnd.hxx>
53 #include <fmtornt.hxx>
54 #include <fmtpdsc.hxx>
55 #include <fmtcnct.hxx>
56 #include <layhelp.hxx>
57 #include <ndtxt.hxx>
59 // OD 16.04.2003 #i13147# - for <SwFlyFrm::GetContour(..)>
60 #include <ndgrf.hxx>
61 // OD 29.10.2003 #113049#
62 #include <tolayoutanchoredobjectposition.hxx>
63 // OD 06.11.2003 #i22305#
64 #include <fmtfollowtextflow.hxx>
65 // --> OD 2004-06-28 #i28701#
66 #include <sortedobjs.hxx>
67 #include <objectformatter.hxx>
68 // <--
69 // OD 2004-04-06 #i26791#
70 #include <anchoredobject.hxx>
71 // --> OD 2006-01-31 #i53298#
72 #include <ndole.hxx>
73 // <--
74 #include <swtable.hxx>
76 #include "doc.hxx"
77 #include "viewsh.hxx"
78 #include "layouter.hxx"
79 #include "pagefrm.hxx"
80 #include "rootfrm.hxx"
81 #include "cntfrm.hxx"
82 #include "pam.hxx"
83 #include "frmatr.hxx"
84 #include "viewimp.hxx"
85 #include "errhdl.hxx"
86 #include "dcontact.hxx"
87 #include "dflyobj.hxx"
88 #include "dview.hxx"
89 #include "flyfrm.hxx"
90 #include "frmtool.hxx"
91 #include "frmfmt.hxx"
92 #include "hints.hxx"
93 #include "swregion.hxx"
94 #include "tabfrm.hxx"
95 #include "txtfrm.hxx"
96 #include "ndnotxt.hxx"
97 #include "notxtfrm.hxx" // GetGrfArea
98 #include "flyfrms.hxx"
99 #include "ndindex.hxx" // GetGrfArea
100 #include "sectfrm.hxx"
101 #include <vcl/svapp.hxx>
102 #include <vcl/salbtype.hxx> // FRound
104 using namespace ::com::sun::star;
107 // OD 2004-03-23 #i26791
108 TYPEINIT2(SwFlyFrm,SwLayoutFrm,SwAnchoredObject);
110 /*************************************************************************
112 |* SwFlyFrm::SwFlyFrm()
114 |* Ersterstellung MA 28. Sep. 92
115 |* Letzte Aenderung MA 09. Apr. 99
117 |*************************************************************************/
119 SwFlyFrm::SwFlyFrm( SwFlyFrmFmt *pFmt, SwFrm *pAnch ) :
120 SwLayoutFrm( pFmt ),
121 // OD 2004-03-22 #i26791#
122 SwAnchoredObject(),
123 // OD 2004-05-27 #i26791# - moved to <SwAnchoredObject>
124 // aRelPos(),
125 pPrevLink( 0 ),
126 pNextLink( 0 ),
127 bInCnt( FALSE ),
128 bAtCnt( FALSE ),
129 bLayout( FALSE ),
130 bAutoPosition( FALSE ),
131 bNoShrink( FALSE ),
132 bLockDeleteContent( FALSE )
134 nType = FRMC_FLY;
136 bInvalid = bNotifyBack = TRUE;
137 bLocked = bMinHeight =
138 bHeightClipped = bWidthClipped = bFormatHeightOnly = FALSE;
140 //Grosseneinstellung, Fixe groesse ist immer die Breite
141 const SwFmtFrmSize &rFrmSize = pFmt->GetFrmSize();
142 BOOL bVert = FALSE;
143 UINT16 nDir =
144 ((SvxFrameDirectionItem&)pFmt->GetFmtAttr( RES_FRAMEDIR )).GetValue();
145 if( FRMDIR_ENVIRONMENT == nDir )
147 bDerivedVert = 1;
148 bDerivedR2L = 1;
149 if( pAnch && pAnch->IsVertical() )
150 bVert = TRUE;
152 else
154 bInvalidVert = 0;
155 bDerivedVert = 0;
156 bDerivedR2L = 0;
157 if( FRMDIR_HORI_LEFT_TOP == nDir || FRMDIR_HORI_RIGHT_TOP == nDir
158 || pFmt->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE) )
159 bVertical = 0;
160 else
161 bVertical = 1;
162 bVert = bVertical;
163 bInvalidR2L = 0;
164 if( FRMDIR_HORI_RIGHT_TOP == nDir )
165 bRightToLeft = 1;
166 else
167 bRightToLeft = 0;
170 Frm().Width( rFrmSize.GetWidth() );
171 Frm().Height( rFrmSize.GetHeightSizeType() == ATT_VAR_SIZE ? MINFLY : rFrmSize.GetHeight() );
173 //Hoehe Fix oder Variabel oder was?
174 if ( rFrmSize.GetHeightSizeType() == ATT_MIN_SIZE )
175 bMinHeight = TRUE;
176 else if ( rFrmSize.GetHeightSizeType() == ATT_FIX_SIZE )
177 bFixSize = TRUE;
179 // OD 2004-02-12 #110582#-2 - insert columns, if necessary
180 InsertColumns();
182 //Erst das Init, dann den Inhalt, denn zum Inhalt koennen widerum
183 //Objekte/Rahmen gehoeren die dann angemeldet werden.
184 InitDrawObj( FALSE );
186 // OD 2004-01-19 #110582#
187 Chain( pAnch );
189 // OD 2004-01-19 #110582#
190 InsertCnt();
192 //Und erstmal in den Wald stellen die Kiste, damit bei neuen Dokument nicht
193 //unnoetig viel formatiert wird.
194 Frm().Pos().X() = Frm().Pos().Y() = WEIT_WECH;
197 // OD 2004-01-19 #110582#
198 void SwFlyFrm::Chain( SwFrm* _pAnch )
200 // Connect to chain neighboors.
201 // No problem, if a neighboor doesn't exist - the construction of the
202 // neighboor will make the connection
203 const SwFmtChain& rChain = GetFmt()->GetChain();
204 if ( rChain.GetPrev() || rChain.GetNext() )
206 if ( rChain.GetNext() )
208 SwFlyFrm* pFollow = FindChainNeighbour( *rChain.GetNext(), _pAnch );
209 if ( pFollow )
211 ASSERT( !pFollow->GetPrevLink(), "wrong chain detected" );
212 if ( !pFollow->GetPrevLink() )
213 SwFlyFrm::ChainFrames( this, pFollow );
216 if ( rChain.GetPrev() )
218 SwFlyFrm *pMaster = FindChainNeighbour( *rChain.GetPrev(), _pAnch );
219 if ( pMaster )
221 ASSERT( !pMaster->GetNextLink(), "wrong chain detected" );
222 if ( !pMaster->GetNextLink() )
223 SwFlyFrm::ChainFrames( pMaster, this );
229 // OD 2004-01-19 #110582#
230 void SwFlyFrm::InsertCnt()
232 if ( !GetPrevLink() )
234 const SwFmtCntnt& rCntnt = GetFmt()->GetCntnt();
235 ASSERT( rCntnt.GetCntntIdx(), ":-( no content prepared." );
236 ULONG nIndex = rCntnt.GetCntntIdx()->GetIndex();
237 // Lower() bedeutet SwColumnFrm, eingefuegt werden muss der Inhalt dann in den (Column)BodyFrm
238 ::_InsertCnt( Lower() ? (SwLayoutFrm*)((SwLayoutFrm*)Lower())->Lower() : (SwLayoutFrm*)this,
239 GetFmt()->GetDoc(), nIndex );
241 //NoTxt haben immer eine FixHeight.
242 if ( Lower() && Lower()->IsNoTxtFrm() )
244 bFixSize = TRUE;
245 bMinHeight = FALSE;
250 // OD 2004-02-12 #110582#-2
251 void SwFlyFrm::InsertColumns()
253 // --> OD 2009-08-12 #i97379#
254 // Check, if column are allowed.
255 // Columns are not allowed for fly frames, which represent graphics or embedded objects.
256 const SwFmtCntnt& rCntnt = GetFmt()->GetCntnt();
257 ASSERT( rCntnt.GetCntntIdx(), "<SwFlyFrm::InsertColumns()> - no content prepared." );
258 SwNodeIndex aFirstCntnt( *(rCntnt.GetCntntIdx()), 1 );
259 if ( aFirstCntnt.GetNode().IsNoTxtNode() )
261 return;
263 // <--
265 const SwFmtCol &rCol = GetFmt()->GetCol();
266 if ( rCol.GetNumCols() > 1 )
268 //PrtArea ersteinmal so gross wie der Frm, damit die Spalten
269 //vernuenftig eingesetzt werden koennen; das schaukelt sich dann
270 //schon zurecht.
271 Prt().Width( Frm().Width() );
272 Prt().Height( Frm().Height() );
273 const SwFmtCol aOld; //ChgColumns() verlaesst sich darauf, dass auch ein
274 //Old-Wert hereingereicht wird.
275 ChgColumns( aOld, rCol );
279 /*************************************************************************
281 |* SwFlyFrm::~SwFlyFrm()
283 |* Ersterstellung MA 28. Sep. 92
284 |* Letzte Aenderung MA 07. Jul. 95
286 |*************************************************************************/
288 SwFlyFrm::~SwFlyFrm()
290 // Accessible objects for fly frames will be destroyed in this destructor.
291 // For frames bound as char or frames that don't have an anchor we have
292 // to do that ourselves. For any other frame the call RemoveFly at the
293 // anchor will do that.
294 if( IsAccessibleFrm() && GetFmt() && (IsFlyInCntFrm() || !GetAnchorFrm()) )
296 SwRootFrm *pRootFrm = FindRootFrm();
297 if( pRootFrm && pRootFrm->IsAnyShellAccessible() )
299 ViewShell *pVSh = pRootFrm->GetCurrShell();
300 if( pVSh && pVSh->Imp() )
302 // Lowers aren't disposed already, so we have to do a recursive
303 // dispose
304 pVSh->Imp()->DisposeAccessibleFrm( this, sal_True );
309 if( GetFmt() && !GetFmt()->GetDoc()->IsInDtor() )
311 // OD 2004-01-19 #110582#
312 Unchain();
314 // OD 2004-01-19 #110582#
315 DeleteCnt();
317 //Tschuess sagen.
318 if ( GetAnchorFrm() )
319 AnchorFrm()->RemoveFly( this );
322 FinitDrawObj();
325 // OD 2004-01-19 #110582#
326 void SwFlyFrm::Unchain()
328 if ( GetPrevLink() )
329 UnchainFrames( GetPrevLink(), this );
330 if ( GetNextLink() )
331 UnchainFrames( this, GetNextLink() );
334 // OD 2004-01-19 #110582#
335 void SwFlyFrm::DeleteCnt()
337 // #110582#-2
338 if ( IsLockDeleteContent() )
339 return;
341 SwFrm* pFrm = pLower;
342 while ( pFrm )
344 while ( pFrm->GetDrawObjs() && pFrm->GetDrawObjs()->Count() )
346 SwAnchoredObject *pAnchoredObj = (*pFrm->GetDrawObjs())[0];
347 if ( pAnchoredObj->ISA(SwFlyFrm) )
348 delete pAnchoredObj;
349 else if ( pAnchoredObj->ISA(SwAnchoredDrawObject) )
351 // OD 23.06.2003 #108784# - consider 'virtual' drawing objects
352 SdrObject* pObj = pAnchoredObj->DrawObj();
353 if ( pObj->ISA(SwDrawVirtObj) )
355 SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(pObj);
356 pDrawVirtObj->RemoveFromWriterLayout();
357 pDrawVirtObj->RemoveFromDrawingPage();
359 else
361 SwDrawContact* pContact =
362 static_cast<SwDrawContact*>(::GetUserCall( pObj ));
363 if ( pContact )
365 pContact->DisconnectFromLayout();
371 pFrm->Remove();
372 delete pFrm;
373 pFrm = pLower;
376 InvalidatePage();
379 /*************************************************************************
381 |* SwFlyFrm::InitDrawObj()
383 |* Ersterstellung MA 02. Dec. 94
384 |* Letzte Aenderung MA 30. Nov. 95
386 |*************************************************************************/
387 void SwFlyFrm::InitDrawObj( BOOL bNotify )
389 //ContactObject aus dem Format suchen. Wenn bereits eines existiert, so
390 //braucht nur eine neue Ref erzeugt werden, anderfalls ist es jetzt an
391 //der Zeit das Contact zu erzeugen.
392 SwClientIter aIter( *GetFmt() );
393 SwFlyDrawContact *pContact = (SwFlyDrawContact*)
394 aIter.First( TYPE(SwFlyDrawContact) );
395 IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess();
396 if ( !pContact )
398 // --> OD 2005-08-08 #i52858# - method name changed
399 pContact = new SwFlyDrawContact( (SwFlyFrmFmt*)GetFmt(),
400 pIDDMA->GetOrCreateDrawModel() );
401 // <--
403 ASSERT( pContact, "InitDrawObj failed" );
404 // OD 2004-03-22 #i26791#
405 SetDrawObj( *(pContact->CreateNewRef( this )) );
407 //Den richtigen Layer setzen.
408 // OD 2004-01-19 #110582#
409 SdrLayerID nHeavenId = pIDDMA->GetHeavenId();
410 SdrLayerID nHellId = pIDDMA->GetHellId();
411 // OD 2004-03-22 #i26791#
412 GetVirtDrawObj()->SetLayer( GetFmt()->GetOpaque().GetValue()
413 ? nHeavenId
414 : nHellId );
415 if ( bNotify )
416 NotifyDrawObj();
419 /*************************************************************************
421 |* SwFlyFrm::FinitDrawObj()
423 |* Ersterstellung MA 12. Dec. 94
424 |* Letzte Aenderung MA 15. May. 95
426 |*************************************************************************/
428 void SwFlyFrm::FinitDrawObj()
430 if ( !GetVirtDrawObj() )
431 return;
433 //Bei den SdrPageViews abmelden falls das Objekt dort noch selektiert ist.
434 if ( !GetFmt()->GetDoc()->IsInDtor() )
436 ViewShell *p1St = GetShell();
437 if ( p1St )
439 ViewShell *pSh = p1St;
441 { //z.Zt. kann das Drawing nur ein Unmark auf alles, weil das
442 //Objekt bereits Removed wurde.
443 if( pSh->HasDrawView() )
444 pSh->Imp()->GetDrawView()->UnmarkAll();
445 pSh = (ViewShell*)pSh->GetNext();
447 } while ( pSh != p1St );
451 //VirtObject mit in das Grab nehmen. Wenn das letzte VirObject
452 //zerstoert wird, mussen das DrawObject und DrawContact ebenfalls
453 //zerstoert werden.
454 SwFlyDrawContact *pMyContact = 0;
455 if ( GetFmt() )
457 SwClientIter aIter( *GetFmt() );
458 aIter.GoStart();
459 do {
460 if ( aIter()->ISA(SwFrm) && (SwFrm*)aIter() != this )
462 pMyContact = 0;
463 break;
465 if( !pMyContact && aIter()->ISA(SwFlyDrawContact) )
466 pMyContact = (SwFlyDrawContact*)aIter();
467 aIter++;
468 } while( aIter() );
471 // OD, OS 2004-03-31 #116203# - clear user call of Writer fly frame 'master'
472 // <SdrObject> to assure, that a <SwXFrame::dispose()> doesn't delete the
473 // Writer fly frame again.
474 if ( pMyContact )
476 pMyContact->GetMaster()->SetUserCall( 0 );
478 GetVirtDrawObj()->SetUserCall( 0 ); //Ruft sonst Delete des ContactObj
479 delete GetVirtDrawObj(); //Meldet sich selbst beim Master ab.
480 if ( pMyContact )
481 delete pMyContact; //zerstoert den Master selbst.
484 /*************************************************************************
486 |* SwFlyFrm::ChainFrames()
488 |* Ersterstellung MA 29. Oct. 97
489 |* Letzte Aenderung MA 20. Jan. 98
491 |*************************************************************************/
493 void SwFlyFrm::ChainFrames( SwFlyFrm *pMaster, SwFlyFrm *pFollow )
495 ASSERT( pMaster && pFollow, "uncomplete chain" );
496 ASSERT( !pMaster->GetNextLink(), "link can not be changed" );
497 ASSERT( !pFollow->GetPrevLink(), "link can not be changed" );
499 pMaster->pNextLink = pFollow;
500 pFollow->pPrevLink = pMaster;
502 if ( pMaster->ContainsCntnt() )
504 //Damit ggf. ein Textfluss zustande kommt muss invalidiert werden.
505 SwFrm *pInva = pMaster->FindLastLower();
506 SWRECTFN( pMaster )
507 const long nBottom = (pMaster->*fnRect->fnGetPrtBottom)();
508 while ( pInva )
510 if( (pInva->Frm().*fnRect->fnBottomDist)( nBottom ) <= 0 )
512 pInva->InvalidateSize();
513 pInva->Prepare( PREP_CLEAR );
514 pInva = pInva->FindPrev();
516 else
517 pInva = 0;
521 if ( pFollow->ContainsCntnt() )
523 //Es gibt nur noch den Inhalt des Masters, der Inhalt vom Follow
524 //hat keine Frames mehr (sollte immer nur genau ein leerer TxtNode sein).
525 SwFrm *pFrm = pFollow->ContainsCntnt();
526 ASSERT( !pFrm->IsTabFrm() && !pFrm->FindNext(), "follow in chain contains content" );
527 pFrm->Cut();
528 delete pFrm;
531 // invalidate accessible relation set (accessibility wrapper)
532 ViewShell* pSh = pMaster->GetShell();
533 if( pSh && pSh->GetLayout()->IsAnyShellAccessible() )
534 pSh->Imp()->InvalidateAccessibleRelationSet( pMaster, pFollow );
538 void SwFlyFrm::UnchainFrames( SwFlyFrm *pMaster, SwFlyFrm *pFollow )
540 pMaster->pNextLink = 0;
541 pFollow->pPrevLink = 0;
543 if ( pFollow->ContainsCntnt() )
545 //Der Master saugt den Inhalt vom Follow auf
546 SwLayoutFrm *pUpper = pMaster;
547 if ( pUpper->Lower()->IsColumnFrm() )
549 pUpper = static_cast<SwLayoutFrm*>(pUpper->GetLastLower());
550 pUpper = static_cast<SwLayoutFrm*>(pUpper->Lower()); // der (Column)BodyFrm
551 ASSERT( pUpper && pUpper->IsColBodyFrm(), "Missing ColumnBody" );
553 SwFlyFrm *pFoll = pFollow;
554 while ( pFoll )
556 SwFrm *pTmp = ::SaveCntnt( pFoll );
557 if ( pTmp )
558 ::RestoreCntnt( pTmp, pUpper, pMaster->FindLastLower(), true );
559 pFoll->SetCompletePaint();
560 pFoll->InvalidateSize();
561 pFoll = pFoll->GetNextLink();
565 //Der Follow muss mit seinem eigenen Inhalt versorgt werden.
566 const SwFmtCntnt &rCntnt = pFollow->GetFmt()->GetCntnt();
567 ASSERT( rCntnt.GetCntntIdx(), ":-( Kein Inhalt vorbereitet." );
568 ULONG nIndex = rCntnt.GetCntntIdx()->GetIndex();
569 // Lower() bedeutet SwColumnFrm, dieser beinhaltet wieder einen SwBodyFrm
570 ::_InsertCnt( pFollow->Lower() ? (SwLayoutFrm*)((SwLayoutFrm*)pFollow->Lower())->Lower()
571 : (SwLayoutFrm*)pFollow,
572 pFollow->GetFmt()->GetDoc(), ++nIndex );
574 // invalidate accessible relation set (accessibility wrapper)
575 ViewShell* pSh = pMaster->GetShell();
576 if( pSh && pSh->GetLayout()->IsAnyShellAccessible() )
577 pSh->Imp()->InvalidateAccessibleRelationSet( pMaster, pFollow );
580 /*************************************************************************
582 |* SwFlyFrm::FindChainNeighbour()
584 |* Ersterstellung MA 11. Nov. 97
585 |* Letzte Aenderung MA 09. Apr. 99
587 |*************************************************************************/
589 SwFlyFrm *SwFlyFrm::FindChainNeighbour( SwFrmFmt &rChain, SwFrm *pAnch )
591 //Wir suchen denjenigen Fly, der in dem selben Bereich steht.
592 //Bereiche koennen zunaechst nur Kopf-/Fusszeilen oder Flys sein.
594 if ( !pAnch ) //Wenn ein Anchor uebergeben Wurde zaehlt dieser: Ctor!
595 pAnch = AnchorFrm();
597 SwLayoutFrm *pLay;
598 if ( pAnch->IsInFly() )
599 pLay = pAnch->FindFlyFrm();
600 else
602 //FindFooterOrHeader taugt hier nicht, weil evtl. noch keine Verbindung
603 //zum Anker besteht.
604 pLay = pAnch->GetUpper();
605 while ( pLay && !(pLay->GetType() & (FRM_HEADER|FRM_FOOTER)) )
606 pLay = pLay->GetUpper();
609 SwClientIter aIter( rChain );
610 SwFlyFrm *pFly = (SwFlyFrm*)aIter.First( TYPE(SwFlyFrm ) );
611 if ( pLay )
613 while ( pFly )
615 if ( pFly->GetAnchorFrm() )
617 if ( pFly->GetAnchorFrm()->IsInFly() )
619 if ( pFly->AnchorFrm()->FindFlyFrm() == pLay )
620 break;
622 else if ( pLay == pFly->FindFooterOrHeader() )
623 break;
625 pFly = (SwFlyFrm*)aIter.Next();
628 else if ( pFly )
630 ASSERT( !aIter.Next(), "chain with more than one inkarnation" );
632 return pFly;
636 /*************************************************************************
638 |* SwFlyFrm::FindLastLower()
640 |* Ersterstellung MA 29. Oct. 97
641 |* Letzte Aenderung MA 29. Oct. 97
643 |*************************************************************************/
645 SwFrm *SwFlyFrm::FindLastLower()
647 SwFrm *pRet = ContainsAny();
648 if ( pRet && pRet->IsInTab() )
649 pRet = pRet->FindTabFrm();
650 SwFrm *pNxt = pRet;
651 while ( pNxt && IsAnLower( pNxt ) )
652 { pRet = pNxt;
653 pNxt = pNxt->FindNext();
655 return pRet;
659 /*************************************************************************
661 |* SwFlyFrm::FrmSizeChg()
663 |* Ersterstellung MA 17. Dec. 92
664 |* Letzte Aenderung MA 24. Jul. 96
666 |*************************************************************************/
668 BOOL SwFlyFrm::FrmSizeChg( const SwFmtFrmSize &rFrmSize )
670 BOOL bRet = FALSE;
671 SwTwips nDiffHeight = Frm().Height();
672 if ( rFrmSize.GetHeightSizeType() == ATT_VAR_SIZE )
673 bFixSize = bMinHeight = FALSE;
674 else
676 if ( rFrmSize.GetHeightSizeType() == ATT_FIX_SIZE )
678 bFixSize = TRUE;
679 bMinHeight = FALSE;
681 else if ( rFrmSize.GetHeightSizeType() == ATT_MIN_SIZE )
683 bFixSize = FALSE;
684 bMinHeight = TRUE;
686 nDiffHeight -= rFrmSize.GetHeight();
688 //Wenn der Fly Spalten enthaehlt muessen der Fly und
689 //die Spalten schon einmal auf die Wunschwerte gebracht
690 //werden, sonst haben wir ein kleines Problem.
691 if ( Lower() )
693 if ( Lower()->IsColumnFrm() )
695 const SwRect aOld( GetObjRectWithSpaces() );
696 const Size aOldSz( Prt().SSize() );
697 const SwTwips nDiffWidth = Frm().Width() - rFrmSize.GetWidth();
698 aFrm.Height( aFrm.Height() - nDiffHeight );
699 aFrm.Width ( aFrm.Width() - nDiffWidth );
700 // --> OD 2006-08-16 #i68520#
701 InvalidateObjRectWithSpaces();
702 // <--
703 aPrt.Height( aPrt.Height() - nDiffHeight );
704 aPrt.Width ( aPrt.Width() - nDiffWidth );
705 ChgLowersProp( aOldSz );
706 ::Notify( this, FindPageFrm(), aOld );
707 bValidPos = FALSE;
708 bRet = TRUE;
710 else if ( Lower()->IsNoTxtFrm() )
712 bFixSize = TRUE;
713 bMinHeight = FALSE;
716 return bRet;
719 /*************************************************************************
721 |* SwFlyFrm::Modify()
723 |* Ersterstellung MA 17. Dec. 92
724 |* Letzte Aenderung MA 17. Jan. 97
726 |*************************************************************************/
728 void SwFlyFrm::Modify( SfxPoolItem * pOld, SfxPoolItem * pNew )
730 BYTE nInvFlags = 0;
732 if( pNew && RES_ATTRSET_CHG == pNew->Which() )
734 SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
735 SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
736 SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
737 SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
738 while( TRUE )
740 _UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(),
741 (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags,
742 &aOldSet, &aNewSet );
743 if( aNIter.IsAtEnd() )
744 break;
745 aNIter.NextItem();
746 aOIter.NextItem();
748 if ( aOldSet.Count() || aNewSet.Count() )
749 SwLayoutFrm::Modify( &aOldSet, &aNewSet );
751 else
752 _UpdateAttr( pOld, pNew, nInvFlags );
754 if ( nInvFlags != 0 )
756 _Invalidate();
757 if ( nInvFlags & 0x01 )
759 _InvalidatePos();
760 // --> OD 2006-08-16 #i68520#
761 InvalidateObjRectWithSpaces();
762 // <--
764 if ( nInvFlags & 0x02 )
766 _InvalidateSize();
767 // --> OD 2006-08-16 #i68520#
768 InvalidateObjRectWithSpaces();
769 // <--
771 if ( nInvFlags & 0x04 )
772 _InvalidatePrt();
773 if ( nInvFlags & 0x08 )
774 SetNotifyBack();
775 if ( nInvFlags & 0x10 )
776 SetCompletePaint();
777 if ( ( nInvFlags & 0x40 ) && Lower() && Lower()->IsNoTxtFrm() )
778 ClrContourCache( GetVirtDrawObj() );
779 SwRootFrm *pRoot;
780 if ( nInvFlags & 0x20 && 0 != (pRoot = FindRootFrm()) )
781 pRoot->InvalidateBrowseWidth();
782 // --> OD 2004-06-28 #i28701#
783 if ( nInvFlags & 0x80 )
785 // update sorted object lists, the Writer fly frame is registered at.
786 UpdateObjInSortedList();
788 // <--
791 // --> OD 2005-07-18 #i51474# - reset flags for the layout process
792 ResetLayoutProcessBools();
793 // <--
796 void SwFlyFrm::_UpdateAttr( SfxPoolItem *pOld, SfxPoolItem *pNew,
797 BYTE &rInvFlags,
798 SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
800 BOOL bClear = TRUE;
801 const USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
802 ViewShell *pSh = GetShell();
803 switch( nWhich )
805 case RES_VERT_ORIENT:
806 case RES_HORI_ORIENT:
807 // OD 22.09.2003 #i18732# - consider new option 'follow text flow'
808 case RES_FOLLOW_TEXT_FLOW:
810 //Achtung! _immer_ Aktion in ChgRePos() mitpflegen.
811 rInvFlags |= 0x09;
813 break;
814 // OD 2004-07-01 #i28701# - consider new option 'wrap influence on position'
815 case RES_WRAP_INFLUENCE_ON_OBJPOS:
817 rInvFlags |= 0x89;
819 break;
820 case RES_SURROUND:
822 // OD 2004-05-13 #i28701# - invalidate position on change of
823 // wrapping style.
824 //rInvFlags |= 0x40;
825 rInvFlags |= 0x41;
826 //Der Hintergrund muss benachrichtigt und Invalidiert werden.
827 const SwRect aTmp( GetObjRectWithSpaces() );
828 NotifyBackground( FindPageFrm(), aTmp, PREP_FLY_ATTR_CHG );
830 // Durch eine Umlaufaenderung von rahmengebundenen Rahmen kann eine
831 // vertikale Ausrichtung aktiviert/deaktiviert werden => MakeFlyPos
832 if( FLY_AT_FLY == GetFmt()->GetAnchor().GetAnchorId() )
833 rInvFlags |= 0x09;
835 //Ggf. die Kontur am Node loeschen.
836 if ( Lower() && Lower()->IsNoTxtFrm() &&
837 !GetFmt()->GetSurround().IsContour() )
839 SwNoTxtNode *pNd = (SwNoTxtNode*)((SwCntntFrm*)Lower())->GetNode();
840 if ( pNd->HasContour() )
841 pNd->SetContour( 0 );
843 // --> OD 2004-06-28 #i28701# - perform reorder of object lists
844 // at anchor frame and at page frame.
845 rInvFlags |= 0x80;
847 break;
849 case RES_PROTECT:
851 const SvxProtectItem *pP = (SvxProtectItem*)pNew;
852 GetVirtDrawObj()->SetMoveProtect( pP->IsPosProtected() );
853 GetVirtDrawObj()->SetResizeProtect( pP->IsSizeProtected() );
854 if( pSh && pSh->GetLayout()->IsAnyShellAccessible() )
855 pSh->Imp()->InvalidateAccessibleEditableState( sal_True, this );
856 break;
859 case RES_COL:
861 ChgColumns( *(const SwFmtCol*)pOld, *(const SwFmtCol*)pNew );
862 const SwFmtFrmSize &rNew = GetFmt()->GetFrmSize();
863 if ( FrmSizeChg( rNew ) )
864 NotifyDrawObj();
865 rInvFlags |= 0x1A;
866 break;
869 case RES_FRM_SIZE:
870 case RES_FMT_CHG:
872 const SwFmtFrmSize &rNew = GetFmt()->GetFrmSize();
873 if ( FrmSizeChg( rNew ) )
874 NotifyDrawObj();
875 rInvFlags |= 0x7F;
876 if ( RES_FMT_CHG == nWhich )
878 SwRect aNew( GetObjRectWithSpaces() );
879 SwRect aOld( aFrm );
880 const SvxULSpaceItem &rUL = ((SwFmtChg*)pOld)->pChangedFmt->GetULSpace();
881 aOld.Top( Max( aOld.Top() - long(rUL.GetUpper()), 0L ) );
882 aOld.SSize().Height()+= rUL.GetLower();
883 const SvxLRSpaceItem &rLR = ((SwFmtChg*)pOld)->pChangedFmt->GetLRSpace();
884 aOld.Left ( Max( aOld.Left() - long(rLR.GetLeft()), 0L ) );
885 aOld.SSize().Width() += rLR.GetRight();
886 aNew.Union( aOld );
887 NotifyBackground( FindPageFrm(), aNew, PREP_CLEAR );
889 //Dummer Fall. Bei der Zusweisung einer Vorlage k?nnen wir uns
890 //nicht auf das alte Spaltenattribut verlassen. Da diese
891 //wenigstens anzahlgemass fuer ChgColumns vorliegen muessen,
892 //bleibt uns nur einen temporaeres Attribut zu basteln.
893 SwFmtCol aCol;
894 if ( Lower() && Lower()->IsColumnFrm() )
896 USHORT nCol = 0;
897 SwFrm *pTmp = Lower();
899 { ++nCol;
900 pTmp = pTmp->GetNext();
901 } while ( pTmp );
902 aCol.Init( nCol, 0, 1000 );
904 ChgColumns( aCol, GetFmt()->GetCol() );
907 SwFmtURL aURL( GetFmt()->GetURL() );
908 if ( aURL.GetMap() )
910 const SwFmtFrmSize &rOld = nWhich == RES_FRM_SIZE ?
911 *(SwFmtFrmSize*)pNew :
912 ((SwFmtChg*)pOld)->pChangedFmt->GetFrmSize();
913 //#35091# Kann beim Laden von Vorlagen mal 0 sein
914 if ( rOld.GetWidth() && rOld.GetHeight() )
917 Fraction aScaleX( rOld.GetWidth(), rNew.GetWidth() );
918 Fraction aScaleY( rOld.GetHeight(), rOld.GetHeight() );
919 aURL.GetMap()->Scale( aScaleX, aScaleY );
920 SwFrmFmt *pFmt = GetFmt();
921 pFmt->LockModify();
922 pFmt->SetFmtAttr( aURL );
923 pFmt->UnlockModify();
926 const SvxProtectItem &rP = GetFmt()->GetProtect();
927 GetVirtDrawObj()->SetMoveProtect( rP.IsPosProtected() );
928 GetVirtDrawObj()->SetResizeProtect( rP.IsSizeProtected() );
930 if ( pSh )
931 pSh->InvalidateWindows( Frm() );
932 const IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess();
933 const BYTE nId = GetFmt()->GetOpaque().GetValue() ?
934 pIDDMA->GetHeavenId() :
935 pIDDMA->GetHellId();
936 GetVirtDrawObj()->SetLayer( nId );
938 if ( Lower() )
940 //Ggf. die Kontur am Node loeschen.
941 if( Lower()->IsNoTxtFrm() &&
942 !GetFmt()->GetSurround().IsContour() )
944 SwNoTxtNode *pNd = (SwNoTxtNode*)((SwCntntFrm*)Lower())->GetNode();
945 if ( pNd->HasContour() )
946 pNd->SetContour( 0 );
948 else if( !Lower()->IsColumnFrm() )
950 SwFrm* pFrm = GetLastLower();
951 if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
952 pFrm->Prepare( PREP_ADJUST_FRM );
956 // --> OD 2004-06-28 #i28701# - perform reorder of object lists
957 // at anchor frame and at page frame.
958 rInvFlags |= 0x80;
960 break;
962 case RES_UL_SPACE:
963 case RES_LR_SPACE:
965 rInvFlags |= 0x41;
966 if ( GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE) )
967 GetFmt()->GetDoc()->GetRootFrm()->InvalidateBrowseWidth();
968 SwRect aNew( GetObjRectWithSpaces() );
969 SwRect aOld( aFrm );
970 if ( RES_UL_SPACE == nWhich )
972 const SvxULSpaceItem &rUL = *(SvxULSpaceItem*)pNew;
973 aOld.Top( Max( aOld.Top() - long(rUL.GetUpper()), 0L ) );
974 aOld.SSize().Height()+= rUL.GetLower();
976 else
978 const SvxLRSpaceItem &rLR = *(SvxLRSpaceItem*)pNew;
979 aOld.Left ( Max( aOld.Left() - long(rLR.GetLeft()), 0L ) );
980 aOld.SSize().Width() += rLR.GetRight();
982 aNew.Union( aOld );
983 NotifyBackground( FindPageFrm(), aNew, PREP_CLEAR );
985 break;
987 case RES_BOX:
988 case RES_SHADOW:
989 rInvFlags |= 0x17;
990 break;
992 case RES_FRAMEDIR :
993 SetDerivedVert( FALSE );
994 SetDerivedR2L( FALSE );
995 CheckDirChange();
996 break;
998 case RES_OPAQUE:
1000 if ( pSh )
1001 pSh->InvalidateWindows( Frm() );
1003 const IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess();
1004 const BYTE nId = ((SvxOpaqueItem*)pNew)->GetValue() ?
1005 pIDDMA->GetHeavenId() :
1006 pIDDMA->GetHellId();
1007 GetVirtDrawObj()->SetLayer( nId );
1008 if( pSh && pSh->GetLayout()->IsAnyShellAccessible() )
1010 pSh->Imp()->DisposeAccessibleFrm( this );
1011 pSh->Imp()->AddAccessibleFrm( this );
1013 // --> OD 2004-06-28 #i28701# - perform reorder of object lists
1014 // at anchor frame and at page frame.
1015 rInvFlags |= 0x80;
1017 break;
1019 case RES_URL:
1020 //Das Interface arbeitet bei Textrahmen auf der Rahmengroesse,
1021 //die Map muss sich aber auf die FrmSize beziehen
1022 if ( (!Lower() || !Lower()->IsNoTxtFrm()) &&
1023 ((SwFmtURL*)pNew)->GetMap() && ((SwFmtURL*)pOld)->GetMap() )
1025 const SwFmtFrmSize &rSz = GetFmt()->GetFrmSize();
1026 if ( rSz.GetHeight() != Frm().Height() ||
1027 rSz.GetWidth() != Frm().Width() )
1029 SwFmtURL aURL( GetFmt()->GetURL() );
1030 Fraction aScaleX( Frm().Width(), rSz.GetWidth() );
1031 Fraction aScaleY( Frm().Height(), rSz.GetHeight() );
1032 aURL.GetMap()->Scale( aScaleX, aScaleY );
1033 SwFrmFmt *pFmt = GetFmt();
1034 pFmt->LockModify();
1035 pFmt->SetFmtAttr( aURL );
1036 pFmt->UnlockModify();
1039 /* Keine Invalidierung notwendig */
1040 break;
1042 case RES_CHAIN:
1044 SwFmtChain *pChain = (SwFmtChain*)pNew;
1045 if ( pChain->GetNext() )
1047 SwFlyFrm *pFollow = FindChainNeighbour( *pChain->GetNext() );
1048 if ( GetNextLink() && pFollow != GetNextLink() )
1049 SwFlyFrm::UnchainFrames( this, GetNextLink());
1050 if ( pFollow )
1052 if ( pFollow->GetPrevLink() &&
1053 pFollow->GetPrevLink() != this )
1054 SwFlyFrm::UnchainFrames( pFollow->GetPrevLink(),
1055 pFollow );
1056 if ( !GetNextLink() )
1057 SwFlyFrm::ChainFrames( this, pFollow );
1060 else if ( GetNextLink() )
1061 SwFlyFrm::UnchainFrames( this, GetNextLink() );
1062 if ( pChain->GetPrev() )
1064 SwFlyFrm *pMaster = FindChainNeighbour( *pChain->GetPrev() );
1065 if ( GetPrevLink() && pMaster != GetPrevLink() )
1066 SwFlyFrm::UnchainFrames( GetPrevLink(), this );
1067 if ( pMaster )
1069 if ( pMaster->GetNextLink() &&
1070 pMaster->GetNextLink() != this )
1071 SwFlyFrm::UnchainFrames( pMaster,
1072 pMaster->GetNextLink() );
1073 if ( !GetPrevLink() )
1074 SwFlyFrm::ChainFrames( pMaster, this );
1077 else if ( GetPrevLink() )
1078 SwFlyFrm::UnchainFrames( GetPrevLink(), this );
1081 default:
1082 bClear = FALSE;
1084 if ( bClear )
1086 if ( pOldSet || pNewSet )
1088 if ( pOldSet )
1089 pOldSet->ClearItem( nWhich );
1090 if ( pNewSet )
1091 pNewSet->ClearItem( nWhich );
1093 else
1094 SwLayoutFrm::Modify( pOld, pNew );
1098 /*************************************************************************
1100 |* SwFlyFrm::GetInfo()
1102 |* Beschreibung erfragt Informationen
1103 |* Ersterstellung JP 31.03.94
1104 |* Letzte Aenderung JP 31.03.94
1106 *************************************************************************/
1108 // erfrage vom Modify Informationen
1109 BOOL SwFlyFrm::GetInfo( SfxPoolItem & rInfo ) const
1111 if( RES_AUTOFMT_DOCNODE == rInfo.Which() )
1112 return FALSE; // es gibt einen FlyFrm also wird er benutzt
1113 return TRUE; // weiter suchen
1116 /*************************************************************************
1118 |* SwFlyFrm::_Invalidate()
1120 |* Ersterstellung MA 15. Oct. 92
1121 |* Letzte Aenderung MA 26. Jun. 96
1123 |*************************************************************************/
1125 void SwFlyFrm::_Invalidate( SwPageFrm *pPage )
1127 InvalidatePage( pPage );
1128 bNotifyBack = bInvalid = TRUE;
1130 SwFlyFrm *pFrm;
1131 if ( GetAnchorFrm() && 0 != (pFrm = AnchorFrm()->FindFlyFrm()) )
1133 //Gaanz dumm: Wenn der Fly innerhalb eines Fly gebunden ist, der
1134 //Spalten enthaehlt, sollte das Format von diesem ausgehen.
1135 if ( !pFrm->IsLocked() && !pFrm->IsColLocked() &&
1136 pFrm->Lower() && pFrm->Lower()->IsColumnFrm() )
1137 pFrm->InvalidateSize();
1140 // --> OD 2008-01-21 #i85216#
1141 // if vertical position is oriented at a layout frame inside a ghost section,
1142 // assure that the position is invalidated and that the information about
1143 // the vertical position oriented frame is cleared
1144 if ( GetVertPosOrientFrm() && GetVertPosOrientFrm()->IsLayoutFrm() )
1146 const SwSectionFrm* pSectFrm( GetVertPosOrientFrm()->FindSctFrm() );
1147 if ( pSectFrm && pSectFrm->GetSection() == 0 )
1149 InvalidatePos();
1150 ClearVertPosOrientFrm();
1153 // <--
1156 /*************************************************************************
1158 |* SwFlyFrm::ChgRelPos()
1160 |* Beschreibung Aenderung der relativen Position, die Position wird
1161 |* damit automatisch Fix, das Attribut wird entprechend angepasst.
1162 |* Ersterstellung MA 25. Aug. 92
1163 |* Letzte Aenderung MA 09. Aug. 95
1165 |*************************************************************************/
1167 void SwFlyFrm::ChgRelPos( const Point &rNewPos )
1169 if ( GetCurrRelPos() != rNewPos )
1171 SwFrmFmt *pFmt = GetFmt();
1172 const bool bVert = GetAnchorFrm()->IsVertical();
1173 const SwTwips nNewY = bVert ? rNewPos.X() : rNewPos.Y();
1174 SwTwips nTmpY = nNewY == LONG_MAX ? 0 : nNewY;
1175 if( bVert )
1176 nTmpY = -nTmpY;
1177 SfxItemSet aSet( pFmt->GetDoc()->GetAttrPool(),
1178 RES_VERT_ORIENT, RES_HORI_ORIENT);
1180 SwFmtVertOrient aVert( pFmt->GetVertOrient() );
1181 SwTxtFrm *pAutoFrm = NULL;
1182 // --> OD 2004-11-12 #i34948# - handle also at-page and at-fly anchored
1183 // Writer fly frames
1184 const RndStdIds eAnchorType = GetFrmFmt().GetAnchor().GetAnchorId();
1185 if ( eAnchorType == FLY_PAGE )
1187 aVert.SetVertOrient( text::VertOrientation::NONE );
1188 aVert.SetRelationOrient( text::RelOrientation::PAGE_FRAME );
1190 else if ( eAnchorType == FLY_AT_FLY )
1192 aVert.SetVertOrient( text::VertOrientation::NONE );
1193 aVert.SetRelationOrient( text::RelOrientation::FRAME );
1195 // <--
1196 else if ( IsFlyAtCntFrm() || text::VertOrientation::NONE != aVert.GetVertOrient() )
1198 if( text::RelOrientation::CHAR == aVert.GetRelationOrient() && IsAutoPos() )
1200 if( LONG_MAX != nNewY )
1202 aVert.SetVertOrient( text::VertOrientation::NONE );
1203 xub_StrLen nOfs =
1204 pFmt->GetAnchor().GetCntntAnchor()->nContent.GetIndex();
1205 ASSERT( GetAnchorFrm()->IsTxtFrm(), "TxtFrm expected" );
1206 pAutoFrm = (SwTxtFrm*)GetAnchorFrm();
1207 while( pAutoFrm->GetFollow() &&
1208 pAutoFrm->GetFollow()->GetOfst() <= nOfs )
1210 if( pAutoFrm == GetAnchorFrm() )
1211 nTmpY += pAutoFrm->GetRelPos().Y();
1212 nTmpY -= pAutoFrm->GetUpper()->Prt().Height();
1213 pAutoFrm = pAutoFrm->GetFollow();
1215 nTmpY = ((SwFlyAtCntFrm*)this)->GetRelCharY(pAutoFrm)-nTmpY;
1217 else
1218 aVert.SetVertOrient( text::VertOrientation::CHAR_BOTTOM );
1220 else
1222 aVert.SetVertOrient( text::VertOrientation::NONE );
1223 aVert.SetRelationOrient( text::RelOrientation::FRAME );
1226 aVert.SetPos( nTmpY );
1227 aSet.Put( aVert );
1229 //Fuer Flys im Cnt ist die horizontale Ausrichtung uninteressant,
1230 //den sie ist stets 0.
1231 if ( !IsFlyInCntFrm() )
1233 const SwTwips nNewX = bVert ? rNewPos.Y() : rNewPos.X();
1234 SwTwips nTmpX = nNewX == LONG_MAX ? 0 : nNewX;
1235 SwFmtHoriOrient aHori( pFmt->GetHoriOrient() );
1236 // --> OD 2004-11-12 #i34948# - handle also at-page and at-fly anchored
1237 // Writer fly frames
1238 if ( eAnchorType == FLY_PAGE )
1240 aHori.SetHoriOrient( text::HoriOrientation::NONE );
1241 aHori.SetRelationOrient( text::RelOrientation::PAGE_FRAME );
1242 aHori.SetPosToggle( FALSE );
1244 else if ( eAnchorType == FLY_AT_FLY )
1246 aHori.SetHoriOrient( text::HoriOrientation::NONE );
1247 aHori.SetRelationOrient( text::RelOrientation::FRAME );
1248 aHori.SetPosToggle( FALSE );
1250 // <--
1251 else if ( IsFlyAtCntFrm() || text::HoriOrientation::NONE != aHori.GetHoriOrient() )
1253 aHori.SetHoriOrient( text::HoriOrientation::NONE );
1254 if( text::RelOrientation::CHAR == aHori.GetRelationOrient() && IsAutoPos() )
1256 if( LONG_MAX != nNewX )
1258 if( !pAutoFrm )
1260 xub_StrLen nOfs = pFmt->GetAnchor().GetCntntAnchor()
1261 ->nContent.GetIndex();
1262 ASSERT( GetAnchorFrm()->IsTxtFrm(), "TxtFrm expected");
1263 pAutoFrm = (SwTxtFrm*)GetAnchorFrm();
1264 while( pAutoFrm->GetFollow() &&
1265 pAutoFrm->GetFollow()->GetOfst() <= nOfs )
1266 pAutoFrm = pAutoFrm->GetFollow();
1268 nTmpX -= ((SwFlyAtCntFrm*)this)->GetRelCharX(pAutoFrm);
1271 else
1272 aHori.SetRelationOrient( text::RelOrientation::FRAME );
1273 aHori.SetPosToggle( FALSE );
1275 aHori.SetPos( nTmpX );
1276 aSet.Put( aHori );
1278 pFmt->GetDoc()->SetAttr( aSet, *pFmt );
1281 /*************************************************************************
1283 |* SwFlyFrm::Format()
1285 |* Beschreibung: "Formatiert" den Frame; Frm und PrtArea.
1286 |* Die Fixsize wird hier nicht eingestellt.
1287 |* Ersterstellung MA 14. Jun. 93
1288 |* Letzte Aenderung MA 13. Jun. 96
1290 |*************************************************************************/
1292 void SwFlyFrm::Format( const SwBorderAttrs *pAttrs )
1294 ASSERT( pAttrs, "FlyFrm::Format, pAttrs ist 0." );
1296 ColLock();
1298 if ( !bValidSize )
1300 if ( Frm().Top() == WEIT_WECH && Frm().Left() == WEIT_WECH )
1302 //Sicherheitsschaltung wegnehmen (siehe SwFrm::CTor)
1303 Frm().Pos().X() = Frm().Pos().Y() = 0;
1304 // --> OD 2006-08-16 #i68520#
1305 InvalidateObjRectWithSpaces();
1306 // <--
1309 //Breite der Spalten pruefen und ggf. einstellen.
1310 if ( Lower() && Lower()->IsColumnFrm() )
1311 AdjustColumns( 0, FALSE );
1313 bValidSize = TRUE;
1315 const SwTwips nUL = pAttrs->CalcTopLine() + pAttrs->CalcBottomLine();
1316 const SwTwips nLR = pAttrs->CalcLeftLine() + pAttrs->CalcRightLine();
1317 const SwFmtFrmSize &rFrmSz = GetFmt()->GetFrmSize();
1318 Size aRelSize( CalcRel( rFrmSz ) );
1320 ASSERT( pAttrs->GetSize().Height() != 0 || rFrmSz.GetHeightPercent(), "Hoehe des RahmenAttr ist 0." );
1321 ASSERT( pAttrs->GetSize().Width() != 0 || rFrmSz.GetWidthPercent(), "Breite des RahmenAttr ist 0." );
1323 SWRECTFN( this )
1324 if( !HasFixSize() )
1326 SwTwips nRemaining = 0;
1328 long nMinHeight = 0;
1329 if( IsMinHeight() )
1330 nMinHeight = bVert ? aRelSize.Width() : aRelSize.Height();
1332 if ( Lower() )
1334 if ( Lower()->IsColumnFrm() )
1336 FormatWidthCols( *pAttrs, nUL, nMinHeight );
1337 nRemaining = (Lower()->Frm().*fnRect->fnGetHeight)();
1339 else
1341 SwFrm *pFrm = Lower();
1342 while ( pFrm )
1344 nRemaining += (pFrm->Frm().*fnRect->fnGetHeight)();
1345 if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
1346 // Dieser TxtFrm waere gern ein bisschen groesser
1347 nRemaining += ((SwTxtFrm*)pFrm)->GetParHeight()
1348 - (pFrm->Prt().*fnRect->fnGetHeight)();
1349 else if( pFrm->IsSctFrm() && ((SwSectionFrm*)pFrm)->IsUndersized() )
1350 nRemaining += ((SwSectionFrm*)pFrm)->Undersize();
1351 pFrm = pFrm->GetNext();
1353 // --> OD 2006-02-09 #130878#
1354 // Do not keep old height, if content has no height.
1355 // The old height could be wrong due to wrong layout cache
1356 // and isn't corrected in the further formatting, because
1357 // the fly frame doesn't become invalid anymore.
1358 // if( !nRemaining )
1359 // nRemaining = nOldHeight - nUL;
1360 // <--
1362 if ( GetDrawObjs() )
1364 sal_uInt32 nCnt = GetDrawObjs()->Count();
1365 SwTwips nTop = (Frm().*fnRect->fnGetTop)();
1366 SwTwips nBorder = (Frm().*fnRect->fnGetHeight)() -
1367 (Prt().*fnRect->fnGetHeight)();
1368 for ( USHORT i = 0; i < nCnt; ++i )
1370 SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[i];
1371 if ( pAnchoredObj->ISA(SwFlyFrm) )
1373 SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
1374 // OD 06.11.2003 #i22305# - consider
1375 // only Writer fly frames, which follow the text flow.
1376 if ( pFly->IsFlyLayFrm() &&
1377 pFly->Frm().Top() != WEIT_WECH &&
1378 pFly->GetFmt()->GetFollowTextFlow().GetValue() )
1380 SwTwips nDist = -(pFly->Frm().*fnRect->
1381 fnBottomDist)( nTop );
1382 if( nDist > nBorder + nRemaining )
1383 nRemaining = nDist - nBorder;
1390 if( IsMinHeight() && (nRemaining + nUL) < nMinHeight )
1391 nRemaining = nMinHeight - nUL;
1392 //Weil das Grow/Shrink der Flys die Groessen nicht direkt
1393 //einstellt, sondern indirekt per Invalidate ein Format
1394 //ausloesst, muessen die Groessen hier direkt eingestellt
1395 //werden. Benachrichtung laeuft bereits mit.
1396 //Weil bereits haeufiger 0en per Attribut hereinkamen wehre
1397 //ich mich ab sofort dagegen.
1398 if ( nRemaining < MINFLY )
1399 nRemaining = MINFLY;
1400 (Prt().*fnRect->fnSetHeight)( nRemaining );
1401 nRemaining -= (Frm().*fnRect->fnGetHeight)();
1402 (Frm().*fnRect->fnAddBottom)( nRemaining + nUL );
1403 // --> OD 2006-08-16 #i68520#
1404 if ( nRemaining + nUL != 0 )
1406 InvalidateObjRectWithSpaces();
1408 // <--
1409 bValidSize = TRUE;
1411 else
1413 bValidSize = TRUE; //Fixe Frms formatieren sich nicht.
1414 //Flys stellen ihre Groesse anhand des Attr ein.
1415 SwTwips nNewSize = bVert ? aRelSize.Width() : aRelSize.Height();
1416 nNewSize -= nUL;
1417 if( nNewSize < MINFLY )
1418 nNewSize = MINFLY;
1419 (Prt().*fnRect->fnSetHeight)( nNewSize );
1420 nNewSize += nUL - (Frm().*fnRect->fnGetHeight)();
1421 (Frm().*fnRect->fnAddBottom)( nNewSize );
1422 // --> OD 2006-08-16 #i68520#
1423 if ( nNewSize != 0 )
1425 InvalidateObjRectWithSpaces();
1427 // <--
1430 if ( !bFormatHeightOnly )
1432 ASSERT( aRelSize == CalcRel( rFrmSz ), "SwFlyFrm::Format CalcRel problem" )
1433 SwTwips nNewSize = bVert ? aRelSize.Height() : aRelSize.Width();
1435 if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
1437 // #i9046# Autowidth for fly frames
1438 const SwTwips nAutoWidth = CalcAutoWidth();
1439 if ( nAutoWidth )
1441 if( ATT_MIN_SIZE == rFrmSz.GetWidthSizeType() )
1442 nNewSize = Max( nNewSize - nLR, nAutoWidth );
1443 else
1444 nNewSize = nAutoWidth;
1447 else
1448 nNewSize -= nLR;
1450 if( nNewSize < MINFLY )
1451 nNewSize = MINFLY;
1452 (Prt().*fnRect->fnSetWidth)( nNewSize );
1453 nNewSize += nLR - (Frm().*fnRect->fnGetWidth)();
1454 (Frm().*fnRect->fnAddRight)( nNewSize );
1455 // --> OD 2006-08-16 #i68520#
1456 if ( nNewSize != 0 )
1458 InvalidateObjRectWithSpaces();
1460 // <--
1463 ColUnlock();
1466 // OD 14.03.2003 #i11760# - change parameter <bNoColl>: type <bool>;
1467 // default value = false.
1468 // OD 14.03.2003 #i11760# - add new parameter <bNoCalcFollow> with
1469 // default value = false.
1470 // OD 11.04.2003 #108824# - new parameter <bNoCalcFollow> was used by method
1471 // <FormatWidthCols(..)> to avoid follow formatting
1472 // for text frames. But, unformatted follows causes
1473 // problems in method <SwCntntFrm::_WouldFit(..)>,
1474 // which assumes that the follows are formatted.
1475 // Thus, <bNoCalcFollow> no longer used by <FormatWidthCols(..)>.
1476 //void CalcCntnt( SwLayoutFrm *pLay, BOOL bNoColl )
1477 void CalcCntnt( SwLayoutFrm *pLay,
1478 bool bNoColl,
1479 bool bNoCalcFollow )
1481 SwSectionFrm* pSect;
1482 BOOL bCollect = FALSE;
1483 if( pLay->IsSctFrm() )
1485 pSect = (SwSectionFrm*)pLay;
1486 if( pSect->IsEndnAtEnd() && !bNoColl )
1488 bCollect = TRUE;
1489 SwLayouter::CollectEndnotes( pLay->GetFmt()->GetDoc(), pSect );
1491 pSect->CalcFtnCntnt();
1493 else
1494 pSect = NULL;
1495 SwFrm *pFrm = pLay->ContainsAny();
1496 if ( !pFrm )
1498 if( pSect )
1500 if( pSect->HasFollow() )
1501 pFrm = pSect->GetFollow()->ContainsAny();
1502 if( !pFrm )
1504 if( pSect->IsEndnAtEnd() )
1506 if( bCollect )
1507 pLay->GetFmt()->GetDoc()->GetLayouter()->
1508 InsertEndnotes( pSect );
1509 BOOL bLock = pSect->IsFtnLock();
1510 pSect->SetFtnLock( TRUE );
1511 pSect->CalcFtnCntnt();
1512 pSect->CalcFtnCntnt();
1513 pSect->SetFtnLock( bLock );
1515 return;
1517 pFrm->_InvalidatePos();
1519 else
1520 return;
1522 pFrm->InvalidatePage();
1526 // local variables to avoid loops caused by anchored object positioning
1527 SwAnchoredObject* pAgainObj1 = 0;
1528 SwAnchoredObject* pAgainObj2 = 0;
1530 // FME 2007-08-30 #i81146# new loop control
1531 USHORT nLoopControlRuns = 0;
1532 const USHORT nLoopControlMax = 20;
1533 const SwFrm* pLoopControlCond = 0;
1535 SwFrm* pLast;
1538 pLast = pFrm;
1539 if( pFrm->IsVertical() ?
1540 ( pFrm->GetUpper()->Prt().Height() != pFrm->Frm().Height() )
1541 : ( pFrm->GetUpper()->Prt().Width() != pFrm->Frm().Width() ) )
1543 pFrm->Prepare( PREP_FIXSIZE_CHG );
1544 pFrm->_InvalidateSize();
1547 if ( pFrm->IsTabFrm() )
1549 ((SwTabFrm*)pFrm)->bCalcLowers = TRUE;
1550 // OD 26.08.2003 #i18103# - lock move backward of follow table,
1551 // if no section content is formatted or follow table belongs
1552 // to the section, which content is formatted.
1553 if ( ((SwTabFrm*)pFrm)->IsFollow() &&
1554 ( !pSect || pSect == pFrm->FindSctFrm() ) )
1556 ((SwTabFrm*)pFrm)->bLockBackMove = TRUE;
1560 // OD 14.03.2003 #i11760# - forbid format of follow, if requested.
1561 if ( bNoCalcFollow && pFrm->IsTxtFrm() )
1562 static_cast<SwTxtFrm*>(pFrm)->ForbidFollowFormat();
1564 pFrm->Calc();
1566 // OD 14.03.2003 #i11760# - reset control flag for follow format.
1567 if ( pFrm->IsTxtFrm() )
1569 static_cast<SwTxtFrm*>(pFrm)->AllowFollowFormat();
1572 // #111937# The keep-attribute can cause the position
1573 // of the prev to be invalid:
1574 // OD 2004-03-15 #116560# - Do not consider invalid previous frame
1575 // due to its keep-attribute, if current frame is a follow or is locked.
1576 // --> OD 2005-03-08 #i44049# - do not consider invalid previous
1577 // frame due to its keep-attribute, if it can't move forward.
1578 // --> OD 2006-01-27 #i57765# - do not consider invalid previous
1579 // frame, if current frame has a column/page break before attribute.
1580 SwFrm* pTmpPrev = pFrm->FindPrev();
1581 SwFlowFrm* pTmpPrevFlowFrm = pTmpPrev && pTmpPrev->IsFlowFrm() ? SwFlowFrm::CastFlowFrm(pTmpPrev) : 0;
1582 SwFlowFrm* pTmpFlowFrm = pFrm->IsFlowFrm() ? SwFlowFrm::CastFlowFrm(pFrm) : 0;
1584 bool bPrevInvalid = pTmpPrevFlowFrm && pTmpFlowFrm &&
1585 !pTmpFlowFrm->IsFollow() &&
1586 !StackHack::IsLocked() && // #i76382#
1587 !pTmpFlowFrm->IsJoinLocked() &&
1588 !pTmpPrev->GetValidPosFlag() &&
1589 pLay->IsAnLower( pTmpPrev ) &&
1590 pTmpPrevFlowFrm->IsKeep( *pTmpPrev->GetAttrSet() ) &&
1591 pTmpPrevFlowFrm->IsKeepFwdMoveAllowed();
1592 // <--
1594 // format floating screen objects anchored to the frame.
1595 bool bRestartLayoutProcess = false;
1596 if ( !bPrevInvalid && pFrm->GetDrawObjs() && pLay->IsAnLower( pFrm ) )
1598 bool bAgain = false;
1599 SwPageFrm* pPageFrm = pFrm->FindPageFrm();
1600 sal_uInt32 nCnt = pFrm->GetDrawObjs()->Count();
1601 for ( USHORT i = 0; i < nCnt; ++i )
1603 // --> OD 2004-07-01 #i28701#
1604 SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i];
1605 // determine, if anchored object has to be formatted.
1606 if ( pAnchoredObj->PositionLocked() )
1608 continue;
1611 // format anchored object
1612 if ( pAnchoredObj->IsFormatPossible() )
1614 // --> OD 2005-05-17 #i43737# - no invalidation of
1615 // anchored object needed - causes loops for as-character
1616 // anchored objects.
1617 //pAnchoredObj->InvalidateObjPos();
1618 // <--
1619 SwRect aRect( pAnchoredObj->GetObjRect() );
1620 if ( !SwObjectFormatter::FormatObj( *pAnchoredObj, pFrm, pPageFrm ) )
1622 bRestartLayoutProcess = true;
1623 break;
1625 // --> OD 2004-08-25 #i3317# - restart layout process,
1626 // if the position of the anchored object is locked now.
1627 if ( pAnchoredObj->PositionLocked() )
1629 bRestartLayoutProcess = true;
1630 break;
1632 // <--
1634 if ( aRect != pAnchoredObj->GetObjRect() )
1636 bAgain = true;
1637 if ( pAgainObj2 == pAnchoredObj )
1639 ASSERT( false,
1640 "::CalcCntnt(..) - loop detected, perform attribute changes to avoid the loop" );
1641 //Oszillation unterbinden.
1642 SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt();
1643 SwFmtSurround aAttr( rFmt.GetSurround() );
1644 if( SURROUND_THROUGHT != aAttr.GetSurround() )
1646 // Bei autopositionierten hilft manchmal nur
1647 // noch, auf Durchlauf zu schalten
1648 if( rFmt.GetAnchor().GetAnchorId() == FLY_AUTO_CNTNT &&
1649 SURROUND_PARALLEL == aAttr.GetSurround() )
1650 aAttr.SetSurround( SURROUND_THROUGHT );
1651 else
1652 aAttr.SetSurround( SURROUND_PARALLEL );
1653 rFmt.LockModify();
1654 rFmt.SetFmtAttr( aAttr );
1655 rFmt.UnlockModify();
1658 else
1660 if ( pAgainObj1 == pAnchoredObj )
1661 pAgainObj2 = pAnchoredObj;
1662 pAgainObj1 = pAnchoredObj;
1666 if ( !pFrm->GetDrawObjs() )
1667 break;
1668 if ( pFrm->GetDrawObjs()->Count() < nCnt )
1670 --i;
1671 --nCnt;
1676 // --> OD 2004-06-11 #i28701# - restart layout process, if
1677 // requested by floating screen object formatting
1678 if ( bRestartLayoutProcess )
1680 pFrm = pLay->ContainsAny();
1681 pAgainObj1 = 0L;
1682 pAgainObj2 = 0L;
1683 continue;
1686 // OD 2004-05-17 #i28701# - format anchor frame after its objects
1687 // are formatted, if the wrapping style influence has to be considered.
1688 if ( pLay->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) )
1690 pFrm->Calc();
1692 // <--
1694 if ( bAgain )
1696 pFrm = pLay->ContainsCntnt();
1697 if ( pFrm && pFrm->IsInTab() )
1698 pFrm = pFrm->FindTabFrm();
1699 if( pFrm && pFrm->IsInSct() )
1701 SwSectionFrm* pTmp = pFrm->FindSctFrm();
1702 if( pTmp != pLay && pLay->IsAnLower( pTmp ) )
1703 pFrm = pTmp;
1706 if ( pFrm == pLoopControlCond )
1707 ++nLoopControlRuns;
1708 else
1710 nLoopControlRuns = 0;
1711 pLoopControlCond = pFrm;
1714 if ( nLoopControlRuns < nLoopControlMax )
1715 continue;
1717 #if OSL_DEBUG_LEVEL > 1
1718 ASSERT( false, "LoopControl in CalcCntnt" )
1719 #endif
1722 if ( pFrm->IsTabFrm() )
1724 if ( ((SwTabFrm*)pFrm)->IsFollow() )
1725 ((SwTabFrm*)pFrm)->bLockBackMove = FALSE;
1728 pFrm = bPrevInvalid ? pTmpPrev : pFrm->FindNext();
1729 if( !bPrevInvalid && pFrm && pFrm->IsSctFrm() && pSect )
1731 // Es koennen hier leere SectionFrms herumspuken
1732 while( pFrm && pFrm->IsSctFrm() && !((SwSectionFrm*)pFrm)->GetSection() )
1733 pFrm = pFrm->FindNext();
1734 // Wenn FindNext den Follow des urspruenglichen Bereichs liefert,
1735 // wollen wir mit dessen Inhalt weitermachen, solange dieser
1736 // zurueckfliesst.
1737 if( pFrm && pFrm->IsSctFrm() && ( pFrm == pSect->GetFollow() ||
1738 ((SwSectionFrm*)pFrm)->IsAnFollow( pSect ) ) )
1740 pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
1741 if( pFrm )
1742 pFrm->_InvalidatePos();
1745 // Im pLay bleiben, Ausnahme, bei SectionFrms mit Follow wird der erste
1746 // CntntFrm des Follows anformatiert, damit er die Chance erhaelt, in
1747 // pLay zu landen. Solange diese Frames in pLay landen, geht's weiter.
1748 } while ( pFrm &&
1749 ( pLay->IsAnLower( pFrm ) ||
1750 ( pSect &&
1751 ( ( pSect->HasFollow() &&
1752 ( pLay->IsAnLower( pLast ) ||
1753 ( pLast->IsInSct() &&
1754 pLast->FindSctFrm()->IsAnFollow(pSect) ) ) &&
1755 pSect->GetFollow()->IsAnLower( pFrm ) ) ||
1756 ( pFrm->IsInSct() &&
1757 pFrm->FindSctFrm()->IsAnFollow( pSect ) ) ) ) ) );
1758 if( pSect )
1760 if( bCollect )
1762 pLay->GetFmt()->GetDoc()->GetLayouter()->InsertEndnotes(pSect);
1763 pSect->CalcFtnCntnt();
1765 if( pSect->HasFollow() )
1767 SwSectionFrm* pNxt = pSect->GetFollow();
1768 while( pNxt && !pNxt->ContainsCntnt() )
1769 pNxt = pNxt->GetFollow();
1770 if( pNxt )
1771 pNxt->CalcFtnCntnt();
1773 if( bCollect )
1775 pFrm = pLay->ContainsAny();
1776 bCollect = FALSE;
1777 if( pFrm )
1778 continue;
1781 break;
1783 while( TRUE );
1786 /*************************************************************************
1788 |* SwFlyFrm::MakeFlyPos()
1790 |* Ersterstellung MA ??
1791 |* Letzte Aenderung MA 14. Nov. 96
1793 |*************************************************************************/
1794 // OD 2004-03-23 #i26791#
1795 //void SwFlyFrm::MakeFlyPos()
1796 void SwFlyFrm::MakeObjPos()
1798 if ( !bValidPos )
1800 bValidPos = TRUE;
1802 // OD 29.10.2003 #113049# - use new class to position object
1803 GetAnchorFrm()->Calc();
1804 objectpositioning::SwToLayoutAnchoredObjectPosition
1805 aObjPositioning( *GetVirtDrawObj() );
1806 aObjPositioning.CalcPosition();
1808 // --> OD 2006-10-05 #i58280#
1809 // update relative position
1810 SetCurrRelPos( aObjPositioning.GetRelPos() );
1811 // <--
1813 SWRECTFN( GetAnchorFrm() );
1814 aFrm.Pos( aObjPositioning.GetRelPos() );
1815 aFrm.Pos() += (GetAnchorFrm()->Frm().*fnRect->fnGetPos)();
1816 // --> OD 2006-09-11 #i69335#
1817 InvalidateObjRectWithSpaces();
1818 // <--
1822 /*************************************************************************
1824 |* SwFlyFrm::MakePrtArea()
1826 |* Ersterstellung MA 23. Jun. 93
1827 |* Letzte Aenderung MA 23. Jun. 93
1829 |*************************************************************************/
1830 void SwFlyFrm::MakePrtArea( const SwBorderAttrs &rAttrs )
1833 if ( !bValidPrtArea )
1835 bValidPrtArea = TRUE;
1837 // OD 31.07.2003 #110978# - consider vertical layout
1838 SWRECTFN( this )
1839 (this->*fnRect->fnSetXMargins)( rAttrs.CalcLeftLine(),
1840 rAttrs.CalcRightLine() );
1841 (this->*fnRect->fnSetYMargins)( rAttrs.CalcTopLine(),
1842 rAttrs.CalcBottomLine() );
1846 /*************************************************************************
1848 |* SwFlyFrm::_Grow(), _Shrink()
1850 |* Ersterstellung MA 05. Oct. 92
1851 |* Letzte Aenderung MA 05. Sep. 96
1853 |*************************************************************************/
1855 SwTwips SwFlyFrm::_Grow( SwTwips nDist, BOOL bTst )
1857 SWRECTFN( this )
1858 if ( Lower() && !IsColLocked() && !HasFixSize() )
1860 SwTwips nSize = (Frm().*fnRect->fnGetHeight)();
1861 if( nSize > 0 && nDist > ( LONG_MAX - nSize ) )
1862 nDist = LONG_MAX - nSize;
1864 if ( nDist <= 0L )
1865 return 0L;
1867 if ( Lower()->IsColumnFrm() )
1868 { //Bei Spaltigkeit ubernimmt das Format die Kontrolle ueber
1869 //das Wachstum (wg. des Ausgleichs).
1870 if ( !bTst )
1872 // --> OD 2004-06-09 #i28701# - unlock position of Writer fly frame
1873 UnlockPosition();
1874 _InvalidatePos();
1875 InvalidateSize();
1877 return 0L;
1880 if ( !bTst )
1882 const SwRect aOld( GetObjRectWithSpaces() );
1883 _InvalidateSize();
1884 const BOOL bOldLock = bLocked;
1885 Unlock();
1886 if ( IsFlyFreeFrm() )
1888 // --> OD 2004-11-12 #i37068# - no format of position here
1889 // and prevent move in method <CheckClip(..)>.
1890 // This is needed to prevent layout loop caused by nested
1891 // Writer fly frames - inner Writer fly frames format its
1892 // anchor, which grows/shrinks the outer Writer fly frame.
1893 // Note: position will be invalidated below.
1894 bValidPos = TRUE;
1895 // --> OD 2005-10-10 #i55416#
1896 // Suppress format of width for autowidth frame, because the
1897 // format of the width would call <SwTxtFrm::CalcFitToContent()>
1898 // for the lower frame, which initiated this grow.
1899 const BOOL bOldFormatHeightOnly = bFormatHeightOnly;
1900 const SwFmtFrmSize& rFrmSz = GetFmt()->GetFrmSize();
1901 if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
1903 bFormatHeightOnly = TRUE;
1905 // <--
1906 static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( true );
1907 ((SwFlyFreeFrm*)this)->SwFlyFreeFrm::MakeAll();
1908 static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( false );
1909 // --> OD 2005-10-10 #i55416#
1910 if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
1912 bFormatHeightOnly = bOldFormatHeightOnly;
1914 // <--
1915 // <--
1917 else
1918 MakeAll();
1919 _InvalidateSize();
1920 InvalidatePos();
1921 if ( bOldLock )
1922 Lock();
1923 const SwRect aNew( GetObjRectWithSpaces() );
1924 if ( aOld != aNew )
1925 ::Notify( this, FindPageFrm(), aOld );
1926 return (aNew.*fnRect->fnGetHeight)()-(aOld.*fnRect->fnGetHeight)();
1928 return nDist;
1930 return 0L;
1933 SwTwips SwFlyFrm::_Shrink( SwTwips nDist, BOOL bTst )
1935 if( Lower() && !IsColLocked() && !HasFixSize() && !IsNoShrink() )
1937 SWRECTFN( this )
1938 SwTwips nHeight = (Frm().*fnRect->fnGetHeight)();
1939 if ( nDist > nHeight )
1940 nDist = nHeight;
1942 SwTwips nVal = nDist;
1943 if ( IsMinHeight() )
1945 const SwFmtFrmSize& rFmtSize = GetFmt()->GetFrmSize();
1946 SwTwips nFmtHeight = bVert ? rFmtSize.GetWidth() : rFmtSize.GetHeight();
1948 nVal = Min( nDist, nHeight - nFmtHeight );
1951 if ( nVal <= 0L )
1952 return 0L;
1954 if ( Lower()->IsColumnFrm() )
1955 { //Bei Spaltigkeit ubernimmt das Format die Kontrolle ueber
1956 //das Wachstum (wg. des Ausgleichs).
1957 if ( !bTst )
1959 SwRect aOld( GetObjRectWithSpaces() );
1960 (Frm().*fnRect->fnSetHeight)( nHeight - nVal );
1961 // --> OD 2006-08-16 #i68520#
1962 if ( nHeight - nVal != 0 )
1964 InvalidateObjRectWithSpaces();
1966 // <--
1967 nHeight = (Prt().*fnRect->fnGetHeight)();
1968 (Prt().*fnRect->fnSetHeight)( nHeight - nVal );
1969 _InvalidatePos();
1970 InvalidateSize();
1971 ::Notify( this, FindPageFrm(), aOld );
1972 NotifyDrawObj();
1973 if ( GetAnchorFrm()->IsInFly() )
1974 AnchorFrm()->FindFlyFrm()->Shrink( nDist, bTst );
1976 return 0L;
1979 if ( !bTst )
1981 const SwRect aOld( GetObjRectWithSpaces() );
1982 _InvalidateSize();
1983 const BOOL bOldLocked = bLocked;
1984 Unlock();
1985 if ( IsFlyFreeFrm() )
1987 // --> OD 2004-11-12 #i37068# - no format of position here
1988 // and prevent move in method <CheckClip(..)>.
1989 // This is needed to prevent layout loop caused by nested
1990 // Writer fly frames - inner Writer fly frames format its
1991 // anchor, which grows/shrinks the outer Writer fly frame.
1992 // Note: position will be invalidated below.
1993 bValidPos = TRUE;
1994 // --> OD 2005-10-10 #i55416#
1995 // Suppress format of width for autowidth frame, because the
1996 // format of the width would call <SwTxtFrm::CalcFitToContent()>
1997 // for the lower frame, which initiated this shrink.
1998 const BOOL bOldFormatHeightOnly = bFormatHeightOnly;
1999 const SwFmtFrmSize& rFrmSz = GetFmt()->GetFrmSize();
2000 if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
2002 bFormatHeightOnly = TRUE;
2004 // <--
2005 static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( true );
2006 ((SwFlyFreeFrm*)this)->SwFlyFreeFrm::MakeAll();
2007 static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( false );
2008 // --> OD 2005-10-10 #i55416#
2009 if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
2011 bFormatHeightOnly = bOldFormatHeightOnly;
2013 // <--
2014 // <--
2016 else
2017 MakeAll();
2018 _InvalidateSize();
2019 InvalidatePos();
2020 if ( bOldLocked )
2021 Lock();
2022 const SwRect aNew( GetObjRectWithSpaces() );
2023 if ( aOld != aNew )
2025 ::Notify( this, FindPageFrm(), aOld );
2026 if ( GetAnchorFrm()->IsInFly() )
2027 AnchorFrm()->FindFlyFrm()->Shrink( nDist, bTst );
2029 return (aOld.*fnRect->fnGetHeight)() -
2030 (aNew.*fnRect->fnGetHeight)();
2032 return nVal;
2034 return 0L;
2037 /*************************************************************************
2039 |* SwFlyFrm::ChgSize()
2041 |* Ersterstellung MA 05. Oct. 92
2042 |* Letzte Aenderung MA 04. Sep. 96
2044 |*************************************************************************/
2046 Size SwFlyFrm::ChgSize( const Size& aNewSize )
2048 // --> OD 2006-01-19 #i53298#
2049 // If the fly frame anchored at-paragraph or at-character contains an OLE
2050 // object, assure that the new size fits into the current clipping area
2051 // of the fly frame
2052 Size aAdjustedNewSize( aNewSize );
2054 if ( dynamic_cast<SwFlyAtCntFrm*>(this) &&
2055 Lower() && dynamic_cast<SwNoTxtFrm*>(Lower()) &&
2056 static_cast<SwNoTxtFrm*>(Lower())->GetNode()->GetOLENode() )
2058 SwRect aClipRect;
2059 ::CalcClipRect( GetVirtDrawObj(), aClipRect, FALSE );
2060 if ( aAdjustedNewSize.Width() > aClipRect.Width() )
2062 aAdjustedNewSize.setWidth( aClipRect.Width() );
2064 if ( aAdjustedNewSize.Height() > aClipRect.Height() )
2066 aAdjustedNewSize.setWidth( aClipRect.Height() );
2070 // <--
2071 if ( aAdjustedNewSize != Frm().SSize() )
2073 SwFrmFmt *pFmt = GetFmt();
2074 SwFmtFrmSize aSz( pFmt->GetFrmSize() );
2075 aSz.SetWidth( aAdjustedNewSize.Width() );
2076 // --> OD 2006-01-19 #i53298# - no tolerance any more.
2077 // If it reveals that the tolerance is still needed, then suppress a
2078 // <SetAttr> call, if <aSz> equals the current <SwFmtFrmSize> attribute.
2079 // if ( Abs(aAdjustedNewSize.Height() - aSz.GetHeight()) > 1 )
2080 aSz.SetHeight( aAdjustedNewSize.Height() );
2081 // <--
2082 // uebers Doc fuers Undo!
2083 pFmt->GetDoc()->SetAttr( aSz, *pFmt );
2084 return aSz.GetSize();
2086 else
2087 return Frm().SSize();
2090 /*************************************************************************
2092 |* SwFlyFrm::IsLowerOf()
2094 |* Ersterstellung MA 27. Dec. 93
2095 |* Letzte Aenderung MA 27. Dec. 93
2097 |*************************************************************************/
2099 BOOL SwFlyFrm::IsLowerOf( const SwLayoutFrm* pUpperFrm ) const
2101 ASSERT( GetAnchorFrm(), "8-( Fly is lost in Space." );
2102 const SwFrm* pFrm = GetAnchorFrm();
2105 if ( pFrm == pUpperFrm )
2106 return TRUE;
2107 pFrm = pFrm->IsFlyFrm()
2108 ? ((const SwFlyFrm*)pFrm)->GetAnchorFrm()
2109 : pFrm->GetUpper();
2110 } while ( pFrm );
2111 return FALSE;
2114 /*************************************************************************
2116 |* SwFlyFrm::Cut()
2118 |* Ersterstellung MA 23. Feb. 94
2119 |* Letzte Aenderung MA 23. Feb. 94
2121 |*************************************************************************/
2123 void SwFlyFrm::Cut()
2127 /*************************************************************************
2129 |* SwFrm::AppendFly(), RemoveFly()
2131 |* Ersterstellung MA 25. Aug. 92
2132 |* Letzte Aenderung MA 09. Jun. 95
2134 |*************************************************************************/
2136 void SwFrm::AppendFly( SwFlyFrm *pNew )
2138 if ( !pDrawObjs )
2139 pDrawObjs = new SwSortedObjs();
2140 pDrawObjs->Insert( *pNew );
2141 pNew->ChgAnchorFrm( this );
2143 //Bei der Seite anmelden; kann sein, dass noch keine da ist - die
2144 //Anmeldung wird dann in SwPageFrm::PreparePage durch gefuehrt.
2145 SwPageFrm *pPage = FindPageFrm();
2146 if ( pPage )
2148 if ( pNew->IsFlyAtCntFrm() && pNew->Frm().Top() == WEIT_WECH )
2150 //Versuch die Seitenformatierung von neuen Dokumenten etwas
2151 //guenstiger zu gestalten.
2152 //Wir haengen die Flys erstenmal nach hinten damit sie bei heftigem
2153 //Fluss der Anker nicht unoetig oft formatiert werden.
2154 //Damit man noch brauchbar an das Ende des Dokumentes springen
2155 //kann werden die Flys nicht ganz an das Ende gehaengt.
2156 SwRootFrm *pRoot = (SwRootFrm*)pPage->GetUpper();
2157 if( !SwLayHelper::CheckPageFlyCache( pPage, pNew ) )
2159 SwPageFrm *pTmp = pRoot->GetLastPage();
2160 if ( pTmp->GetPhyPageNum() > 30 )
2162 for ( USHORT i = 0; i < 10; ++i )
2164 pTmp = (SwPageFrm*)pTmp->GetPrev();
2165 if( pTmp->GetPhyPageNum() <= pPage->GetPhyPageNum() )
2166 break; // damit wir nicht vor unserem Anker landen
2168 if ( pTmp->IsEmptyPage() )
2169 pTmp = (SwPageFrm*)pTmp->GetPrev();
2170 pPage = pTmp;
2173 pPage->AppendFlyToPage( pNew );
2175 else
2176 pPage->AppendFlyToPage( pNew );
2180 void SwFrm::RemoveFly( SwFlyFrm *pToRemove )
2182 //Bei der Seite Abmelden - kann schon passiert sein weil die Seite
2183 //bereits destruiert wurde.
2184 SwPageFrm *pPage = pToRemove->FindPageFrm();
2185 if ( pPage && pPage->GetSortedObjs() )
2187 pPage->RemoveFlyFromPage( pToRemove );
2189 // --> OD 2008-05-19 #i73201#
2190 else
2192 if ( pToRemove->IsAccessibleFrm() &&
2193 pToRemove->GetFmt() &&
2194 !pToRemove->IsFlyInCntFrm() )
2196 SwRootFrm *pRootFrm = FindRootFrm();
2197 if( pRootFrm && pRootFrm->IsAnyShellAccessible() )
2199 ViewShell *pVSh = pRootFrm->GetCurrShell();
2200 if( pVSh && pVSh->Imp() )
2202 pVSh->Imp()->DisposeAccessibleFrm( pToRemove );
2207 // <--
2209 pDrawObjs->Remove( *pToRemove );
2210 if ( !pDrawObjs->Count() )
2211 DELETEZ( pDrawObjs );
2213 pToRemove->ChgAnchorFrm( 0 );
2215 if ( !pToRemove->IsFlyInCntFrm() && GetUpper() && IsInTab() )//MA_FLY_HEIGHT
2216 GetUpper()->InvalidateSize();
2219 /*************************************************************************
2221 |* SwFrm::AppendDrawObj(), RemoveDrawObj()
2223 |* --> OD 2004-07-06 #i28701# - new methods
2225 |*************************************************************************/
2226 void SwFrm::AppendDrawObj( SwAnchoredObject& _rNewObj )
2228 if ( !_rNewObj.ISA(SwAnchoredDrawObject) )
2230 ASSERT( false,
2231 "SwFrm::AppendDrawObj(..) - anchored object of unexcepted type -> object not appended" );
2232 return;
2235 if ( !_rNewObj.GetDrawObj()->ISA(SwDrawVirtObj) &&
2236 _rNewObj.GetAnchorFrm() && _rNewObj.GetAnchorFrm() != this )
2238 // perform disconnect from layout, if 'master' drawing object is appended
2239 // to a new frame.
2240 static_cast<SwDrawContact*>(::GetUserCall( _rNewObj.GetDrawObj() ))->
2241 DisconnectFromLayout( false );
2244 if ( _rNewObj.GetAnchorFrm() != this )
2246 if ( !pDrawObjs )
2247 pDrawObjs = new SwSortedObjs();
2248 pDrawObjs->Insert( _rNewObj );
2249 _rNewObj.ChgAnchorFrm( this );
2252 // no direct positioning needed, but invalidate the drawing object position
2253 _rNewObj.InvalidateObjPos();
2255 // register at page frame
2256 SwPageFrm* pPage = FindPageFrm();
2257 if ( pPage )
2259 pPage->AppendDrawObjToPage( _rNewObj );
2262 // Notify accessible layout.
2263 ViewShell* pSh = GetShell();
2264 if( pSh && pSh->GetLayout()->IsAnyShellAccessible() )
2266 pSh->Imp()->AddAccessibleObj( _rNewObj.GetDrawObj() );
2270 void SwFrm::RemoveDrawObj( SwAnchoredObject& _rToRemoveObj )
2272 // Notify accessible layout.
2273 ViewShell* pSh = GetShell();
2274 if( pSh && pSh->GetLayout()->IsAnyShellAccessible() )
2276 pSh->Imp()->DisposeAccessibleObj( _rToRemoveObj.GetDrawObj() );
2279 // deregister from page frame
2280 SwPageFrm* pPage = _rToRemoveObj.GetPageFrm();
2281 if ( pPage && pPage->GetSortedObjs() )
2282 pPage->RemoveDrawObjFromPage( _rToRemoveObj );
2284 pDrawObjs->Remove( _rToRemoveObj );
2285 if ( !pDrawObjs->Count() )
2286 DELETEZ( pDrawObjs );
2288 _rToRemoveObj.ChgAnchorFrm( 0 );
2291 /*************************************************************************
2293 |* SwFrm::InvalidateObjs()
2295 |* Ersterstellung MA 29. Nov. 96
2296 |* Letzte Aenderung MA 29. Nov. 96
2298 |*************************************************************************/
2299 // --> OD 2004-07-01 #i28701# - change purpose of method and adjust its name
2300 void SwFrm::InvalidateObjs( const bool _bInvaPosOnly,
2301 const bool _bNoInvaOfAsCharAnchoredObjs )
2303 if ( GetDrawObjs() )
2305 // --> OD 2004-10-08 #i26945# - determine page the frame is on,
2306 // in order to check, if anchored object is registered at the same
2307 // page.
2308 const SwPageFrm* pPageFrm = FindPageFrm();
2309 // <--
2310 // --> OD 2004-07-01 #i28701# - re-factoring
2311 sal_uInt32 i = 0;
2312 for ( ; i < GetDrawObjs()->Count(); ++i )
2314 SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[i];
2315 if ( _bNoInvaOfAsCharAnchoredObjs &&
2316 pAnchoredObj->GetFrmFmt().GetAnchor().GetAnchorId() == FLY_IN_CNTNT )
2318 continue;
2320 // --> OD 2004-10-08 #i26945# - no invalidation, if anchored object
2321 // isn't registered at the same page and instead is registered at
2322 // the page, where its anchor character text frame is on.
2323 if ( pAnchoredObj->GetPageFrm() &&
2324 pAnchoredObj->GetPageFrm() != pPageFrm )
2326 SwTxtFrm* pAnchorCharFrm = pAnchoredObj->FindAnchorCharFrm();
2327 if ( pAnchorCharFrm &&
2328 pAnchoredObj->GetPageFrm() == pAnchorCharFrm->FindPageFrm() )
2330 continue;
2332 // --> OD 2004-11-24 #115759# - unlock its position, if anchored
2333 // object isn't registered at the page, where its anchor
2334 // character text frame is on, respectively if it has no
2335 // anchor character text frame.
2336 else
2338 pAnchoredObj->UnlockPosition();
2340 // <--
2342 // <--
2343 // --> OD 2005-07-18 #i51474# - reset flag, that anchored object
2344 // has cleared environment, and unlock its position, if the anchored
2345 // object is registered at the same page as the anchor frame is on.
2346 if ( pAnchoredObj->ClearedEnvironment() &&
2347 pAnchoredObj->GetPageFrm() &&
2348 pAnchoredObj->GetPageFrm() == pPageFrm )
2350 pAnchoredObj->UnlockPosition();
2351 pAnchoredObj->SetClearedEnvironment( false );
2353 // <--
2354 // distinguish between writer fly frames and drawing objects
2355 if ( pAnchoredObj->ISA(SwFlyFrm) )
2357 SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
2358 pFly->_Invalidate();
2359 pFly->_InvalidatePos();
2360 if ( !_bInvaPosOnly )
2361 pFly->_InvalidateSize();
2363 else
2365 pAnchoredObj->InvalidateObjPos();
2366 } // end of distinction between writer fly frames and drawing objects
2368 } // end of loop on objects, which are connected to the frame
2372 /*************************************************************************
2374 |* SwLayoutFrm::NotifyLowerObjs()
2376 |*************************************************************************/
2377 // --> OD 2004-07-01 #i28701# - change purpose of method and its name
2378 // --> OD 2004-10-08 #i26945# - correct check, if anchored object is a lower
2379 // of the layout frame. E.g., anchor character text frame can be a follow text
2380 // frame.
2381 // --> OD 2005-03-11 #i44016# - add parameter <_bUnlockPosOfObjs> to
2382 // force an unlockposition call for the lower objects.
2383 void SwLayoutFrm::NotifyLowerObjs( const bool _bUnlockPosOfObjs )
2385 // invalidate lower floating screen objects
2386 SwPageFrm* pPageFrm = FindPageFrm();
2387 if ( pPageFrm && pPageFrm->GetSortedObjs() )
2389 SwSortedObjs& rObjs = *(pPageFrm->GetSortedObjs());
2390 for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i )
2392 SwAnchoredObject* pObj = rObjs[i];
2393 // --> OD 2004-10-08 #i26945# - check, if anchored object is a lower
2394 // of the layout frame is changed to check, if its anchor frame
2395 // is a lower of the layout frame.
2396 // determine the anchor frame - usually it's the anchor frame,
2397 // for at-character/as-character anchored objects the anchor character
2398 // text frame is taken.
2399 const SwFrm* pAnchorFrm = pObj->GetAnchorFrmContainingAnchPos();
2400 // <--
2401 if ( pObj->ISA(SwFlyFrm) )
2403 SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pObj);
2405 if ( pFly->Frm().Left() == WEIT_WECH )
2406 continue;
2408 if ( pFly->IsAnLower( this ) )
2409 continue;
2411 // --> OD 2004-10-08 #i26945# - use <pAnchorFrm> to check, if
2412 // fly frame is lower of layout frame resp. if fly frame is
2413 // at a different page registered as its anchor frame is on.
2414 const bool bLow = IsAnLower( pAnchorFrm );
2415 if ( bLow || pAnchorFrm->FindPageFrm() != pPageFrm )
2416 // <--
2418 pFly->_Invalidate( pPageFrm );
2419 if ( !bLow || pFly->IsFlyAtCntFrm() )
2421 // --> OD 2005-03-11 #i44016#
2422 if ( _bUnlockPosOfObjs )
2424 pFly->UnlockPosition();
2426 // <--
2427 pFly->_InvalidatePos();
2429 else
2430 pFly->_InvalidatePrt();
2433 else
2435 ASSERT( pObj->ISA(SwAnchoredDrawObject),
2436 "<SwLayoutFrm::NotifyFlys() - anchored object of unexcepted type" );
2437 // --> OD 2004-10-08 #i26945# - use <pAnchorFrm> to check, if
2438 // fly frame is lower of layout frame resp. if fly frame is
2439 // at a different page registered as its anchor frame is on.
2440 if ( IsAnLower( pAnchorFrm ) ||
2441 pAnchorFrm->FindPageFrm() != pPageFrm )
2442 // <--
2444 // --> OD 2005-03-11 #i44016#
2445 if ( _bUnlockPosOfObjs )
2447 pObj->UnlockPosition();
2449 // <--
2450 pObj->InvalidateObjPos();
2457 /*************************************************************************
2459 |* SwFlyFrm::NotifyDrawObj()
2461 |* Ersterstellung OK 22. Nov. 94
2462 |* Letzte Aenderung MA 10. Jan. 97
2464 |*************************************************************************/
2466 void SwFlyFrm::NotifyDrawObj()
2468 SwVirtFlyDrawObj* pObj = GetVirtDrawObj();
2469 pObj->SetRect();
2470 pObj->SetRectsDirty();
2471 pObj->SetChanged();
2472 pObj->BroadcastObjectChange();
2473 if ( GetFmt()->GetSurround().IsContour() )
2474 ClrContourCache( pObj );
2477 /*************************************************************************
2479 |* SwFlyFrm::CalcRel()
2481 |* Ersterstellung MA 13. Jun. 96
2482 |* Letzte Aenderung MA 10. Oct. 96
2484 |*************************************************************************/
2486 Size SwFlyFrm::CalcRel( const SwFmtFrmSize &rSz ) const
2488 Size aRet( rSz.GetSize() );
2490 const SwFrm *pRel = IsFlyLayFrm() ? GetAnchorFrm() : GetAnchorFrm()->GetUpper();
2491 if( pRel ) // LAYER_IMPL
2493 long nRelWidth = LONG_MAX, nRelHeight = LONG_MAX;
2494 const ViewShell *pSh = GetShell();
2495 if ( ( pRel->IsBodyFrm() || pRel->IsPageFrm() ) &&
2496 GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE) &&
2497 pSh && pSh->VisArea().HasArea() )
2499 nRelWidth = pSh->GetBrowseWidth();
2500 nRelHeight = pSh->VisArea().Height();
2501 Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() );
2502 long nDiff = nRelWidth - pRel->Prt().Width();
2503 if ( nDiff > 0 )
2504 nRelWidth -= nDiff;
2505 nRelHeight -= 2*aBorder.Height();
2506 nDiff = nRelHeight - pRel->Prt().Height();
2507 if ( nDiff > 0 )
2508 nRelHeight -= nDiff;
2510 nRelWidth = Min( nRelWidth, pRel->Prt().Width() );
2511 nRelHeight = Min( nRelHeight, pRel->Prt().Height() );
2512 if( !pRel->IsPageFrm() )
2514 const SwPageFrm* pPage = FindPageFrm();
2515 if( pPage )
2517 nRelWidth = Min( nRelWidth, pPage->Prt().Width() );
2518 nRelHeight = Min( nRelHeight, pPage->Prt().Height() );
2522 if ( rSz.GetWidthPercent() && rSz.GetWidthPercent() != 0xFF )
2523 aRet.Width() = nRelWidth * rSz.GetWidthPercent() / 100;
2524 if ( rSz.GetHeightPercent() && rSz.GetHeightPercent() != 0xFF )
2525 aRet.Height() = nRelHeight * rSz.GetHeightPercent() / 100;
2527 if ( rSz.GetWidthPercent() == 0xFF )
2529 aRet.Width() *= aRet.Height();
2530 aRet.Width() /= rSz.GetHeight();
2532 else if ( rSz.GetHeightPercent() == 0xFF )
2534 aRet.Height() *= aRet.Width();
2535 aRet.Height() /= rSz.GetWidth();
2538 return aRet;
2541 /*************************************************************************
2543 |* SwFlyFrm::CalcAutoWidth()
2545 |*************************************************************************/
2547 SwTwips lcl_CalcAutoWidth( const SwLayoutFrm& rFrm )
2549 SwTwips nRet = 0;
2550 SwTwips nMin = 0;
2551 const SwFrm* pFrm = rFrm.Lower();
2553 // No autowidth defined for columned frames
2554 if ( !pFrm || pFrm->IsColumnFrm() )
2555 return nRet;
2557 while ( pFrm )
2559 if ( pFrm->IsSctFrm() )
2561 nMin = lcl_CalcAutoWidth( *(SwSectionFrm*)pFrm );
2563 if ( pFrm->IsTxtFrm() )
2565 nMin = ((SwTxtFrm*)pFrm)->CalcFitToContent();
2566 const SvxLRSpaceItem &rSpace =
2567 ((SwTxtFrm*)pFrm)->GetTxtNode()->GetSwAttrSet().GetLRSpace();
2568 nMin += rSpace.GetRight() + rSpace.GetTxtLeft() + rSpace.GetTxtFirstLineOfst();
2570 else if ( pFrm->IsTabFrm() )
2572 const SwFmtFrmSize& rTblFmtSz = ((SwTabFrm*)pFrm)->GetTable()->GetFrmFmt()->GetFrmSize();
2573 if ( USHRT_MAX == rTblFmtSz.GetSize().Width() ||
2574 text::HoriOrientation::NONE == ((SwTabFrm*)pFrm)->GetFmt()->GetHoriOrient().GetHoriOrient() )
2576 const SwPageFrm* pPage = rFrm.FindPageFrm();
2577 // auto width table
2578 nMin = pFrm->GetUpper()->IsVertical() ?
2579 pPage->Prt().Height() :
2580 pPage->Prt().Width();
2582 else
2584 nMin = rTblFmtSz.GetSize().Width();
2588 if ( nMin > nRet )
2589 nRet = nMin;
2591 pFrm = pFrm->GetNext();
2594 return nRet;
2597 SwTwips SwFlyFrm::CalcAutoWidth() const
2599 return lcl_CalcAutoWidth( *this );
2602 /*************************************************************************
2604 |* SwFlyFrm::AddSpacesToFrm
2606 |* Ersterstellung MA 11. Nov. 96
2607 |* Letzte Aenderung MA 10. Mar. 97
2609 |*************************************************************************/
2611 //SwRect SwFlyFrm::AddSpacesToFrm() const
2613 // SwRect aRect( Frm() );
2614 // const SvxULSpaceItem &rUL = GetFmt()->GetULSpace();
2615 // const SvxLRSpaceItem &rLR = GetFmt()->GetLRSpace();
2616 // aRect.Left( Max( aRect.Left() - long(rLR.GetLeft()), 0L ) );
2617 // aRect.SSize().Width() += rLR.GetRight();
2618 // aRect.Top( Max( aRect.Top() - long(rUL.GetUpper()), 0L ) );
2619 // aRect.SSize().Height()+= rUL.GetLower();
2620 // return aRect;
2623 /*************************************************************************
2625 |* SwFlyFrm::GetContour()
2627 |* Ersterstellung MA 09. Jan. 97
2628 |* Letzte Aenderung MA 10. Jan. 97
2630 |*************************************************************************/
2631 /// OD 16.04.2003 #i13147# - If called for paint and the <SwNoTxtFrm> contains
2632 /// a graphic, load of intrinsic graphic has to be avoided.
2633 BOOL SwFlyFrm::GetContour( PolyPolygon& rContour,
2634 const sal_Bool _bForPaint ) const
2636 BOOL bRet = FALSE;
2637 if( GetFmt()->GetSurround().IsContour() && Lower() &&
2638 Lower()->IsNoTxtFrm() )
2640 SwNoTxtNode *pNd = (SwNoTxtNode*)((SwCntntFrm*)Lower())->GetNode();
2641 // OD 16.04.2003 #i13147# - determine <GraphicObject> instead of <Graphic>
2642 // in order to avoid load of graphic, if <SwNoTxtNode> contains a graphic
2643 // node and method is called for paint.
2644 const GraphicObject* pGrfObj = NULL;
2645 sal_Bool bGrfObjCreated = sal_False;
2646 const SwGrfNode* pGrfNd = pNd->GetGrfNode();
2647 if ( pGrfNd && _bForPaint )
2649 pGrfObj = &(pGrfNd->GetGrfObj());
2651 else
2653 pGrfObj = new GraphicObject( pNd->GetGraphic() );
2654 bGrfObjCreated = sal_True;
2656 ASSERT( pGrfObj, "SwFlyFrm::GetContour() - No Graphic/GraphicObject found at <SwNoTxtNode>." );
2657 if ( pGrfObj && pGrfObj->GetType() != GRAPHIC_NONE )
2659 if( !pNd->HasContour() )
2661 // OD 16.04.2003 #i13147# - no <CreateContour> for a graphic
2662 // during paint. Thus, return (value of <bRet> should be <FALSE>).
2663 if ( pGrfNd && _bForPaint )
2665 ASSERT( false, "SwFlyFrm::GetContour() - No Contour found at <SwNoTxtNode> during paint." );
2666 return bRet;
2668 pNd->CreateContour();
2670 pNd->GetContour( rContour );
2671 //Der Node haelt das Polygon passend zur Originalgroesse der Grafik
2672 //hier muss die Skalierung einkalkuliert werden.
2673 SwRect aClip;
2674 SwRect aOrig;
2675 Lower()->Calc();
2676 ((SwNoTxtFrm*)Lower())->GetGrfArea( aClip, &aOrig, FALSE );
2677 // OD 16.04.2003 #i13147# - copy method code <SvxContourDlg::ScaleContour(..)>
2678 // in order to avoid that graphic has to be loaded for contour scale.
2679 //SvxContourDlg::ScaleContour( rContour, aGrf, MAP_TWIP, aOrig.SSize() );
2681 OutputDevice* pOutDev = Application::GetDefaultDevice();
2682 const MapMode aDispMap( MAP_TWIP );
2683 const MapMode aGrfMap( pGrfObj->GetPrefMapMode() );
2684 const Size aGrfSize( pGrfObj->GetPrefSize() );
2685 double fScaleX;
2686 double fScaleY;
2687 Size aOrgSize;
2688 Point aNewPoint;
2689 BOOL bPixelMap = aGrfMap.GetMapUnit() == MAP_PIXEL;
2691 if ( bPixelMap )
2692 aOrgSize = pOutDev->PixelToLogic( aGrfSize, aDispMap );
2693 else
2694 aOrgSize = pOutDev->LogicToLogic( aGrfSize, aGrfMap, aDispMap );
2696 if ( aOrgSize.Width() && aOrgSize.Height() )
2698 fScaleX = (double) aOrig.Width() / aOrgSize.Width();
2699 fScaleY = (double) aOrig.Height() / aOrgSize.Height();
2701 for ( USHORT j = 0, nPolyCount = rContour.Count(); j < nPolyCount; j++ )
2703 Polygon& rPoly = rContour[ j ];
2705 for ( USHORT i = 0, nCount = rPoly.GetSize(); i < nCount; i++ )
2707 if ( bPixelMap )
2708 aNewPoint = pOutDev->PixelToLogic( rPoly[ i ], aDispMap );
2709 else
2710 aNewPoint = pOutDev->LogicToLogic( rPoly[ i ], aGrfMap, aDispMap );
2712 rPoly[ i ] = Point( FRound( aNewPoint.X() * fScaleX ), FRound( aNewPoint.Y() * fScaleY ) );
2717 // OD 17.04.2003 #i13147# - destroy created <GraphicObject>.
2718 if ( bGrfObjCreated )
2720 delete pGrfObj;
2722 rContour.Move( aOrig.Left(), aOrig.Top() );
2723 if( !aClip.Width() )
2724 aClip.Width( 1 );
2725 if( !aClip.Height() )
2726 aClip.Height( 1 );
2727 rContour.Clip( aClip.SVRect() );
2728 rContour.Optimize(POLY_OPTIMIZE_CLOSE);
2729 bRet = TRUE;
2732 return bRet;
2735 // OD 2004-03-25 #i26791#
2736 const SwVirtFlyDrawObj* SwFlyFrm::GetVirtDrawObj() const
2738 return static_cast<const SwVirtFlyDrawObj*>(GetDrawObj());
2740 SwVirtFlyDrawObj* SwFlyFrm::GetVirtDrawObj()
2742 return static_cast<SwVirtFlyDrawObj*>(DrawObj());
2745 // =============================================================================
2746 // OD 2004-03-24 #i26791# - implementation of pure virtual method declared in
2747 // base class <SwAnchoredObject>
2748 // =============================================================================
2749 void SwFlyFrm::InvalidateObjPos()
2751 InvalidatePos();
2752 // --> OD 2006-08-10 #i68520#
2753 InvalidateObjRectWithSpaces();
2754 // <--
2757 SwFrmFmt& SwFlyFrm::GetFrmFmt()
2759 ASSERT( GetFmt(),
2760 "<SwFlyFrm::GetFrmFmt()> - missing frame format -> crash." );
2761 return *GetFmt();
2763 const SwFrmFmt& SwFlyFrm::GetFrmFmt() const
2765 ASSERT( GetFmt(),
2766 "<SwFlyFrm::GetFrmFmt()> - missing frame format -> crash." );
2767 return *GetFmt();
2770 const SwRect SwFlyFrm::GetObjRect() const
2772 return Frm();
2775 // --> OD 2006-10-05 #i70122#
2776 // for Writer fly frames the bounding rectangle equals the object rectangles
2777 const SwRect SwFlyFrm::GetObjBoundRect() const
2779 return GetObjRect();
2781 // <--
2783 // --> OD 2006-08-10 #i68520#
2784 bool SwFlyFrm::_SetObjTop( const SwTwips _nTop )
2786 const bool bChanged( Frm().Pos().Y() != _nTop );
2788 Frm().Pos().Y() = _nTop;
2790 return bChanged;
2792 bool SwFlyFrm::_SetObjLeft( const SwTwips _nLeft )
2794 const bool bChanged( Frm().Pos().X() != _nLeft );
2796 Frm().Pos().X() = _nLeft;
2798 return bChanged;
2800 // <--
2802 /** method to assure that anchored object is registered at the correct
2803 page frame
2805 OD 2004-07-02 #i28701#
2807 @author OD
2809 void SwFlyFrm::RegisterAtCorrectPage()
2811 // default behaviour is to do nothing.
2814 /** method to determine, if a <MakeAll()> on the Writer fly frame is possible
2816 OD 2004-05-11 #i28701#
2818 @author OD
2820 bool SwFlyFrm::IsFormatPossible() const
2822 return SwAnchoredObject::IsFormatPossible() &&
2823 !IsLocked() && !IsColLocked();