merge the formfield patch from ooo-build
[ooovba.git] / sw / source / core / layout / ssfrm.cxx
blob2ff9b7cfc2e48a4d8c5841f71d3c232d03012c67
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ssfrm.cxx,v $
10 * $Revision: 1.51 $
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"
35 #include <pagefrm.hxx>
36 #include <rootfrm.hxx>
37 #include <cntfrm.hxx>
38 #include <doc.hxx>
39 #include <node.hxx>
40 #include <dview.hxx>
41 #include <dcontact.hxx>
42 #include <dflyobj.hxx>
43 #include <flyfrm.hxx>
44 #include <txtfrm.hxx> // ClearPara()
45 #include <cellfrm.hxx>
46 #include <swtable.hxx>
47 #include <fmtfsize.hxx>
48 #include <ftnidx.hxx>
49 #include <txtftn.hxx>
50 #include <ndtxt.hxx>
51 #include <ndindex.hxx>
52 #include <frmtool.hxx>
53 #include <pagedesc.hxx>
54 #include <svx/boxitem.hxx>
55 #include <svx/shaditem.hxx>
56 #include <fmtclds.hxx>
57 #include <viewsh.hxx>
58 #include <viewimp.hxx>
60 // OD 2004-05-24 #i28701#
61 #include <sortedobjs.hxx>
62 #include <hints.hxx>
64 // No inline cause we need the function pointers
65 long SwFrm::GetTopMargin() const
66 { return Prt().Top(); }
67 long SwFrm::GetBottomMargin() const
68 { return Frm().Height() -Prt().Height() -Prt().Top(); }
69 long SwFrm::GetLeftMargin() const
70 { return Prt().Left(); }
71 long SwFrm::GetRightMargin() const
72 { return Frm().Width() - Prt().Width() - Prt().Left(); }
73 long SwFrm::GetPrtLeft() const
74 { return Frm().Left() + Prt().Left(); }
75 long SwFrm::GetPrtBottom() const
76 { return Frm().Top() + Prt().Height() + Prt().Top(); }
77 long SwFrm::GetPrtRight() const
78 { return Frm().Left() + Prt().Width() + Prt().Left(); }
79 long SwFrm::GetPrtTop() const
80 { return Frm().Top() + Prt().Top(); }
82 BOOL SwFrm::SetMinLeft( long nDeadline )
84 SwTwips nDiff = nDeadline - Frm().Left();
85 if( nDiff > 0 )
87 Frm().Left( nDeadline );
88 Prt().Width( Prt().Width() - nDiff );
89 return TRUE;
91 return FALSE;
94 BOOL SwFrm::SetMaxBottom( long nDeadline )
96 SwTwips nDiff = Frm().Top() + Frm().Height() - nDeadline;
97 if( nDiff > 0 )
99 Frm().Height( Frm().Height() - nDiff );
100 Prt().Height( Prt().Height() - nDiff );
101 return TRUE;
103 return FALSE;
106 BOOL SwFrm::SetMinTop( long nDeadline )
108 SwTwips nDiff = nDeadline - Frm().Top();
109 if( nDiff > 0 )
111 Frm().Top( nDeadline );
112 Prt().Height( Prt().Height() - nDiff );
113 return TRUE;
115 return FALSE;
118 BOOL SwFrm::SetMaxRight( long nDeadline )
120 SwTwips nDiff = Frm().Left() + Frm().Width() - nDeadline;
121 if( nDiff > 0 )
123 Frm().Width( Frm().Width() - nDiff );
124 Prt().Width( Prt().Width() - nDiff );
125 return TRUE;
127 return FALSE;
130 void SwFrm::MakeBelowPos( const SwFrm* pUp, const SwFrm* pPrv, BOOL bNotify )
132 if( pPrv )
134 aFrm.Pos( pPrv->Frm().Pos() );
135 aFrm.Pos().Y() += pPrv->Frm().Height();
137 else
139 aFrm.Pos( pUp->Frm().Pos() );
140 aFrm.Pos() += pUp->Prt().Pos();
142 if( bNotify )
143 aFrm.Pos().Y() += 1;
146 void SwFrm::MakeUpperPos( const SwFrm* pUp, const SwFrm* pPrv, BOOL bNotify )
148 if( pPrv )
150 aFrm.Pos( pPrv->Frm().Pos() );
151 aFrm.Pos().Y() -= Frm().Height();
153 else
155 aFrm.Pos( pUp->Frm().Pos() );
156 aFrm.Pos() += pUp->Prt().Pos();
157 aFrm.Pos().Y() += pUp->Prt().Height() - aFrm.Height();
159 if( bNotify )
160 aFrm.Pos().Y() -= 1;
163 void SwFrm::MakeLeftPos( const SwFrm* pUp, const SwFrm* pPrv, BOOL bNotify )
165 if( pPrv )
167 aFrm.Pos( pPrv->Frm().Pos() );
168 aFrm.Pos().X() -= Frm().Width();
170 else
172 aFrm.Pos( pUp->Frm().Pos() );
173 aFrm.Pos() += pUp->Prt().Pos();
174 aFrm.Pos().X() += pUp->Prt().Width() - aFrm.Width();
176 if( bNotify )
177 aFrm.Pos().X() -= 1;
180 void SwFrm::MakeRightPos( const SwFrm* pUp, const SwFrm* pPrv, BOOL bNotify )
182 if( pPrv )
184 aFrm.Pos( pPrv->Frm().Pos() );
185 aFrm.Pos().X() += pPrv->Frm().Width();
187 else
189 aFrm.Pos( pUp->Frm().Pos() );
190 aFrm.Pos() += pUp->Prt().Pos();
192 if( bNotify )
193 aFrm.Pos().X() += 1;
196 void SwFrm::SetTopBottomMargins( long nTop, long nBot )
198 Prt().Top( nTop );
199 Prt().Height( Frm().Height() - nTop - nBot );
202 void SwFrm::SetBottomTopMargins( long nBot, long nTop )
204 Prt().Top( nTop );
205 Prt().Height( Frm().Height() - nTop - nBot );
208 void SwFrm::SetLeftRightMargins( long nLeft, long nRight)
210 Prt().Left( nLeft );
211 Prt().Width( Frm().Width() - nLeft - nRight );
214 void SwFrm::SetRightLeftMargins( long nRight, long nLeft)
216 Prt().Left( nLeft );
217 Prt().Width( Frm().Width() - nLeft - nRight );
220 const USHORT nMinVertCellHeight = 1135;
222 /*-----------------11.9.2001 11:11------------------
223 * SwFrm::CheckDirChange(..)
224 * checks the layout direction and
225 * invalidates the lower frames rekursivly, if necessary.
226 * --------------------------------------------------*/
228 void SwFrm::CheckDirChange()
230 BOOL bOldVert = GetVerticalFlag();
231 BOOL bOldRev = IsReverse();
232 BOOL bOldR2L = GetRightToLeftFlag();
233 SetInvalidVert( TRUE );
234 SetInvalidR2L( TRUE );
235 BOOL bChg = bOldR2L != IsRightToLeft();
236 if( ( IsVertical() != bOldVert ) || bChg || IsReverse() != bOldRev )
238 InvalidateAll();
239 if( IsLayoutFrm() )
241 // set minimum row height for vertical cells in horizontal table:
242 if ( IsCellFrm() && GetUpper() )
244 if ( IsVertical() != GetUpper()->IsVertical() &&
245 ((SwCellFrm*)this)->GetTabBox()->getRowSpan() == 1 )
247 SwTableLine* pLine = (SwTableLine*)((SwCellFrm*)this)->GetTabBox()->GetUpper();
248 SwFrmFmt* pFrmFmt = pLine->GetFrmFmt();
249 SwFmtFrmSize aNew( pFrmFmt->GetFrmSize() );
250 if ( ATT_FIX_SIZE != aNew.GetHeightSizeType() )
251 aNew.SetHeightSizeType( ATT_MIN_SIZE );
252 if ( aNew.GetHeight() < nMinVertCellHeight )
253 aNew.SetHeight( nMinVertCellHeight );
254 SwDoc* pDoc = pFrmFmt->GetDoc();
255 pDoc->SetAttr( aNew, *pLine->ClaimFrmFmt() );
259 SwFrm* pFrm = ((SwLayoutFrm*)this)->Lower();
260 const SwFmtCol* pCol = NULL;
261 SwLayoutFrm* pBody = 0;
262 if( pFrm )
264 if( IsPageFrm() )
266 // If we're a page frame and we change our layout direction,
267 // we have to look for columns and rearrange them.
268 pBody = ((SwPageFrm*)this)->FindBodyCont();
269 if(pBody && pBody->Lower() && pBody->Lower()->IsColumnFrm())
270 pCol = &((SwPageFrm*)this)->GetFmt()->GetCol();
272 else if( pFrm->IsColumnFrm() )
274 pBody = ((SwLayoutFrm*)this);
275 const SwFrmFmt *pFmt = pBody->GetFmt();
276 if( pFmt )
277 pCol = &pFmt->GetCol();
280 while( pFrm )
282 pFrm->CheckDirChange();
283 pFrm = pFrm->GetNext();
285 if( pCol )
286 pBody->AdjustColumns( pCol, TRUE );
288 else if( IsTxtFrm() )
289 ((SwTxtFrm*)this)->Prepare( PREP_CLEAR );
291 // --> OD 2004-07-27 #i31698# - notify anchored objects also for page frames.
292 // Remove code above for special handling of page frames
293 if ( GetDrawObjs() )
295 const SwSortedObjs *pObjs = GetDrawObjs();
296 sal_uInt32 nCnt = pObjs->Count();
297 for ( sal_uInt32 i = 0; i < nCnt; ++i )
299 SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
300 if( pAnchoredObj->ISA(SwFlyFrm) )
301 static_cast<SwFlyFrm*>(pAnchoredObj)->CheckDirChange();
302 else
304 // OD 2004-04-06 #i26791# - direct object
305 // positioning no longer needed. Instead
306 // invalidate
307 pAnchoredObj->InvalidateObjPos();
309 // --> OD 2004-07-27 #i31698# - update layout direction of
310 // anchored object
312 ::setContextWritingMode( pAnchoredObj->DrawObj(), pAnchoredObj->GetAnchorFrmContainingAnchPos() );
313 pAnchoredObj->UpdateLayoutDir();
315 // <--
321 /*-----------------13.9.2002 11:11------------------
322 * SwFrm::GetFrmAnchorPos(..)
323 * returns the position for anchors based on frame direction
324 * --------------------------------------------------*/
325 // OD 2004-03-10 #i11860# - consider lower space and line spacing of
326 // previous frame according to new option 'Use former object positioning'
327 Point SwFrm::GetFrmAnchorPos( sal_Bool bIgnoreFlysAnchoredAtThisFrame ) const
329 Point aAnchor = Frm().Pos();
330 if ( IsVertical() || IsRightToLeft() )
331 aAnchor.X() += Frm().Width();
333 if ( IsTxtFrm() )
335 SwTwips nBaseOfstForFly =
336 ((SwTxtFrm*)this)->GetBaseOfstForFly( bIgnoreFlysAnchoredAtThisFrame );
337 if ( IsVertical() )
338 aAnchor.Y() += nBaseOfstForFly;
339 else
340 aAnchor.X() += nBaseOfstForFly;
342 // OD 2004-03-10 #i11860# - if option 'Use former object positioning'
343 // is OFF, consider the lower space and the line spacing of the
344 // previous frame and the spacing considered for the page grid
345 const SwTxtFrm* pThisTxtFrm = static_cast<const SwTxtFrm*>(this);
346 const SwTwips nUpperSpaceAmountConsideredForPrevFrmAndPageGrid =
347 pThisTxtFrm->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid();
348 if ( IsVertical() )
350 aAnchor.X() -= nUpperSpaceAmountConsideredForPrevFrmAndPageGrid;
352 else
354 aAnchor.Y() += nUpperSpaceAmountConsideredForPrevFrmAndPageGrid;
358 return aAnchor;
362 /*************************************************************************
364 |* SwFrm::~SwFrm()
366 |* Ersterstellung MA 02. Mar. 94
367 |* Letzte Aenderung MA 25. Jun. 95
369 |*************************************************************************/
372 SwFrm::~SwFrm()
374 // accessible objects for fly and cell frames have been already disposed
375 // by the destructors of the derived classes.
376 if( IsAccessibleFrm() && !(IsFlyFrm() || IsCellFrm()) && GetDep() )
378 SwRootFrm *pRootFrm = FindRootFrm();
379 if( pRootFrm && pRootFrm->IsAnyShellAccessible() )
381 ViewShell *pVSh = pRootFrm->GetCurrShell();
382 if( pVSh && pVSh->Imp() )
384 ASSERT( !GetLower(), "Lowers should be dispose already!" );
385 pVSh->Imp()->DisposeAccessibleFrm( this );
390 if( pDrawObjs )
392 for ( sal_uInt32 i = pDrawObjs->Count(); i; )
394 SwAnchoredObject* pAnchoredObj = (*pDrawObjs)[--i];
395 if ( pAnchoredObj->ISA(SwFlyFrm) )
396 delete pAnchoredObj;
397 else
399 SdrObject* pSdrObj = pAnchoredObj->DrawObj();
400 SwDrawContact* pContact =
401 static_cast<SwDrawContact*>(pSdrObj->GetUserCall());
402 ASSERT( pContact,
403 "<SwFrm::~SwFrm> - missing contact for drawing object" );
404 if ( pContact )
406 pContact->DisconnectObjFromLayout( pSdrObj );
410 if ( pDrawObjs )
411 delete pDrawObjs;
414 #ifndef PRODUCT
415 // JP 15.10.2001: for detection of access to deleted frames
416 pDrawObjs = (SwSortedObjs*)0x33333333;
417 #endif
420 /*************************************************************************
422 |* SwLayoutFrm::SetFrmFmt()
423 |* Ersterstellung MA 22. Apr. 93
424 |* Letzte Aenderung MA 02. Nov. 94
426 |*************************************************************************/
429 void SwLayoutFrm::SetFrmFmt( SwFrmFmt *pNew )
431 if ( pNew != GetFmt() )
433 SwFmtChg aOldFmt( GetFmt() );
434 pNew->Add( this );
435 SwFmtChg aNewFmt( pNew );
436 Modify( &aOldFmt, &aNewFmt );
440 /*************************************************************************
441 |* SwCntntFrm::SwCntntFrm()
442 |*************************************************************************/
443 SwCntntFrm::SwCntntFrm( SwCntntNode * const pCntnt ) :
444 SwFrm( pCntnt ),
445 SwFlowFrm( (SwFrm&)*this )
449 /*************************************************************************
450 |* SwCntntFrm::~SwCntntFrm()
451 |*************************************************************************/
452 SwCntntFrm::~SwCntntFrm()
454 SwCntntNode* pCNd;
455 if( 0 != ( pCNd = PTR_CAST( SwCntntNode, pRegisteredIn )) &&
456 !pCNd->GetDoc()->IsInDtor() )
458 //Bei der Root abmelden wenn ich dort noch im Turbo stehe.
459 SwRootFrm *pRoot = FindRootFrm();
460 if( pRoot && pRoot->GetTurbo() == this )
462 pRoot->DisallowTurbo();
463 pRoot->ResetTurbo();
465 if( IsTxtFrm() && ((SwTxtFrm*)this)->HasFtn() )
467 SwTxtNode *pTxtNd = ((SwTxtFrm*)this)->GetTxtNode();
468 const SwFtnIdxs &rFtnIdxs = pCNd->GetDoc()->GetFtnIdxs();
469 USHORT nPos;
470 ULONG nIndex = pCNd->GetIndex();
471 rFtnIdxs.SeekEntry( *pTxtNd, &nPos );
472 SwTxtFtn* pTxtFtn;
473 if( nPos < rFtnIdxs.Count() )
475 while( nPos && pTxtNd == &(rFtnIdxs[ nPos ]->GetTxtNode()) )
476 --nPos;
477 if( nPos || pTxtNd != &(rFtnIdxs[ nPos ]->GetTxtNode()) )
478 ++nPos;
480 while( nPos < rFtnIdxs.Count() )
482 pTxtFtn = rFtnIdxs[ nPos ];
483 if( pTxtFtn->GetTxtNode().GetIndex() > nIndex )
484 break;
485 pTxtFtn->DelFrms();
486 ++nPos;
492 /*************************************************************************
494 |* SwLayoutFrm::~SwLayoutFrm
496 |* Ersterstellung AK 28-Feb-1991
497 |* Letzte Aenderung MA 11. Jan. 95
499 |*************************************************************************/
502 SwLayoutFrm::~SwLayoutFrm()
504 SwFrm *pFrm = pLower;
506 if( GetFmt() && !GetFmt()->GetDoc()->IsInDtor() )
508 while ( pFrm )
510 //Erst die Objs des Frm vernichten, denn diese koennen sich sonst nach
511 //dem Remove nicht mehr bei der Seite abmelden.
512 //Falls sich einer nicht abmeldet wollen wir nicht gleich
513 //endlos schleifen.
515 sal_uInt32 nCnt;
516 while ( pFrm->GetDrawObjs() && pFrm->GetDrawObjs()->Count() )
518 nCnt = pFrm->GetDrawObjs()->Count();
519 // --> OD 2004-06-30 #i28701#
520 SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[0];
521 if ( pAnchoredObj->ISA(SwFlyFrm) )
524 //cmc: flush any accessible events that might be related to
525 //this object
526 if (ViewShell *pSh = GetShell())
527 if (SwViewImp *pImp = pSh ? pSh->Imp() : 0)
528 pImp->FireAccessibleEvents();
530 delete pAnchoredObj;
532 else
534 SdrObject* pSdrObj = pAnchoredObj->DrawObj();
535 SwDrawContact* pContact =
536 static_cast<SwDrawContact*>(pSdrObj->GetUserCall());
537 ASSERT( pContact,
538 "<SwFrm::~SwFrm> - missing contact for drawing object" );
539 if ( pContact )
541 pContact->DisconnectObjFromLayout( pSdrObj );
544 if ( pFrm->GetDrawObjs() &&
545 nCnt == pFrm->GetDrawObjs()->Count() )
547 pFrm->GetDrawObjs()->Remove( *pAnchoredObj );
549 // <--
551 pFrm->Remove();
552 delete pFrm;
553 pFrm = pLower;
555 //Fly's vernichten. Der letzte loescht gleich das Array.
556 sal_uInt32 nCnt;
557 while ( GetDrawObjs() && GetDrawObjs()->Count() )
559 nCnt = GetDrawObjs()->Count();
561 // --> OD 2004-06-30 #i28701#
562 SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[0];
563 if ( pAnchoredObj->ISA(SwFlyFrm) )
564 delete pAnchoredObj;
565 else
567 SdrObject* pSdrObj = pAnchoredObj->DrawObj();
568 SwDrawContact* pContact =
569 static_cast<SwDrawContact*>(pSdrObj->GetUserCall());
570 ASSERT( pContact,
571 "<SwFrm::~SwFrm> - missing contact for drawing object" );
572 if ( pContact )
574 pContact->DisconnectObjFromLayout( pSdrObj );
577 if ( GetDrawObjs() && nCnt == GetDrawObjs()->Count() )
579 GetDrawObjs()->Remove( *pAnchoredObj );
581 // <--
584 else
586 while( pFrm )
588 SwFrm *pNxt = pFrm->GetNext();
589 delete pFrm;
590 pFrm = pNxt;
595 /*************************************************************************
597 |* SwFrm::PaintArea()
599 |* Created AMA 08/22/2000
600 |* Last change AMA 08/23/2000
602 |* The paintarea is the area, in which the content of a frame is allowed
603 |* to be displayed. This region could be larger than the printarea (Prt())
604 |* of the upper, it includes e.g. often the margin of the page.
606 |*************************************************************************/
608 const SwRect SwFrm::PaintArea() const
610 // NEW TABLES
611 // Cell frames may not leave their upper:
612 SwRect aRect = IsRowFrm() ? GetUpper()->Frm() : Frm();
613 const BOOL bVert = IsVertical();
614 SwRectFn fnRect = bVert ? fnRectVert : fnRectHori;
615 long nRight = (aRect.*fnRect->fnGetRight)();
616 long nLeft = (aRect.*fnRect->fnGetLeft)();
617 const SwFrm* pTmp = this;
618 BOOL bLeft = TRUE;
619 BOOL bRight = TRUE;
620 long nRowSpan = 0;
621 while( pTmp )
623 if( pTmp->IsCellFrm() && pTmp->GetUpper() &&
624 pTmp->GetUpper()->IsVertical() != pTmp->IsVertical() )
625 nRowSpan = ((SwCellFrm*)pTmp)->GetTabBox()->getRowSpan();
626 long nTmpRight = (pTmp->Frm().*fnRect->fnGetRight)();
627 long nTmpLeft = (pTmp->Frm().*fnRect->fnGetLeft)();
628 if( pTmp->IsRowFrm() && nRowSpan > 1 )
630 const SwFrm* pNxt = pTmp;
631 while( --nRowSpan > 0 && pNxt->GetNext() )
632 pNxt = pNxt->GetNext();
633 if( pTmp->IsVertical() )
634 nTmpLeft = (pNxt->Frm().*fnRect->fnGetLeft)();
635 else
636 nTmpRight = (pNxt->Frm().*fnRect->fnGetRight)();
638 ASSERT( pTmp, "PaintArea lost in time and space" );
639 if( pTmp->IsPageFrm() || pTmp->IsFlyFrm() ||
640 pTmp->IsCellFrm() || pTmp->IsRowFrm() || //nobody leaves a table!
641 pTmp->IsRootFrm() )
643 if( bLeft || nLeft < nTmpLeft )
644 nLeft = nTmpLeft;
645 if( bRight || nTmpRight < nRight )
646 nRight = nTmpRight;
647 if( pTmp->IsPageFrm() || pTmp->IsFlyFrm() || pTmp->IsRootFrm() )
648 break;
649 bLeft = FALSE;
650 bRight = FALSE;
652 else if( pTmp->IsColumnFrm() ) // nobody enters neightbour columns
654 BOOL bR2L = pTmp->IsRightToLeft();
655 // the first column has _no_ influence to the left range
656 if( bR2L ? pTmp->GetNext() : pTmp->GetPrev() )
658 if( bLeft || nLeft < nTmpLeft )
659 nLeft = nTmpLeft;
660 bLeft = FALSE;
662 // the last column has _no_ influence to the right range
663 if( bR2L ? pTmp->GetPrev() : pTmp->GetNext() )
665 if( bRight || nTmpRight < nRight )
666 nRight = nTmpRight;
667 bRight = FALSE;
670 else if( bVert && pTmp->IsBodyFrm() )
672 // Header and footer frames have always horizontal direction and
673 // limit the body frame.
674 // A previous frame of a body frame must be a header,
675 // the next frame of a body frame may be a footnotecontainer or
676 // a footer. The footnotecontainer has the same direction like
677 // the body frame.
678 if( pTmp->GetPrev() && ( bLeft || nLeft < nTmpLeft ) )
680 nLeft = nTmpLeft;
681 bLeft = FALSE;
683 if( pTmp->GetNext() &&
684 ( pTmp->GetNext()->IsFooterFrm() || pTmp->GetNext()->GetNext() )
685 && ( bRight || nTmpRight < nRight ) )
687 nRight = nTmpRight;
688 bRight = FALSE;
691 pTmp = pTmp->GetUpper();
693 (aRect.*fnRect->fnSetLeft)( nLeft );
694 (aRect.*fnRect->fnSetRight)( nRight );
695 return aRect;
698 /*************************************************************************
700 |* SwFrm::UnionFrm()
702 |* Created AMA 08/22/2000
703 |* Last change AMA 08/23/2000
705 |* The unionframe is the framearea (Frm()) of a frame expanded by the
706 |* printarea, if there's a negative margin at the left or right side.
708 |*************************************************************************/
710 const SwRect SwFrm::UnionFrm( BOOL bBorder ) const
712 BOOL bVert = IsVertical();
713 SwRectFn fnRect = bVert ? fnRectVert : fnRectHori;
714 long nLeft = (Frm().*fnRect->fnGetLeft)();
715 long nWidth = (Frm().*fnRect->fnGetWidth)();
716 long nPrtLeft = (Prt().*fnRect->fnGetLeft)();
717 long nPrtWidth = (Prt().*fnRect->fnGetWidth)();
718 if( nPrtLeft + nPrtWidth > nWidth )
719 nWidth = nPrtLeft + nPrtWidth;
720 if( nPrtLeft < 0 )
722 nLeft += nPrtLeft;
723 nWidth -= nPrtLeft;
725 SwTwips nRight = nLeft + nWidth;
726 long nAdd = 0;
727 if( bBorder )
729 SwBorderAttrAccess aAccess( SwFrm::GetCache(), this );
730 const SwBorderAttrs &rAttrs = *aAccess.Get();
731 const SvxBoxItem &rBox = rAttrs.GetBox();
732 if ( rBox.GetLeft() )
733 nLeft -= rBox.CalcLineSpace( BOX_LINE_LEFT );
734 else if ( rAttrs.IsBorderDist() )
735 nLeft -= rBox.GetDistance( BOX_LINE_LEFT ) + 1;
736 if ( rBox.GetRight() )
737 nAdd += rBox.CalcLineSpace( BOX_LINE_RIGHT );
738 else if ( rAttrs.IsBorderDist() )
739 nAdd += rBox.GetDistance( BOX_LINE_RIGHT ) + 1;
740 if( rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE )
742 const SvxShadowItem &rShadow = rAttrs.GetShadow();
743 nLeft -= rShadow.CalcShadowSpace( SHADOW_LEFT );
744 nAdd += rShadow.CalcShadowSpace( SHADOW_RIGHT );
747 if( IsTxtFrm() && ((SwTxtFrm*)this)->HasPara() )
749 long nTmp = ((SwTxtFrm*)this)->HangingMargin();
750 if( nTmp > nAdd )
751 nAdd = nTmp;
753 nWidth = nRight + nAdd - nLeft;
754 SwRect aRet( Frm() );
755 (aRet.*fnRect->fnSetPosX)( nLeft );
756 (aRet.*fnRect->fnSetWidth)( nWidth );
757 return aRet;