1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sw.hxx" 26 27 #include <ftnfrm.hxx> 28 #include <pagefrm.hxx> 29 #include <rootfrm.hxx> 30 #include <cntfrm.hxx> 31 #include <doc.hxx> 32 #include <node.hxx> 33 #include <dview.hxx> 34 #include <dcontact.hxx> 35 #include <dflyobj.hxx> 36 #include <flyfrm.hxx> 37 #include <txtfrm.hxx> // ClearPara() 38 #include <cellfrm.hxx> 39 #include <swtable.hxx> 40 #include <fmtfsize.hxx> 41 #include <ftnidx.hxx> 42 #include <txtftn.hxx> 43 #include <ndtxt.hxx> 44 #include <ndindex.hxx> 45 #include <frmtool.hxx> 46 #include <pagedesc.hxx> 47 #include <editeng/boxitem.hxx> 48 #include <editeng/shaditem.hxx> 49 #include <fmtclds.hxx> 50 #include <viewsh.hxx> 51 #include <viewimp.hxx> 52 #include <sortedobjs.hxx> 53 #include <hints.hxx> 54 #include <switerator.hxx> 55 56 // No inline cause we need the function pointers 57 long SwFrm::GetTopMargin() const 58 { return Prt().Top(); } 59 long SwFrm::GetBottomMargin() const 60 { return Frm().Height() -Prt().Height() -Prt().Top(); } 61 long SwFrm::GetLeftMargin() const 62 { return Prt().Left(); } 63 long SwFrm::GetRightMargin() const 64 { return Frm().Width() - Prt().Width() - Prt().Left(); } 65 long SwFrm::GetPrtLeft() const 66 { return Frm().Left() + Prt().Left(); } 67 long SwFrm::GetPrtBottom() const 68 { return Frm().Top() + Prt().Height() + Prt().Top(); } 69 long SwFrm::GetPrtRight() const 70 { return Frm().Left() + Prt().Width() + Prt().Left(); } 71 long SwFrm::GetPrtTop() const 72 { return Frm().Top() + Prt().Top(); } 73 74 sal_Bool SwFrm::SetMinLeft( long nDeadline ) 75 { 76 SwTwips nDiff = nDeadline - Frm().Left(); 77 if( nDiff > 0 ) 78 { 79 Frm().Left( nDeadline ); 80 Prt().Width( Prt().Width() - nDiff ); 81 return sal_True; 82 } 83 return sal_False; 84 } 85 86 sal_Bool SwFrm::SetMaxBottom( long nDeadline ) 87 { 88 SwTwips nDiff = Frm().Top() + Frm().Height() - nDeadline; 89 if( nDiff > 0 ) 90 { 91 Frm().Height( Frm().Height() - nDiff ); 92 Prt().Height( Prt().Height() - nDiff ); 93 return sal_True; 94 } 95 return sal_False; 96 } 97 98 sal_Bool SwFrm::SetMinTop( long nDeadline ) 99 { 100 SwTwips nDiff = nDeadline - Frm().Top(); 101 if( nDiff > 0 ) 102 { 103 Frm().Top( nDeadline ); 104 Prt().Height( Prt().Height() - nDiff ); 105 return sal_True; 106 } 107 return sal_False; 108 } 109 110 sal_Bool SwFrm::SetMaxRight( long nDeadline ) 111 { 112 SwTwips nDiff = Frm().Left() + Frm().Width() - nDeadline; 113 if( nDiff > 0 ) 114 { 115 Frm().Width( Frm().Width() - nDiff ); 116 Prt().Width( Prt().Width() - nDiff ); 117 return sal_True; 118 } 119 return sal_False; 120 } 121 122 void SwFrm::MakeBelowPos( const SwFrm* pUp, const SwFrm* pPrv, sal_Bool bNotify ) 123 { 124 if( pPrv ) 125 { 126 aFrm.Pos( pPrv->Frm().Pos() ); 127 aFrm.Pos().Y() += pPrv->Frm().Height(); 128 } 129 else 130 { 131 aFrm.Pos( pUp->Frm().Pos() ); 132 aFrm.Pos() += pUp->Prt().Pos(); 133 } 134 if( bNotify ) 135 aFrm.Pos().Y() += 1; 136 } 137 138 void SwFrm::MakeUpperPos( const SwFrm* pUp, const SwFrm* pPrv, sal_Bool bNotify ) 139 { 140 if( pPrv ) 141 { 142 aFrm.Pos( pPrv->Frm().Pos() ); 143 aFrm.Pos().Y() -= Frm().Height(); 144 } 145 else 146 { 147 aFrm.Pos( pUp->Frm().Pos() ); 148 aFrm.Pos() += pUp->Prt().Pos(); 149 aFrm.Pos().Y() += pUp->Prt().Height() - aFrm.Height(); 150 } 151 if( bNotify ) 152 aFrm.Pos().Y() -= 1; 153 } 154 155 void SwFrm::MakeLeftPos( const SwFrm* pUp, const SwFrm* pPrv, sal_Bool bNotify ) 156 { 157 if( pPrv ) 158 { 159 aFrm.Pos( pPrv->Frm().Pos() ); 160 aFrm.Pos().X() -= Frm().Width(); 161 } 162 else 163 { 164 aFrm.Pos( pUp->Frm().Pos() ); 165 aFrm.Pos() += pUp->Prt().Pos(); 166 aFrm.Pos().X() += pUp->Prt().Width() - aFrm.Width(); 167 } 168 if( bNotify ) 169 aFrm.Pos().X() -= 1; 170 } 171 172 void SwFrm::MakeRightPos( const SwFrm* pUp, const SwFrm* pPrv, sal_Bool bNotify ) 173 { 174 if( pPrv ) 175 { 176 aFrm.Pos( pPrv->Frm().Pos() ); 177 aFrm.Pos().X() += pPrv->Frm().Width(); 178 } 179 else 180 { 181 aFrm.Pos( pUp->Frm().Pos() ); 182 aFrm.Pos() += pUp->Prt().Pos(); 183 } 184 if( bNotify ) 185 aFrm.Pos().X() += 1; 186 } 187 188 void SwFrm::SetTopBottomMargins( long nTop, long nBot ) 189 { 190 Prt().Top( nTop ); 191 Prt().Height( Frm().Height() - nTop - nBot ); 192 } 193 194 void SwFrm::SetBottomTopMargins( long nBot, long nTop ) 195 { 196 Prt().Top( nTop ); 197 Prt().Height( Frm().Height() - nTop - nBot ); 198 } 199 200 void SwFrm::SetLeftRightMargins( long nLeft, long nRight) 201 { 202 Prt().Left( nLeft ); 203 Prt().Width( Frm().Width() - nLeft - nRight ); 204 } 205 206 void SwFrm::SetRightLeftMargins( long nRight, long nLeft) 207 { 208 Prt().Left( nLeft ); 209 Prt().Width( Frm().Width() - nLeft - nRight ); 210 } 211 212 const sal_uInt16 nMinVertCellHeight = 1135; 213 214 /*----------------------------------- 215 * SwFrm::CheckDirChange(..) 216 * checks the layout direction and 217 * invalidates the lower frames rekursivly, if necessary. 218 * --------------------------------------------------*/ 219 220 void SwFrm::CheckDirChange() 221 { 222 sal_Bool bOldVert = GetVerticalFlag(); 223 sal_Bool bOldRev = IsReverse(); 224 sal_Bool bOldR2L = GetRightToLeftFlag(); 225 SetInvalidVert( sal_True ); 226 SetInvalidR2L( sal_True ); 227 sal_Bool bChg = bOldR2L != IsRightToLeft(); 228 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 229 sal_Bool bOldVertL2R = IsVertLR(); 230 if( ( IsVertical() != bOldVert ) || bChg || IsReverse() != bOldRev || bOldVertL2R != IsVertLR() ) 231 { 232 InvalidateAll(); 233 if( IsLayoutFrm() ) 234 { 235 // set minimum row height for vertical cells in horizontal table: 236 if ( IsCellFrm() && GetUpper() ) 237 { 238 if ( IsVertical() != GetUpper()->IsVertical() && 239 ((SwCellFrm*)this)->GetTabBox()->getRowSpan() == 1 ) 240 { 241 SwTableLine* pLine = (SwTableLine*)((SwCellFrm*)this)->GetTabBox()->GetUpper(); 242 SwFrmFmt* pFrmFmt = pLine->GetFrmFmt(); 243 SwFmtFrmSize aNew( pFrmFmt->GetFrmSize() ); 244 if ( ATT_FIX_SIZE != aNew.GetHeightSizeType() ) 245 aNew.SetHeightSizeType( ATT_MIN_SIZE ); 246 if ( aNew.GetHeight() < nMinVertCellHeight ) 247 aNew.SetHeight( nMinVertCellHeight ); 248 SwDoc* pDoc = pFrmFmt->GetDoc(); 249 pDoc->SetAttr( aNew, *pLine->ClaimFrmFmt() ); 250 } 251 } 252 253 SwFrm* pFrm = ((SwLayoutFrm*)this)->Lower(); 254 const SwFmtCol* pCol = NULL; 255 SwLayoutFrm* pBody = 0; 256 if( pFrm ) 257 { 258 if( IsPageFrm() ) 259 { 260 // If we're a page frame and we change our layout direction, 261 // we have to look for columns and rearrange them. 262 pBody = ((SwPageFrm*)this)->FindBodyCont(); 263 if(pBody && pBody->Lower() && pBody->Lower()->IsColumnFrm()) 264 pCol = &((SwPageFrm*)this)->GetFmt()->GetCol(); 265 } 266 else if( pFrm->IsColumnFrm() ) 267 { 268 pBody = ((SwLayoutFrm*)this); 269 const SwFrmFmt *pFmt = pBody->GetFmt(); 270 if( pFmt ) 271 pCol = &pFmt->GetCol(); 272 } 273 } 274 while( pFrm ) 275 { 276 pFrm->CheckDirChange(); 277 pFrm = pFrm->GetNext(); 278 } 279 if( pCol ) 280 pBody->AdjustColumns( pCol, sal_True ); 281 } 282 else if( IsTxtFrm() ) 283 ((SwTxtFrm*)this)->Prepare( PREP_CLEAR ); 284 285 // --> OD 2004-07-27 #i31698# - notify anchored objects also for page frames. 286 // Remove code above for special handling of page frames 287 if ( GetDrawObjs() ) 288 { 289 const SwSortedObjs *pObjs = GetDrawObjs(); 290 sal_uInt32 nCnt = pObjs->Count(); 291 for ( sal_uInt32 i = 0; i < nCnt; ++i ) 292 { 293 SwAnchoredObject* pAnchoredObj = (*pObjs)[i]; 294 if( pAnchoredObj->ISA(SwFlyFrm) ) 295 static_cast<SwFlyFrm*>(pAnchoredObj)->CheckDirChange(); 296 else 297 { 298 // OD 2004-04-06 #i26791# - direct object 299 // positioning no longer needed. Instead 300 // invalidate 301 pAnchoredObj->InvalidateObjPos(); 302 } 303 // --> OD 2004-07-27 #i31698# - update layout direction of 304 // anchored object 305 { 306 ::setContextWritingMode( pAnchoredObj->DrawObj(), pAnchoredObj->GetAnchorFrmContainingAnchPos() ); 307 pAnchoredObj->UpdateLayoutDir(); 308 } 309 // <-- 310 } 311 } 312 } 313 } 314 315 /*----------------------------------- 316 * SwFrm::GetFrmAnchorPos(..) 317 * returns the position for anchors based on frame direction 318 * --------------------------------------------------*/ 319 // OD 2004-03-10 #i11860# - consider lower space and line spacing of 320 // previous frame according to new option 'Use former object positioning' 321 Point SwFrm::GetFrmAnchorPos( sal_Bool bIgnoreFlysAnchoredAtThisFrame ) const 322 { 323 Point aAnchor = Frm().Pos(); 324 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 325 if ( ( IsVertical() && !IsVertLR() ) || IsRightToLeft() ) 326 aAnchor.X() += Frm().Width(); 327 328 if ( IsTxtFrm() ) 329 { 330 SwTwips nBaseOfstForFly = 331 ((SwTxtFrm*)this)->GetBaseOfstForFly( bIgnoreFlysAnchoredAtThisFrame ); 332 if ( IsVertical() ) 333 aAnchor.Y() += nBaseOfstForFly; 334 else 335 aAnchor.X() += nBaseOfstForFly; 336 337 // OD 2004-03-10 #i11860# - if option 'Use former object positioning' 338 // is OFF, consider the lower space and the line spacing of the 339 // previous frame and the spacing considered for the page grid 340 const SwTxtFrm* pThisTxtFrm = static_cast<const SwTxtFrm*>(this); 341 const SwTwips nUpperSpaceAmountConsideredForPrevFrmAndPageGrid = 342 pThisTxtFrm->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid(); 343 if ( IsVertical() ) 344 { 345 aAnchor.X() -= nUpperSpaceAmountConsideredForPrevFrmAndPageGrid; 346 } 347 else 348 { 349 aAnchor.Y() += nUpperSpaceAmountConsideredForPrevFrmAndPageGrid; 350 } 351 } 352 353 return aAnchor; 354 } 355 356 357 /************************************************************************* 358 |* 359 |* SwFrm::~SwFrm() 360 |* 361 |*************************************************************************/ 362 363 SwFrm::~SwFrm() 364 { 365 // accessible objects for fly and cell frames have been already disposed 366 // by the destructors of the derived classes. 367 if( IsAccessibleFrm() && !(IsFlyFrm() || IsCellFrm()) && GetDep() ) 368 { 369 SwRootFrm *pRootFrm = getRootFrm(); 370 if( pRootFrm && pRootFrm->IsAnyShellAccessible() ) 371 { 372 ViewShell *pVSh = pRootFrm->GetCurrShell(); 373 if( pVSh && pVSh->Imp() ) 374 { 375 ASSERT( !GetLower(), "Lowers should be dispose already!" ); 376 pVSh->Imp()->DisposeAccessibleFrm( this ); 377 } 378 } 379 } 380 381 if( pDrawObjs ) 382 { 383 for ( sal_uInt32 i = pDrawObjs->Count(); i; ) 384 { 385 SwAnchoredObject* pAnchoredObj = (*pDrawObjs)[--i]; 386 if ( pAnchoredObj->ISA(SwFlyFrm) ) 387 delete pAnchoredObj; 388 else 389 { 390 SdrObject* pSdrObj = pAnchoredObj->DrawObj(); 391 SwDrawContact* pContact = 392 static_cast<SwDrawContact*>(pSdrObj->GetUserCall()); 393 ASSERT( pContact, 394 "<SwFrm::~SwFrm> - missing contact for drawing object" ); 395 if ( pContact ) 396 { 397 pContact->DisconnectObjFromLayout( pSdrObj ); 398 } 399 } 400 } 401 if ( pDrawObjs ) 402 delete pDrawObjs; 403 } 404 405 #ifdef DBG_UTIL 406 // JP 15.10.2001: for detection of access to deleted frames 407 pDrawObjs = (SwSortedObjs*)0x33333333; 408 #endif 409 } 410 411 /*************************************************************************/ 412 413 const SwFrmFmt * SwLayoutFrm::GetFmt() const 414 { 415 return static_cast< const SwFlyFrmFmt * >( GetDep() ); 416 } 417 418 SwFrmFmt * SwLayoutFrm::GetFmt() 419 { 420 return static_cast< SwFlyFrmFmt * >( GetDep() ); 421 } 422 423 424 /************************************************************************* 425 |* 426 |* SwLayoutFrm::SetFrmFmt() 427 |* 428 |*************************************************************************/ 429 430 431 void SwLayoutFrm::SetFrmFmt( SwFrmFmt *pNew ) 432 { 433 if ( pNew != GetFmt() ) 434 { 435 SwFmtChg aOldFmt( GetFmt() ); 436 pNew->Add( this ); 437 SwFmtChg aNewFmt( pNew ); 438 ModifyNotification( &aOldFmt, &aNewFmt ); 439 } 440 } 441 442 /************************************************************************* 443 |* SwCntntFrm::SwCntntFrm() 444 |*************************************************************************/ 445 SwCntntFrm::SwCntntFrm( SwCntntNode * const pCntnt, SwFrm* pSib ) : 446 SwFrm( pCntnt, pSib ), 447 SwFlowFrm( (SwFrm&)*this ) 448 { 449 } 450 451 /************************************************************************* 452 |* SwCntntFrm::~SwCntntFrm() 453 |*************************************************************************/ 454 SwCntntFrm::~SwCntntFrm() 455 { 456 SwCntntNode* pCNd; 457 if( 0 != ( pCNd = PTR_CAST( SwCntntNode, GetRegisteredIn() )) && 458 !pCNd->GetDoc()->IsInDtor() ) 459 { 460 //Bei der Root abmelden wenn ich dort noch im Turbo stehe. 461 SwRootFrm *pRoot = getRootFrm(); 462 if( pRoot && pRoot->GetTurbo() == this ) 463 { 464 pRoot->DisallowTurbo(); 465 pRoot->ResetTurbo(); 466 } 467 if( IsTxtFrm() && ((SwTxtFrm*)this)->HasFtn() ) 468 { 469 SwTxtNode *pTxtNd = ((SwTxtFrm*)this)->GetTxtNode(); 470 const SwFtnIdxs &rFtnIdxs = pCNd->GetDoc()->GetFtnIdxs(); 471 sal_uInt16 nPos; 472 sal_uLong nIndex = pCNd->GetIndex(); 473 rFtnIdxs.SeekEntry( *pTxtNd, &nPos ); 474 SwTxtFtn* pTxtFtn; 475 if( nPos < rFtnIdxs.Count() ) 476 { 477 while( nPos && pTxtNd == &(rFtnIdxs[ nPos ]->GetTxtNode()) ) 478 --nPos; 479 if( nPos || pTxtNd != &(rFtnIdxs[ nPos ]->GetTxtNode()) ) 480 ++nPos; 481 } 482 while( nPos < rFtnIdxs.Count() ) 483 { 484 pTxtFtn = rFtnIdxs[ nPos ]; 485 if( pTxtFtn->GetTxtNode().GetIndex() > nIndex ) 486 break; 487 pTxtFtn->DelFrms( this ); 488 ++nPos; 489 } 490 } 491 } 492 } 493 494 void SwCntntFrm::RegisterToNode( SwCntntNode& rNode ) 495 { 496 rNode.Add( this ); 497 } 498 499 void SwCntntFrm::DelFrms( const SwCntntNode& rNode ) 500 { 501 SwIterator<SwCntntFrm,SwCntntNode> aIter( rNode ); 502 for( SwCntntFrm* pFrm = aIter.First(); pFrm; pFrm = aIter.Next() ) 503 { 504 // --> OD 2005-12-01 #i27138# 505 // notify accessibility paragraphs objects about changed 506 // CONTENT_FLOWS_FROM/_TO relation. 507 // Relation CONTENT_FLOWS_FROM for current next paragraph will change 508 // and relation CONTENT_FLOWS_TO for current previous paragraph will change. 509 if ( pFrm->IsTxtFrm() ) 510 { 511 ViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() ); 512 if ( pViewShell && pViewShell->GetLayout() && 513 pViewShell->GetLayout()->IsAnyShellAccessible() ) 514 { 515 pViewShell->InvalidateAccessibleParaFlowRelation( 516 dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )), 517 dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) ); 518 } 519 } 520 // <-- 521 if( pFrm->HasFollow() ) 522 pFrm->GetFollow()->_SetIsFollow( pFrm->IsFollow() ); 523 if( pFrm->IsFollow() ) 524 { 525 SwCntntFrm* pMaster = (SwTxtFrm*)pFrm->FindMaster(); 526 pMaster->SetFollow( pFrm->GetFollow() ); 527 pFrm->_SetIsFollow( sal_False ); 528 } 529 pFrm->SetFollow( 0 );//Damit er nicht auf dumme Gedanken kommt. 530 //Andernfalls kann es sein, dass ein Follow 531 //vor seinem Master zerstoert wird, der Master 532 //greift dann ueber den ungueltigen 533 //Follow-Pointer auf fremdes Memory zu. 534 //Die Kette darf hier zerknauscht werden, weil 535 //sowieso alle zerstoert werden. 536 if( pFrm->GetUpper() && pFrm->IsInFtn() && !pFrm->GetIndNext() && 537 !pFrm->GetIndPrev() ) 538 { 539 SwFtnFrm *pFtn = pFrm->FindFtnFrm(); 540 ASSERT( pFtn, "You promised a FtnFrm?" ); 541 SwCntntFrm* pCFrm; 542 if( !pFtn->GetFollow() && !pFtn->GetMaster() && 543 0 != ( pCFrm = pFtn->GetRefFromAttr()) && pCFrm->IsFollow() ) 544 { 545 ASSERT( pCFrm->IsTxtFrm(), "NoTxtFrm has Footnote?" ); 546 ((SwTxtFrm*)pCFrm->FindMaster())->Prepare( PREP_FTN_GONE ); 547 } 548 } 549 pFrm->Cut(); 550 delete pFrm; 551 } 552 } 553 554 /************************************************************************* 555 |* 556 |* SwLayoutFrm::~SwLayoutFrm 557 |* 558 |*************************************************************************/ 559 560 561 SwLayoutFrm::~SwLayoutFrm() 562 { 563 SwFrm *pFrm = pLower; 564 565 if( GetFmt() && !GetFmt()->GetDoc()->IsInDtor() ) 566 { 567 while ( pFrm ) 568 { 569 //Erst die Objs des Frm vernichten, denn diese koennen sich sonst nach 570 //dem Remove nicht mehr bei der Seite abmelden. 571 //Falls sich einer nicht abmeldet wollen wir nicht gleich 572 //endlos schleifen. 573 574 sal_uInt32 nCnt; 575 while ( pFrm->GetDrawObjs() && pFrm->GetDrawObjs()->Count() ) 576 { 577 nCnt = pFrm->GetDrawObjs()->Count(); 578 // --> OD 2004-06-30 #i28701# 579 SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[0]; 580 if ( pAnchoredObj->ISA(SwFlyFrm) ) 581 delete pAnchoredObj; 582 else 583 { 584 SdrObject* pSdrObj = pAnchoredObj->DrawObj(); 585 SwDrawContact* pContact = 586 static_cast<SwDrawContact*>(pSdrObj->GetUserCall()); 587 ASSERT( pContact, 588 "<SwFrm::~SwFrm> - missing contact for drawing object" ); 589 if ( pContact ) 590 { 591 pContact->DisconnectObjFromLayout( pSdrObj ); 592 } 593 } 594 if ( pFrm->GetDrawObjs() && 595 nCnt == pFrm->GetDrawObjs()->Count() ) 596 { 597 pFrm->GetDrawObjs()->Remove( *pAnchoredObj ); 598 } 599 // <-- 600 } 601 pFrm->Remove(); 602 delete pFrm; 603 pFrm = pLower; 604 } 605 //Fly's vernichten. Der letzte loescht gleich das Array. 606 sal_uInt32 nCnt; 607 while ( GetDrawObjs() && GetDrawObjs()->Count() ) 608 { 609 nCnt = GetDrawObjs()->Count(); 610 611 // --> OD 2004-06-30 #i28701# 612 SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[0]; 613 if ( pAnchoredObj->ISA(SwFlyFrm) ) 614 delete pAnchoredObj; 615 else 616 { 617 SdrObject* pSdrObj = pAnchoredObj->DrawObj(); 618 SwDrawContact* pContact = 619 static_cast<SwDrawContact*>(pSdrObj->GetUserCall()); 620 ASSERT( pContact, 621 "<SwFrm::~SwFrm> - missing contact for drawing object" ); 622 if ( pContact ) 623 { 624 pContact->DisconnectObjFromLayout( pSdrObj ); 625 } 626 } 627 if ( GetDrawObjs() && nCnt == GetDrawObjs()->Count() ) 628 { 629 GetDrawObjs()->Remove( *pAnchoredObj ); 630 } 631 // <-- 632 } 633 } 634 else 635 { 636 while( pFrm ) 637 { 638 SwFrm *pNxt = pFrm->GetNext(); 639 delete pFrm; 640 pFrm = pNxt; 641 } 642 } 643 } 644 645 /************************************************************************* 646 |* 647 |* SwFrm::PaintArea() 648 |* 649 |* The paintarea is the area, in which the content of a frame is allowed 650 |* to be displayed. This region could be larger than the printarea (Prt()) 651 |* of the upper, it includes e.g. often the margin of the page. 652 |* 653 |*************************************************************************/ 654 655 const SwRect SwFrm::PaintArea() const 656 { 657 // NEW TABLES 658 // Cell frames may not leave their upper: 659 SwRect aRect = IsRowFrm() ? GetUpper()->Frm() : Frm(); 660 const sal_Bool bVert = IsVertical(); 661 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 662 SwRectFn fnRect = bVert ? ( IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori; 663 long nRight = (aRect.*fnRect->fnGetRight)(); 664 long nLeft = (aRect.*fnRect->fnGetLeft)(); 665 const SwFrm* pTmp = this; 666 sal_Bool bLeft = sal_True; 667 sal_Bool bRight = sal_True; 668 long nRowSpan = 0; 669 while( pTmp ) 670 { 671 if( pTmp->IsCellFrm() && pTmp->GetUpper() && 672 pTmp->GetUpper()->IsVertical() != pTmp->IsVertical() ) 673 nRowSpan = ((SwCellFrm*)pTmp)->GetTabBox()->getRowSpan(); 674 long nTmpRight = (pTmp->Frm().*fnRect->fnGetRight)(); 675 long nTmpLeft = (pTmp->Frm().*fnRect->fnGetLeft)(); 676 if( pTmp->IsRowFrm() && nRowSpan > 1 ) 677 { 678 const SwFrm* pNxt = pTmp; 679 while( --nRowSpan > 0 && pNxt->GetNext() ) 680 pNxt = pNxt->GetNext(); 681 if( pTmp->IsVertical() ) 682 nTmpLeft = (pNxt->Frm().*fnRect->fnGetLeft)(); 683 else 684 nTmpRight = (pNxt->Frm().*fnRect->fnGetRight)(); 685 } 686 ASSERT( pTmp, "PaintArea lost in time and space" ); 687 if( pTmp->IsPageFrm() || pTmp->IsFlyFrm() || 688 pTmp->IsCellFrm() || pTmp->IsRowFrm() || //nobody leaves a table! 689 pTmp->IsRootFrm() ) 690 { 691 if( bLeft || nLeft < nTmpLeft ) 692 nLeft = nTmpLeft; 693 if( bRight || nTmpRight < nRight ) 694 nRight = nTmpRight; 695 if( pTmp->IsPageFrm() || pTmp->IsFlyFrm() || pTmp->IsRootFrm() ) 696 break; 697 bLeft = sal_False; 698 bRight = sal_False; 699 } 700 else if( pTmp->IsColumnFrm() ) // nobody enters neightbour columns 701 { 702 sal_Bool bR2L = pTmp->IsRightToLeft(); 703 // the first column has _no_ influence to the left range 704 if( bR2L ? pTmp->GetNext() : pTmp->GetPrev() ) 705 { 706 if( bLeft || nLeft < nTmpLeft ) 707 nLeft = nTmpLeft; 708 bLeft = sal_False; 709 } 710 // the last column has _no_ influence to the right range 711 if( bR2L ? pTmp->GetPrev() : pTmp->GetNext() ) 712 { 713 if( bRight || nTmpRight < nRight ) 714 nRight = nTmpRight; 715 bRight = sal_False; 716 } 717 } 718 else if( bVert && pTmp->IsBodyFrm() ) 719 { 720 // Header and footer frames have always horizontal direction and 721 // limit the body frame. 722 // A previous frame of a body frame must be a header, 723 // the next frame of a body frame may be a footnotecontainer or 724 // a footer. The footnotecontainer has the same direction like 725 // the body frame. 726 if( pTmp->GetPrev() && ( bLeft || nLeft < nTmpLeft ) ) 727 { 728 nLeft = nTmpLeft; 729 bLeft = sal_False; 730 } 731 if( pTmp->GetNext() && 732 ( pTmp->GetNext()->IsFooterFrm() || pTmp->GetNext()->GetNext() ) 733 && ( bRight || nTmpRight < nRight ) ) 734 { 735 nRight = nTmpRight; 736 bRight = sal_False; 737 } 738 } 739 pTmp = pTmp->GetUpper(); 740 } 741 (aRect.*fnRect->fnSetLeft)( nLeft ); 742 (aRect.*fnRect->fnSetRight)( nRight ); 743 return aRect; 744 } 745 746 /************************************************************************* 747 |* 748 |* SwFrm::UnionFrm() 749 |* 750 |* The unionframe is the framearea (Frm()) of a frame expanded by the 751 |* printarea, if there's a negative margin at the left or right side. 752 |* 753 |*************************************************************************/ 754 755 const SwRect SwFrm::UnionFrm( sal_Bool bBorder ) const 756 { 757 sal_Bool bVert = IsVertical(); 758 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 759 SwRectFn fnRect = bVert ? ( IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori; 760 long nLeft = (Frm().*fnRect->fnGetLeft)(); 761 long nWidth = (Frm().*fnRect->fnGetWidth)(); 762 long nPrtLeft = (Prt().*fnRect->fnGetLeft)(); 763 long nPrtWidth = (Prt().*fnRect->fnGetWidth)(); 764 if( nPrtLeft + nPrtWidth > nWidth ) 765 nWidth = nPrtLeft + nPrtWidth; 766 if( nPrtLeft < 0 ) 767 { 768 nLeft += nPrtLeft; 769 nWidth -= nPrtLeft; 770 } 771 SwTwips nRight = nLeft + nWidth; 772 long nAdd = 0; 773 if( bBorder ) 774 { 775 SwBorderAttrAccess aAccess( SwFrm::GetCache(), this ); 776 const SwBorderAttrs &rAttrs = *aAccess.Get(); 777 const SvxBoxItem &rBox = rAttrs.GetBox(); 778 if ( rBox.GetLeft() ) 779 nLeft -= rBox.CalcLineSpace( BOX_LINE_LEFT ); 780 else if ( rAttrs.IsBorderDist() ) 781 nLeft -= rBox.GetDistance( BOX_LINE_LEFT ) + 1; 782 if ( rBox.GetRight() ) 783 nAdd += rBox.CalcLineSpace( BOX_LINE_RIGHT ); 784 else if ( rAttrs.IsBorderDist() ) 785 nAdd += rBox.GetDistance( BOX_LINE_RIGHT ) + 1; 786 if( rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE ) 787 { 788 const SvxShadowItem &rShadow = rAttrs.GetShadow(); 789 nLeft -= rShadow.CalcShadowSpace( SHADOW_LEFT ); 790 nAdd += rShadow.CalcShadowSpace( SHADOW_RIGHT ); 791 } 792 } 793 if( IsTxtFrm() && ((SwTxtFrm*)this)->HasPara() ) 794 { 795 long nTmp = ((SwTxtFrm*)this)->HangingMargin(); 796 if( nTmp > nAdd ) 797 nAdd = nTmp; 798 } 799 nWidth = nRight + nAdd - nLeft; 800 SwRect aRet( Frm() ); 801 (aRet.*fnRect->fnSetPosX)( nLeft ); 802 (aRet.*fnRect->fnSetWidth)( nWidth ); 803 return aRet; 804 } 805 806 807 808 809