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
GetTopMargin() const57 long SwFrm::GetTopMargin() const
58 { return Prt().Top(); }
GetBottomMargin() const59 long SwFrm::GetBottomMargin() const
60 { return Frm().Height() -Prt().Height() -Prt().Top(); }
GetLeftMargin() const61 long SwFrm::GetLeftMargin() const
62 { return Prt().Left(); }
GetRightMargin() const63 long SwFrm::GetRightMargin() const
64 { return Frm().Width() - Prt().Width() - Prt().Left(); }
GetPrtLeft() const65 long SwFrm::GetPrtLeft() const
66 { return Frm().Left() + Prt().Left(); }
GetPrtBottom() const67 long SwFrm::GetPrtBottom() const
68 { return Frm().Top() + Prt().Height() + Prt().Top(); }
GetPrtRight() const69 long SwFrm::GetPrtRight() const
70 { return Frm().Left() + Prt().Width() + Prt().Left(); }
GetPrtTop() const71 long SwFrm::GetPrtTop() const
72 { return Frm().Top() + Prt().Top(); }
73
SetMinLeft(long nDeadline)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
SetMaxBottom(long nDeadline)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
SetMinTop(long nDeadline)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
SetMaxRight(long nDeadline)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
MakeBelowPos(const SwFrm * pUp,const SwFrm * pPrv,sal_Bool bNotify)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
MakeUpperPos(const SwFrm * pUp,const SwFrm * pPrv,sal_Bool bNotify)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
MakeLeftPos(const SwFrm * pUp,const SwFrm * pPrv,sal_Bool bNotify)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
MakeRightPos(const SwFrm * pUp,const SwFrm * pPrv,sal_Bool bNotify)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
SetTopBottomMargins(long nTop,long nBot)188 void SwFrm::SetTopBottomMargins( long nTop, long nBot )
189 {
190 Prt().Top( nTop );
191 Prt().Height( Frm().Height() - nTop - nBot );
192 }
193
SetBottomTopMargins(long nBot,long nTop)194 void SwFrm::SetBottomTopMargins( long nBot, long nTop )
195 {
196 Prt().Top( nTop );
197 Prt().Height( Frm().Height() - nTop - nBot );
198 }
199
SetLeftRightMargins(long nLeft,long nRight)200 void SwFrm::SetLeftRightMargins( long nLeft, long nRight)
201 {
202 Prt().Left( nLeft );
203 Prt().Width( Frm().Width() - nLeft - nRight );
204 }
205
SetRightLeftMargins(long nRight,long nLeft)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
CheckDirChange()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'
GetFrmAnchorPos(sal_Bool bIgnoreFlysAnchoredAtThisFrame) const321 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
~SwFrm()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
GetFmt() const413 const SwFrmFmt * SwLayoutFrm::GetFmt() const
414 {
415 return static_cast< const SwFlyFrmFmt * >( GetDep() );
416 }
417
GetFmt()418 SwFrmFmt * SwLayoutFrm::GetFmt()
419 {
420 return static_cast< SwFlyFrmFmt * >( GetDep() );
421 }
422
423
424 /*************************************************************************
425 |*
426 |* SwLayoutFrm::SetFrmFmt()
427 |*
428 |*************************************************************************/
429
430
SetFrmFmt(SwFrmFmt * pNew)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 |*************************************************************************/
SwCntntFrm(SwCntntNode * const pCntnt,SwFrm * pSib)445 SwCntntFrm::SwCntntFrm( SwCntntNode * const pCntnt, SwFrm* pSib ) :
446 SwFrm( pCntnt, pSib ),
447 SwFlowFrm( (SwFrm&)*this )
448 {
449 }
450
451 /*************************************************************************
452 |* SwCntntFrm::~SwCntntFrm()
453 |*************************************************************************/
~SwCntntFrm()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
RegisterToNode(SwCntntNode & rNode)494 void SwCntntFrm::RegisterToNode( SwCntntNode& rNode )
495 {
496 rNode.Add( this );
497 }
498
DelFrms(const SwCntntNode & rNode)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
~SwLayoutFrm()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
PaintArea() const655 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
UnionFrm(sal_Bool bBorder) const755 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