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