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 : #include <tools/bigint.hxx>
21 : #include <svx/svdmodel.hxx>
22 : #include <svx/svdpage.hxx>
23 : #include <editeng/brushitem.hxx>
24 : #include <editeng/shaditem.hxx>
25 : #include <editeng/ulspitem.hxx>
26 : #include <editeng/boxitem.hxx>
27 : #include <editeng/lspcitem.hxx>
28 :
29 : #include <fmtornt.hxx>
30 : #include <fmthdft.hxx>
31 : #include <fmtfsize.hxx>
32 : #include <fmtsrnd.hxx>
33 : #include <docary.hxx>
34 : #include <lineinfo.hxx>
35 : #include <swmodule.hxx>
36 : #include "pagefrm.hxx"
37 : #include "colfrm.hxx"
38 : #include "fesh.hxx"
39 : #include "viewimp.hxx"
40 : #include "viewopt.hxx"
41 : #include "dflyobj.hxx"
42 : #include "dcontact.hxx"
43 : #include "frmtool.hxx"
44 : #include "tabfrm.hxx"
45 : #include "rowfrm.hxx"
46 : #include "ftnfrm.hxx"
47 : #include "txtfrm.hxx"
48 : #include "notxtfrm.hxx"
49 : #include "flyfrms.hxx"
50 : #include "layact.hxx"
51 : #include "pagedesc.hxx"
52 : #include "section.hxx"
53 : #include "sectfrm.hxx"
54 : #include "node2lay.hxx"
55 : #include "ndole.hxx"
56 : #include "hints.hxx"
57 : #include <layhelp.hxx>
58 : #include <laycache.hxx>
59 : #include <rootfrm.hxx>
60 : #include <paratr.hxx>
61 : #include <sortedobjs.hxx>
62 : #include <objectformatter.hxx>
63 : #include <switerator.hxx>
64 :
65 : // ftnfrm.cxx:
66 : void sw_RemoveFtns( SwFtnBossFrm* pBoss, sal_Bool bPageOnly, sal_Bool bEndNotes );
67 :
68 : using namespace ::com::sun::star;
69 :
70 :
71 : bool bObjsDirect = true;
72 : bool bDontCreateObjects = false;
73 : bool bSetCompletePaintOnInvalidate = false;
74 :
75 : sal_uInt8 StackHack::nCnt = 0;
76 : sal_Bool StackHack::bLocked = sal_False;
77 :
78 :
79 :
80 : /*************************************************************************/
81 :
82 24196 : SwFrmNotify::SwFrmNotify( SwFrm *pF ) :
83 : pFrm( pF ),
84 24196 : aFrm( pF->Frm() ),
85 24196 : aPrt( pF->Prt() ),
86 : bInvaKeep( sal_False ),
87 24196 : bValidSize( pF->GetValidSizeFlag() ),
88 96784 : mbFrmDeleted( false ) // #i49383#
89 : {
90 24196 : if ( pF->IsTxtFrm() )
91 : {
92 12243 : mnFlyAnchorOfst = ((SwTxtFrm*)pF)->GetBaseOfstForFly( sal_True );
93 12243 : mnFlyAnchorOfstNoWrap = ((SwTxtFrm*)pF)->GetBaseOfstForFly( sal_False );
94 : }
95 : else
96 : {
97 11953 : mnFlyAnchorOfst = 0;
98 11953 : mnFlyAnchorOfstNoWrap = 0;
99 : }
100 :
101 24196 : bHadFollow = pF->IsCntntFrm() ?
102 12635 : (((SwCntntFrm*)pF)->GetFollow() ? sal_True : sal_False) :
103 36831 : sal_False;
104 24196 : }
105 :
106 : /*************************************************************************/
107 :
108 24196 : SwFrmNotify::~SwFrmNotify()
109 : {
110 : // #i49383#
111 24196 : if ( mbFrmDeleted )
112 : {
113 0 : return;
114 : }
115 :
116 24196 : SWRECTFN( pFrm )
117 24196 : const bool bAbsP = POS_DIFF( aFrm, pFrm->Frm() );
118 : const bool bChgWidth =
119 24196 : (aFrm.*fnRect->fnGetWidth)() != (pFrm->Frm().*fnRect->fnGetWidth)();
120 : const bool bChgHeight =
121 24196 : (aFrm.*fnRect->fnGetHeight)()!=(pFrm->Frm().*fnRect->fnGetHeight)();
122 36444 : const bool bChgFlyBasePos = pFrm->IsTxtFrm() &&
123 24483 : ( ( mnFlyAnchorOfst != ((SwTxtFrm*)pFrm)->GetBaseOfstForFly( sal_True ) ) ||
124 36436 : ( mnFlyAnchorOfstNoWrap != ((SwTxtFrm*)pFrm)->GetBaseOfstForFly( sal_False ) ) );
125 :
126 24196 : if ( pFrm->IsFlowFrm() && !pFrm->IsInFtn() )
127 : {
128 13439 : SwFlowFrm *pFlow = SwFlowFrm::CastFlowFrm( pFrm );
129 :
130 13439 : if ( !pFlow->IsFollow() )
131 : {
132 12579 : if ( !pFrm->GetIndPrev() )
133 : {
134 8526 : if ( bInvaKeep )
135 : {
136 618 : SwFrm *pPre = pFrm->FindPrev();
137 618 : if ( pPre && pPre->IsFlowFrm() )
138 : {
139 : // 1. pPre wants to keep with me:
140 69 : bool bInvalidPrePos = SwFlowFrm::CastFlowFrm( pPre )->IsKeep( *pPre->GetAttrSet() ) && pPre->GetIndPrev();
141 :
142 : // 2. pPre is a table and the last row wants to keep with me:
143 69 : if ( !bInvalidPrePos && pPre->IsTabFrm() )
144 : {
145 42 : SwTabFrm* pPreTab = static_cast<SwTabFrm*>(pPre);
146 42 : if ( pPreTab->GetFmt()->GetDoc()->get(IDocumentSettingAccess::TABLE_ROW_KEEP) )
147 : {
148 40 : SwRowFrm* pLastRow = static_cast<SwRowFrm*>(pPreTab->GetLastLower());
149 40 : if ( pLastRow && pLastRow->ShouldRowKeepWithNext() )
150 0 : bInvalidPrePos = true;
151 : }
152 : }
153 :
154 69 : if ( bInvalidPrePos )
155 0 : pPre->InvalidatePos();
156 : }
157 : }
158 : }
159 4053 : else if ( !pFlow->HasFollow() )
160 : {
161 3918 : long nOldHeight = (aFrm.*fnRect->fnGetHeight)();
162 3918 : long nNewHeight = (pFrm->Frm().*fnRect->fnGetHeight)();
163 3918 : if( (nOldHeight > nNewHeight) || (!nOldHeight && nNewHeight) )
164 1248 : pFlow->CheckKeep();
165 : }
166 : }
167 : }
168 :
169 24196 : if ( bAbsP )
170 : {
171 10504 : pFrm->SetCompletePaint();
172 :
173 10504 : SwFrm* pNxt = pFrm->GetIndNext();
174 : // #121888# - skip empty section frames
175 25104 : while ( pNxt &&
176 10655 : pNxt->IsSctFrm() && !static_cast<SwSectionFrm*>(pNxt)->GetSection() )
177 : {
178 36 : pNxt = pNxt->GetIndNext();
179 : }
180 :
181 10504 : if ( pNxt )
182 4024 : pNxt->InvalidatePos();
183 : else
184 : {
185 : // #104100# - correct condition for setting retouche
186 : // flag for vertical layout.
187 10358 : if( pFrm->IsRetoucheFrm() &&
188 3878 : (aFrm.*fnRect->fnTopDist)( (pFrm->Frm().*fnRect->fnGetTop)() ) > 0 )
189 : {
190 1086 : pFrm->SetRetouche();
191 : }
192 :
193 : // A fresh follow frame does not have to be invalidated, because
194 : // it is already formatted:
195 6480 : if ( bHadFollow || !pFrm->IsCntntFrm() || !((SwCntntFrm*)pFrm)->GetFollow() )
196 : {
197 6467 : if ( !pFrm->IsTabFrm() || !((SwTabFrm*)pFrm)->GetFollow() )
198 6466 : pFrm->InvalidateNextPos();
199 : }
200 : }
201 : }
202 :
203 : //For each resize of the background graphics is a repaint necessary.
204 : const bool bPrtWidth =
205 24196 : (aPrt.*fnRect->fnGetWidth)() != (pFrm->Prt().*fnRect->fnGetWidth)();
206 : const bool bPrtHeight =
207 24196 : (aPrt.*fnRect->fnGetHeight)()!=(pFrm->Prt().*fnRect->fnGetHeight)();
208 24196 : if ( bPrtWidth || bPrtHeight )
209 : {
210 10997 : const SvxGraphicPosition ePos = pFrm->GetAttrSet()->GetBackground().GetGraphicPos();
211 10997 : if ( GPOS_NONE != ePos && GPOS_TILED != ePos )
212 6 : pFrm->SetCompletePaint();
213 : }
214 : else
215 : {
216 : // #97597# - consider case that *only* margins between
217 : // frame and printing area has changed. Then, frame has to be repainted,
218 : // in order to force paint of the margin areas.
219 13199 : if ( !bAbsP && (bChgWidth || bChgHeight) )
220 : {
221 62 : pFrm->SetCompletePaint();
222 : }
223 : }
224 :
225 24196 : const bool bPrtP = POS_DIFF( aPrt, pFrm->Prt() );
226 24196 : if ( bAbsP || bPrtP || bChgWidth || bChgHeight ||
227 11414 : bPrtWidth || bPrtHeight || bChgFlyBasePos )
228 : {
229 13375 : if( pFrm->IsAccessibleFrm() )
230 : {
231 10610 : SwRootFrm *pRootFrm = pFrm->getRootFrm();
232 10611 : if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
233 1 : pRootFrm->GetCurrShell() )
234 : {
235 1 : pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( pFrm, aFrm );
236 : }
237 : }
238 :
239 : // Notification of anchored objects
240 13375 : if ( pFrm->GetDrawObjs() )
241 : {
242 520 : const SwSortedObjs &rObjs = *pFrm->GetDrawObjs();
243 520 : SwPageFrm* pPageFrm = 0;
244 1185 : for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i )
245 : {
246 : // OD 2004-03-31 #i26791# - no general distinction between
247 : // Writer fly frames and drawing objects
248 665 : bool bNotify = false;
249 665 : bool bNotifySize = false;
250 665 : SwAnchoredObject* pObj = rObjs[i];
251 665 : SwContact* pContact = ::GetUserCall( pObj->GetDrawObj() );
252 : // #115759#
253 665 : const bool bAnchoredAsChar = pContact->ObjAnchoredAsChar();
254 665 : if ( !bAnchoredAsChar )
255 : {
256 : // Notify object, which aren't anchored as-character:
257 :
258 : // always notify objects, if frame position has changed
259 : // or if the object is to-page|to-fly anchored.
260 192 : if ( bAbsP ||
261 192 : pContact->ObjAnchoredAtPage() ||
262 24 : pContact->ObjAnchoredAtFly() )
263 : {
264 144 : bNotify = true;
265 :
266 : // assure that to-fly anchored Writer fly frames are
267 : // registered at the correct page frame, if frame
268 : // position has changed.
269 144 : if ( bAbsP && pContact->ObjAnchoredAtFly() &&
270 0 : pObj->ISA(SwFlyFrm) )
271 : {
272 : // determine to-fly anchored Writer fly frame
273 0 : SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
274 : // determine page frame of to-fly anchored
275 : // Writer fly frame
276 0 : SwPageFrm* pFlyPageFrm = pFlyFrm->FindPageFrm();
277 : // determine page frame, if needed.
278 0 : if ( !pPageFrm )
279 : {
280 0 : pPageFrm = pFrm->FindPageFrm();
281 : }
282 0 : if ( pPageFrm != pFlyPageFrm )
283 : {
284 : OSL_ENSURE( pFlyPageFrm, "~SwFrmNotify: Fly from Nowhere" );
285 0 : if( pFlyPageFrm )
286 0 : pFlyPageFrm->MoveFly( pFlyFrm, pPageFrm );
287 : else
288 0 : pPageFrm->AppendFlyToPage( pFlyFrm );
289 : }
290 : }
291 : }
292 : // otherwise the objects are notified in dependence to
293 : // its positioning and alignment
294 : else
295 : {
296 : const SwFmtVertOrient& rVert =
297 24 : pContact->GetFmt()->GetVertOrient();
298 70 : if ( ( rVert.GetVertOrient() == text::VertOrientation::CENTER ||
299 44 : rVert.GetVertOrient() == text::VertOrientation::BOTTOM ||
300 52 : rVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA ) &&
301 0 : ( bChgHeight || bPrtHeight ) )
302 : {
303 3 : bNotify = true;
304 : }
305 24 : if ( !bNotify )
306 : {
307 : const SwFmtHoriOrient& rHori =
308 21 : pContact->GetFmt()->GetHoriOrient();
309 59 : if ( ( rHori.GetHoriOrient() != text::HoriOrientation::NONE ||
310 34 : rHori.GetRelationOrient()== text::RelOrientation::PRINT_AREA ||
311 56 : rHori.GetRelationOrient()== text::RelOrientation::FRAME ) &&
312 17 : ( bChgWidth || bPrtWidth || bChgFlyBasePos ) )
313 : {
314 1 : bNotify = true;
315 : }
316 : }
317 : }
318 : }
319 497 : else if ( bPrtWidth )
320 : {
321 : // Notify as-character anchored objects, if printing area
322 : // width has changed.
323 194 : bNotify = true;
324 194 : bNotifySize = true;
325 : }
326 :
327 : // perform notification via the corresponding invalidations
328 665 : if ( bNotify )
329 : {
330 342 : if ( pObj->ISA(SwFlyFrm) )
331 : {
332 277 : SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
333 277 : if ( bNotifySize )
334 176 : pFlyFrm->_InvalidateSize();
335 : // #115759# - no invalidation of
336 : // position for as-character anchored objects.
337 277 : if ( !bAnchoredAsChar )
338 : {
339 101 : pFlyFrm->_InvalidatePos();
340 : }
341 277 : pFlyFrm->_Invalidate();
342 : }
343 65 : else if ( pObj->ISA(SwAnchoredDrawObject) )
344 : {
345 : // #115759# - no invalidation of
346 : // position for as-character anchored objects.
347 65 : if ( !bAnchoredAsChar )
348 : {
349 47 : pObj->InvalidateObjPos();
350 : }
351 : }
352 : else
353 : {
354 : OSL_FAIL( "<SwCntntNotify::~SwCntntNotify()> - unknown anchored object type. Please inform OD." );
355 : }
356 : }
357 : }
358 13375 : }
359 : }
360 10821 : else if( pFrm->IsTxtFrm() && bValidSize != pFrm->GetValidSizeFlag() )
361 : {
362 5709 : SwRootFrm *pRootFrm = pFrm->getRootFrm();
363 5709 : if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
364 0 : pRootFrm->GetCurrShell() )
365 : {
366 0 : pRootFrm->GetCurrShell()->Imp()->InvalidateAccessibleFrmContent( pFrm );
367 : }
368 : }
369 :
370 : // #i9046# Automatic frame width
371 24196 : SwFlyFrm* pFly = 0;
372 : // #i35879# Do not trust the inf flags. pFrm does not
373 : // necessarily have to have an upper!
374 24196 : if ( !pFrm->IsFlyFrm() && 0 != ( pFly = pFrm->ImplFindFlyFrm() ) )
375 : {
376 : // #i61999#
377 : // no invalidation of columned Writer fly frames, because automatic
378 : // width doesn't make sense for such Writer fly frames.
379 1099 : if ( pFly->Lower() && !pFly->Lower()->IsColumnFrm() )
380 : {
381 1099 : const SwFmtFrmSize &rFrmSz = pFly->GetFmt()->GetFrmSize();
382 :
383 : // This could be optimized. Basically the fly frame only has to
384 : // be invalidated, if the first line of pFrm (if pFrm is a content
385 : // frame, for other frame types its the print area) has changed its
386 : // size and pFrm was responsible for the current width of pFly. On
387 : // the other hand, this is only rarely used and re-calculation of
388 : // the fly frame does not cause too much trouble. So we keep it this
389 : // way:
390 1099 : if ( ATT_FIX_SIZE != rFrmSz.GetWidthSizeType() )
391 : {
392 : // #i50668#, #i50998# - invalidation of position
393 : // of as-character anchored fly frames not needed and can cause
394 : // layout loops
395 0 : if ( !pFly->ISA(SwFlyInCntFrm) )
396 : {
397 0 : pFly->InvalidatePos();
398 : }
399 0 : pFly->InvalidateSize();
400 : }
401 : }
402 : }
403 24196 : }
404 :
405 : /*************************************************************************/
406 :
407 11561 : SwLayNotify::SwLayNotify( SwLayoutFrm *pLayFrm ) :
408 : SwFrmNotify( pLayFrm ),
409 11561 : bLowersComplete( sal_False )
410 : {
411 11561 : }
412 :
413 : /*************************************************************************/
414 :
415 : // OD 2004-05-11 #i28701# - local method to invalidate the position of all
416 : // frames inclusive its floating screen objects, which are lowers of the given
417 : // layout frame
418 94 : static void lcl_InvalidatePosOfLowers( SwLayoutFrm& _rLayoutFrm )
419 : {
420 94 : if( _rLayoutFrm.IsFlyFrm() && _rLayoutFrm.GetDrawObjs() )
421 : {
422 0 : _rLayoutFrm.InvalidateObjs( true, false );
423 : }
424 :
425 94 : SwFrm* pLowerFrm = _rLayoutFrm.Lower();
426 299 : while ( pLowerFrm )
427 : {
428 111 : pLowerFrm->InvalidatePos();
429 111 : if ( pLowerFrm->IsTxtFrm() )
430 : {
431 107 : static_cast<SwTxtFrm*>(pLowerFrm)->Prepare( PREP_POS_CHGD );
432 : }
433 4 : else if ( pLowerFrm->IsTabFrm() )
434 : {
435 0 : pLowerFrm->InvalidatePrt();
436 : }
437 :
438 111 : pLowerFrm->InvalidateObjs( true, false );
439 :
440 111 : pLowerFrm = pLowerFrm->GetNext();
441 : };
442 94 : }
443 :
444 23122 : SwLayNotify::~SwLayNotify()
445 : {
446 : // #i49383#
447 11561 : if ( mbFrmDeleted )
448 : {
449 0 : return;
450 : }
451 :
452 11561 : SwLayoutFrm *pLay = GetLay();
453 11561 : SWRECTFN( pLay )
454 11561 : bool bNotify = false;
455 11561 : if ( pLay->Prt().SSize() != aPrt.SSize() )
456 : {
457 5661 : if ( !IsLowersComplete() )
458 : {
459 : bool bInvaPercent;
460 :
461 5657 : if ( pLay->IsRowFrm() )
462 : {
463 429 : bInvaPercent = true;
464 429 : long nNew = (pLay->Prt().*fnRect->fnGetHeight)();
465 429 : if( nNew != (aPrt.*fnRect->fnGetHeight)() )
466 375 : ((SwRowFrm*)pLay)->AdjustCells( nNew, sal_True);
467 858 : if( (pLay->Prt().*fnRect->fnGetWidth)()
468 429 : != (aPrt.*fnRect->fnGetWidth)() )
469 422 : ((SwRowFrm*)pLay)->AdjustCells( 0, sal_False );
470 : }
471 : else
472 : {
473 : //Proportional adoption of the internal.
474 : //1. If the formatted is no Fly
475 : //2. If he contains no columns
476 : //3. If the Fly has a fixed hight and the columns
477 : // are next to be.
478 : // Hoehe danebenliegen.
479 : //4. Never at SectionFrms.
480 : bool bLow;
481 5228 : if( pLay->IsFlyFrm() )
482 : {
483 465 : if ( pLay->Lower() )
484 : {
485 465 : bLow = !pLay->Lower()->IsColumnFrm() ||
486 0 : (pLay->Lower()->Frm().*fnRect->fnGetHeight)()
487 465 : != (pLay->Prt().*fnRect->fnGetHeight)();
488 : }
489 : else
490 0 : bLow = false;
491 : }
492 4763 : else if( pLay->IsSctFrm() )
493 : {
494 26 : if ( pLay->Lower() )
495 : {
496 26 : if( pLay->Lower()->IsColumnFrm() && pLay->Lower()->GetNext() )
497 3 : bLow = pLay->Lower()->Frm().Height() != pLay->Prt().Height();
498 : else
499 23 : bLow = pLay->Prt().Width() != aPrt.Width();
500 : }
501 : else
502 0 : bLow = false;
503 : }
504 4737 : else if( pLay->IsFooterFrm() && !pLay->HasFixSize() )
505 81 : bLow = pLay->Prt().Width() != aPrt.Width();
506 : else
507 4656 : bLow = true;
508 5228 : bInvaPercent = bLow;
509 5228 : if ( bLow )
510 : {
511 5202 : pLay->ChgLowersProp( aPrt.SSize() );
512 : }
513 : //Wenn die PrtArea gewachsen ist, so ist es moeglich, dass die
514 : //Kette der Untergeordneten einen weiteren Frm aufnehmen kann,
515 : //mithin muss also der 'moeglicherweise passende' Invalidiert werden.
516 : //Das invalidieren lohnt nur, wenn es sich beim mir bzw. meinen
517 : //Uppers um eine Moveable-Section handelt.
518 : //Die PrtArea ist gewachsen, wenn die Breite oder die Hoehe groesser
519 : //geworden ist.
520 11912 : if ( (pLay->Prt().Height() > aPrt.Height() ||
521 10445 : pLay->Prt().Width() > aPrt.Width()) &&
522 9104 : (pLay->IsMoveable() || pLay->IsFlyFrm()) )
523 : {
524 596 : SwFrm *pTmpFrm = pLay->Lower();
525 596 : if ( pTmpFrm && pTmpFrm->IsFlowFrm() )
526 : {
527 990 : while ( pTmpFrm->GetNext() )
528 72 : pTmpFrm = pTmpFrm->GetNext();
529 459 : pTmpFrm->InvalidateNextPos();
530 : }
531 : }
532 : }
533 5657 : bNotify = true;
534 : //EXPENSIVE!! But how we do it more elegant?
535 5657 : if( bInvaPercent )
536 5631 : pLay->InvaPercentLowers( pLay->Prt().Height() - aPrt.Height() );
537 : }
538 5661 : if ( pLay->IsTabFrm() )
539 : //So that _only_ the shadow is drawn while resizing.
540 163 : ((SwTabFrm*)pLay)->SetComplete();
541 : else
542 : {
543 5498 : const ViewShell *pSh = pLay->getRootFrm()->GetCurrShell();
544 5532 : if( !( pSh && pSh->GetViewOptions()->getBrowseMode() ) ||
545 34 : !(pLay->GetType() & (FRM_BODY | FRM_PAGE)) )
546 : //Thereby the subordinates are retouched clean.
547 : //Example problem: Take the Flys with the handles and downsize.
548 : //Not for body and page, otherwise it flickers when loading HTML.
549 5464 : pLay->SetCompletePaint();
550 : }
551 : }
552 : //Notify Lower if the position has changed.
553 11561 : const bool bPrtPos = POS_DIFF( aPrt, pLay->Prt() );
554 11561 : const bool bPos = bPrtPos || POS_DIFF( aFrm, pLay->Frm() );
555 11561 : const bool bSize = pLay->Frm().SSize() != aFrm.SSize();
556 :
557 11561 : if ( bPos && pLay->Lower() && !IsLowersComplete() )
558 4055 : pLay->Lower()->InvalidatePos();
559 :
560 11561 : if ( bPrtPos )
561 2502 : pLay->SetCompletePaint();
562 :
563 : //Inform the Follower if the SSize has changed.
564 11561 : if ( bSize )
565 : {
566 2710 : if( pLay->GetNext() )
567 : {
568 1562 : if ( pLay->GetNext()->IsLayoutFrm() )
569 1347 : pLay->GetNext()->_InvalidatePos();
570 : else
571 215 : pLay->GetNext()->InvalidatePos();
572 : }
573 1148 : else if( pLay->IsSctFrm() )
574 11 : pLay->InvalidateNextPos();
575 : }
576 34679 : if ( !IsLowersComplete() &&
577 13081 : !(pLay->GetType()&(FRM_FLY|FRM_SECTION) &&
578 3039 : pLay->Lower() && pLay->Lower()->IsColumnFrm()) &&
579 17125 : (bPos || bNotify) && !(pLay->GetType() & 0x1823) ) //Tab, Row, FtnCont, Root, Page
580 : {
581 : // #i44016# - force unlock of position of lower objects.
582 : // #i43913# - no unlock of position of objects,
583 : // if <pLay> is a cell frame, and its table frame resp. its parent table
584 : // frame is locked.
585 : // #i47458# - force unlock of position of lower objects,
586 : // only if position of layout frame has changed.
587 4926 : bool bUnlockPosOfObjs( bPos );
588 4926 : if ( bUnlockPosOfObjs && pLay->IsCellFrm() )
589 : {
590 2130 : SwTabFrm* pTabFrm( pLay->FindTabFrm() );
591 5094 : if ( pTabFrm &&
592 3426 : ( pTabFrm->IsJoinLocked() ||
593 1296 : ( pTabFrm->IsFollow() &&
594 0 : pTabFrm->FindMaster()->IsJoinLocked() ) ) )
595 : {
596 834 : bUnlockPosOfObjs = false;
597 : }
598 : }
599 : // #i49383# - check for footnote frame, if unlock
600 : // of position of lower objects is allowed.
601 2796 : else if ( bUnlockPosOfObjs && pLay->IsFtnFrm() )
602 : {
603 94 : bUnlockPosOfObjs = static_cast<SwFtnFrm*>(pLay)->IsUnlockPosOfLowerObjs();
604 : }
605 : // #i51303# - no unlock of object positions for sections
606 2702 : else if ( bUnlockPosOfObjs && pLay->IsSctFrm() )
607 : {
608 104 : bUnlockPosOfObjs = false;
609 : }
610 4926 : pLay->NotifyLowerObjs( bUnlockPosOfObjs );
611 : }
612 11561 : if ( bPos && pLay->IsFtnFrm() && pLay->Lower() )
613 : {
614 : // OD 2004-05-11 #i28701#
615 94 : ::lcl_InvalidatePosOfLowers( *pLay );
616 : }
617 17147 : if( ( bPos || bSize ) && pLay->IsFlyFrm() && ((SwFlyFrm*)pLay)->GetAnchorFrm()
618 12303 : && ((SwFlyFrm*)pLay)->GetAnchorFrm()->IsFlyFrm() )
619 0 : ((SwFlyFrm*)pLay)->AnchorFrm()->InvalidateSize();
620 11561 : }
621 :
622 : /*************************************************************************/
623 :
624 1374 : SwFlyNotify::SwFlyNotify( SwFlyFrm *pFlyFrm ) :
625 : SwLayNotify( pFlyFrm ),
626 : // #115759# - keep correct page frame - the page frame
627 : // the Writer fly frame is currently registered at.
628 1374 : pOldPage( pFlyFrm->GetPageFrm() ),
629 2748 : aFrmAndSpace( pFlyFrm->GetObjRectWithSpaces() )
630 : {
631 1374 : }
632 :
633 : /*************************************************************************/
634 :
635 2748 : SwFlyNotify::~SwFlyNotify()
636 : {
637 : // #i49383#
638 1374 : if ( mbFrmDeleted )
639 : {
640 0 : return;
641 : }
642 :
643 1374 : SwFlyFrm *pFly = GetFly();
644 1374 : if ( pFly->IsNotifyBack() )
645 : {
646 674 : ViewShell *pSh = pFly->getRootFrm()->GetCurrShell();
647 674 : SwViewImp *pImp = pSh ? pSh->Imp() : 0;
648 674 : if ( !pImp || !pImp->IsAction() || !pImp->GetLayAction().IsAgain() )
649 : {
650 : //If in the LayAction the IsAgain is set it can be
651 : //that the old page is destroyed in the meantime!
652 674 : ::Notify( pFly, pOldPage, aFrmAndSpace, &aPrt );
653 : // #i35640# - additional notify anchor text frame,
654 : // if Writer fly frame has changed its page
655 1281 : if ( pFly->GetAnchorFrm()->IsTxtFrm() &&
656 607 : pFly->GetPageFrm() != pOldPage )
657 : {
658 0 : pFly->AnchorFrm()->Prepare( PREP_FLY_LEAVE );
659 : }
660 : }
661 674 : pFly->ResetNotifyBack();
662 : }
663 :
664 : //Have the size or the positon changed,
665 : //so should the view know this.
666 1374 : SWRECTFN( pFly )
667 1374 : const bool bPosChgd = POS_DIFF( aFrm, pFly->Frm() );
668 1374 : const bool bFrmChgd = pFly->Frm().SSize() != aFrm.SSize();
669 1374 : const bool bPrtChgd = aPrt != pFly->Prt();
670 1374 : if ( bPosChgd || bFrmChgd || bPrtChgd )
671 : {
672 745 : pFly->NotifyDrawObj();
673 : }
674 1374 : if ( bPosChgd && aFrm.Pos().X() != FAR_AWAY )
675 : {
676 : // OD 2004-05-10 #i28701# - no direct move of lower Writer fly frames.
677 : // reason: New positioning and alignment (e.g. to-paragraph anchored,
678 : // but aligned at page) are introduced.
679 : // <SwLayNotify::~SwLayNotify()> takes care of invalidation of lower
680 : // floating screen objects by calling method <SwLayoutFrm::NotifyLowerObjs()>.
681 :
682 286 : if ( pFly->IsFlyAtCntFrm() )
683 : {
684 10 : SwFrm *pNxt = pFly->AnchorFrm()->FindNext();
685 10 : if ( pNxt )
686 : {
687 6 : pNxt->InvalidatePos();
688 : }
689 : }
690 :
691 : // #i26945# - notify anchor.
692 : // Needed for negative positioned Writer fly frames
693 286 : if ( pFly->GetAnchorFrm()->IsTxtFrm() )
694 : {
695 284 : pFly->AnchorFrm()->Prepare( PREP_FLY_LEAVE );
696 : }
697 : }
698 :
699 : // OD 2004-05-13 #i28701#
700 : // #i45180# - no adjustment of layout process flags and
701 : // further notifications/invalidations, if format is called by grow/shrink
702 1473 : if ( pFly->ConsiderObjWrapInfluenceOnObjPos() &&
703 112 : ( !pFly->ISA(SwFlyFreeFrm) ||
704 56 : !static_cast<SwFlyFreeFrm*>(pFly)->IsNoMoveOnCheckClip() ) )
705 : {
706 : // #i54138# - suppress restart of the layout process
707 : // on changed frame height.
708 : // Note: It doesn't seem to be necessary and can cause layout loops.
709 43 : if ( bPosChgd )
710 : {
711 : // indicate a restart of the layout process
712 20 : pFly->SetRestartLayoutProcess( true );
713 : }
714 : else
715 : {
716 : // lock position
717 23 : pFly->LockPosition();
718 :
719 23 : if ( !pFly->ConsiderForTextWrap() )
720 : {
721 : // indicate that object has to be considered for text wrap
722 22 : pFly->SetConsiderForTextWrap( true );
723 : // invalidate 'background' in order to allow its 'background'
724 : // to wrap around it.
725 : pFly->NotifyBackground( pFly->GetPageFrm(),
726 22 : pFly->GetObjRectWithSpaces(),
727 44 : PREP_FLY_ARRIVE );
728 : // invalidate position of anchor frame in order to force
729 : // a re-format of the anchor frame, which also causes a
730 : // re-format of the invalid previous frames of the anchor frame.
731 22 : pFly->AnchorFrm()->InvalidatePos();
732 : }
733 : }
734 : }
735 1374 : }
736 :
737 : /*************************************************************************/
738 :
739 12635 : SwCntntNotify::SwCntntNotify( SwCntntFrm *pCntntFrm ) :
740 : SwFrmNotify( pCntntFrm ),
741 : // OD 08.01.2004 #i11859#
742 : mbChkHeightOfLastLine( false ),
743 : mnHeightOfLastLine( 0L ),
744 : // OD 2004-02-26 #i25029#
745 : mbInvalidatePrevPrtArea( false ),
746 12635 : mbBordersJoinedWithPrev( false )
747 : {
748 : // OD 08.01.2004 #i11859#
749 12635 : if ( pCntntFrm->IsTxtFrm() )
750 : {
751 12243 : SwTxtFrm* pTxtFrm = static_cast<SwTxtFrm*>(pCntntFrm);
752 12243 : if ( !pTxtFrm->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::OLD_LINE_SPACING) )
753 : {
754 12230 : const SwAttrSet* pSet = pTxtFrm->GetAttrSet();
755 12230 : const SvxLineSpacingItem &rSpace = pSet->GetLineSpacing();
756 12230 : if ( rSpace.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_PROP )
757 : {
758 657 : mbChkHeightOfLastLine = true;
759 657 : mnHeightOfLastLine = pTxtFrm->GetHeightOfLastLine();
760 : }
761 : }
762 : }
763 12635 : }
764 :
765 : /*************************************************************************/
766 :
767 25270 : SwCntntNotify::~SwCntntNotify()
768 : {
769 : // #i49383#
770 12635 : if ( mbFrmDeleted )
771 : {
772 0 : return;
773 : }
774 :
775 12635 : SwCntntFrm *pCnt = GetCnt();
776 12635 : if ( bSetCompletePaintOnInvalidate )
777 105 : pCnt->SetCompletePaint();
778 :
779 12635 : SWRECTFN( pCnt )
780 14647 : if ( pCnt->IsInTab() && ( POS_DIFF( pCnt->Frm(), aFrm ) ||
781 2012 : pCnt->Frm().SSize() != aFrm.SSize()))
782 : {
783 2092 : SwLayoutFrm* pCell = pCnt->GetUpper();
784 4186 : while( !pCell->IsCellFrm() && pCell->GetUpper() )
785 2 : pCell = pCell->GetUpper();
786 : OSL_ENSURE( pCell->IsCellFrm(), "Where's my cell?" );
787 2092 : if ( text::VertOrientation::NONE != pCell->GetFmt()->GetVertOrient().GetVertOrient() )
788 785 : pCell->InvalidatePrt(); //for the vertical allign.
789 : }
790 :
791 : // OD 2004-02-26 #i25029#
792 12704 : if ( mbInvalidatePrevPrtArea && mbBordersJoinedWithPrev &&
793 26 : pCnt->IsTxtFrm() &&
794 12661 : !pCnt->IsFollow() && !pCnt->GetIndPrev() )
795 : {
796 : // determine previous frame
797 13 : SwFrm* pPrevFrm = pCnt->FindPrev();
798 : // skip empty section frames and hidden text frames
799 : {
800 38 : while ( pPrevFrm &&
801 12 : ( ( pPrevFrm->IsSctFrm() &&
802 12 : !static_cast<SwSectionFrm*>(pPrevFrm)->GetSection() ) ||
803 24 : ( pPrevFrm->IsTxtFrm() &&
804 12 : static_cast<SwTxtFrm*>(pPrevFrm)->IsHiddenNow() ) ) )
805 : {
806 0 : pPrevFrm = pPrevFrm->FindPrev();
807 : }
808 : }
809 :
810 : // Invalidate printing area of found previous frame
811 13 : if ( pPrevFrm )
812 : {
813 12 : if ( pPrevFrm->IsSctFrm() )
814 : {
815 0 : if ( pCnt->IsInSct() )
816 : {
817 : // Note: found previous frame is a section frame and
818 : // <pCnt> is also inside a section.
819 : // Thus due to <mbBordersJoinedWithPrev>,
820 : // <pCnt> had joined its borders/shadow with the
821 : // last content of the found section.
822 : // Invalidate printing area of last content in found section.
823 : SwFrm* pLstCntntOfSctFrm =
824 0 : static_cast<SwSectionFrm*>(pPrevFrm)->FindLastCntnt();
825 0 : if ( pLstCntntOfSctFrm )
826 : {
827 0 : pLstCntntOfSctFrm->InvalidatePrt();
828 : }
829 : }
830 : }
831 : else
832 : {
833 12 : pPrevFrm->InvalidatePrt();
834 : }
835 : }
836 : }
837 :
838 12635 : const bool bFirst = (aFrm.*fnRect->fnGetWidth)() == 0;
839 :
840 12635 : if ( pCnt->IsNoTxtFrm() )
841 : {
842 : //Active PlugIn's or OLE-Objects should know something of the change
843 : //thereby they move their window appropriate.
844 392 : ViewShell *pSh = pCnt->getRootFrm()->GetCurrShell();
845 392 : if ( pSh )
846 : {
847 : SwOLENode *pNd;
848 1036 : if ( 0 != (pNd = pCnt->GetNode()->GetOLENode()) &&
849 322 : (pNd->GetOLEObj().IsOleRef() ||
850 0 : pNd->IsOLESizeInvalid()) )
851 : {
852 : const bool bNoTxtFrmPrtAreaChanged =
853 481 : ( aPrt.SSize().Width() != 0 &&
854 481 : aPrt.SSize().Height() != 0 ) &&
855 481 : aPrt.SSize() != pCnt->Prt().SSize();
856 : OSL_ENSURE( pCnt->IsInFly(), "OLE not in FlyFrm" );
857 322 : SwFlyFrm *pFly = pCnt->FindFlyFrm();
858 322 : svt::EmbeddedObjectRef& xObj = pNd->GetOLEObj().GetObject();
859 322 : SwFEShell *pFESh = 0;
860 322 : ViewShell *pTmp = pSh;
861 322 : do
862 322 : { if ( pTmp->ISA( SwCrsrShell ) )
863 : {
864 322 : pFESh = (SwFEShell*)pTmp;
865 : // #108369#: Here used to be the condition if (!bFirst).
866 : // I think this should mean "do not call CalcAndSetScale"
867 : // if the frame is formatted for the first time.
868 : // Unfortunately this is not valid anymore since the
869 : // SwNoTxtFrm already gets a width during CalcLowerPreps.
870 : // Nevertheless, the indention of !bFirst seemed to be
871 : // to assure that the OLE objects have already been notified
872 : // if necessary before calling CalcAndSetScale.
873 : // So I replaced !bFirst by !IsOLESizeInvalid. There is
874 : // one additional problem specific to the word import:
875 : // The layout is calculated _before_ calling PrtOLENotify,
876 : // and the OLE objects are not invalidated during import.
877 : // Therefore I added the condition !IsUpdateExpFld,
878 : // have a look at the occurrence of CalcLayout in
879 : // uiview/view.cxx.
880 644 : if ( !pNd->IsOLESizeInvalid() &&
881 322 : !pSh->GetDoc()->IsUpdateExpFld() )
882 : pFESh->CalcAndSetScale( xObj,
883 322 : &pFly->Prt(), &pFly->Frm(),
884 644 : bNoTxtFrmPrtAreaChanged );
885 : }
886 322 : pTmp = (ViewShell*)pTmp->GetNext();
887 : } while ( pTmp != pSh );
888 :
889 322 : if ( pFESh && pNd->IsOLESizeInvalid() )
890 : {
891 0 : pNd->SetOLESizeInvalid( sal_False );
892 : //TODO/LATER: needs OnDocumentPrinterChanged
893 : //xObj->OnDocumentPrinterChanged( pNd->GetDoc()->getPrinter( false ) );
894 0 : pFESh->CalcAndSetScale( xObj );//Client erzeugen lassen.
895 : }
896 : }
897 : //dito animated graphics
898 392 : if ( Frm().HasArea() && ((SwNoTxtFrm*)pCnt)->HasAnimation() )
899 : {
900 0 : ((SwNoTxtFrm*)pCnt)->StopAnimation();
901 0 : pSh->InvalidateWindows( Frm() );
902 : }
903 : }
904 : }
905 :
906 12635 : if ( bFirst )
907 : {
908 3827 : pCnt->SetRetouche(); //fix(13870)
909 :
910 3827 : SwDoc *pDoc = pCnt->GetNode()->GetDoc();
911 8914 : if ( !pDoc->GetSpzFrmFmts()->empty() &&
912 3827 : pDoc->DoesContainAtPageObjWithContentAnchor() && !pDoc->IsNewDoc() )
913 : {
914 : // If certain import filters for foreign file format import
915 : // AT_PAGE anchored objects, the corresponding page number is
916 : // typically not known. In this case the content position is
917 : // stored at which the anchored object is found in the
918 : // imported document.
919 : // When this content is formatted it is the time at which
920 : // the page is known. Thus, this data can be corrected now.
921 :
922 0 : const SwPageFrm *pPage = 0;
923 0 : SwNodeIndex *pIdx = 0;
924 0 : SwFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
925 :
926 0 : for ( sal_uInt16 i = 0; i < pTbl->size(); ++i )
927 : {
928 0 : SwFrmFmt *pFmt = (*pTbl)[i];
929 0 : const SwFmtAnchor &rAnch = pFmt->GetAnchor();
930 0 : if ( FLY_AT_PAGE != rAnch.GetAnchorId() ||
931 0 : rAnch.GetCntntAnchor() == 0 )
932 : {
933 0 : continue;
934 : }
935 :
936 0 : if ( !pIdx )
937 : {
938 0 : pIdx = new SwNodeIndex( *pCnt->GetNode() );
939 : }
940 0 : if ( rAnch.GetCntntAnchor()->nNode == *pIdx )
941 : {
942 : OSL_FAIL( "<SwCntntNotify::~SwCntntNotify()> - to page anchored object with content position. Please inform OD." );
943 0 : if ( !pPage )
944 : {
945 0 : pPage = pCnt->FindPageFrm();
946 : }
947 0 : SwFmtAnchor aAnch( rAnch );
948 0 : aAnch.SetAnchor( 0 );
949 0 : aAnch.SetPageNum( pPage->GetPhyPageNum() );
950 0 : pFmt->SetFmtAttr( aAnch );
951 0 : if ( RES_DRAWFRMFMT != pFmt->Which() )
952 : {
953 0 : pFmt->MakeFrms();
954 0 : }
955 : }
956 : }
957 0 : delete pIdx;
958 : }
959 : }
960 :
961 : // OD 12.01.2004 #i11859# - invalidate printing area of following frame,
962 : // if height of last line has changed.
963 12635 : if ( pCnt->IsTxtFrm() && mbChkHeightOfLastLine )
964 : {
965 657 : if ( mnHeightOfLastLine != static_cast<SwTxtFrm*>(pCnt)->GetHeightOfLastLine() )
966 : {
967 437 : pCnt->InvalidateNextPrtArea();
968 : }
969 : }
970 :
971 : // #i44049#
972 12635 : if ( pCnt->IsTxtFrm() && POS_DIFF( aFrm, pCnt->Frm() ) )
973 : {
974 5087 : pCnt->InvalidateObjs( true );
975 : }
976 :
977 : // #i43255# - move code to invalidate at-character
978 : // anchored objects due to a change of its anchor character from
979 : // method <SwTxtFrm::Format(..)>.
980 12635 : if ( pCnt->IsTxtFrm() )
981 : {
982 12243 : SwTxtFrm* pMasterFrm = pCnt->IsFollow()
983 849 : ? static_cast<SwTxtFrm*>(pCnt)->FindMaster()
984 13092 : : static_cast<SwTxtFrm*>(pCnt);
985 24486 : if ( pMasterFrm && !pMasterFrm->IsFlyLock() &&
986 12243 : pMasterFrm->GetDrawObjs() )
987 : {
988 767 : SwSortedObjs* pObjs = pMasterFrm->GetDrawObjs();
989 1794 : for ( sal_uInt32 i = 0; i < pObjs->Count(); ++i )
990 : {
991 1027 : SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
992 1027 : if ( pAnchoredObj->GetFrmFmt().GetAnchor().GetAnchorId()
993 : == FLY_AT_CHAR )
994 : {
995 206 : pAnchoredObj->CheckCharRectAndTopOfLine( !pMasterFrm->IsEmpty() );
996 : }
997 : }
998 : }
999 : }
1000 12635 : }
1001 :
1002 : /*************************************************************************/
1003 :
1004 1349 : void AppendObjs( const SwFrmFmts *pTbl, sal_uLong nIndex,
1005 : SwFrm *pFrm, SwPageFrm *pPage )
1006 : {
1007 7293 : for ( sal_uInt16 i = 0; i < pTbl->size(); ++i )
1008 : {
1009 5944 : SwFrmFmt *pFmt = (SwFrmFmt*)(*pTbl)[i];
1010 5944 : const SwFmtAnchor &rAnch = pFmt->GetAnchor();
1011 11680 : if ( rAnch.GetCntntAnchor() &&
1012 5736 : (rAnch.GetCntntAnchor()->nNode.GetIndex() == nIndex) )
1013 : {
1014 86 : const bool bFlyAtFly = rAnch.GetAnchorId() == FLY_AT_FLY; // LAYER_IMPL
1015 : //Is a frame or a SdrObject described?
1016 86 : const bool bSdrObj = RES_DRAWFRMFMT == pFmt->Which();
1017 : // OD 23.06.2003 #108784# - append also drawing objects anchored
1018 : // as character.
1019 134 : const bool bDrawObjInCntnt = bSdrObj &&
1020 134 : (rAnch.GetAnchorId() == FLY_AS_CHAR);
1021 :
1022 172 : if( bFlyAtFly ||
1023 144 : (rAnch.GetAnchorId() == FLY_AT_PARA) ||
1024 163 : (rAnch.GetAnchorId() == FLY_AT_CHAR) ||
1025 : bDrawObjInCntnt )
1026 : {
1027 78 : SdrObject* pSdrObj = 0;
1028 78 : if ( bSdrObj && 0 == (pSdrObj = pFmt->FindSdrObject()) )
1029 : {
1030 : OSL_ENSURE( !bSdrObj, "DrawObject not found." );
1031 0 : pFmt->GetDoc()->DelFrmFmt( pFmt );
1032 0 : --i;
1033 0 : continue;
1034 : }
1035 78 : if ( pSdrObj )
1036 : {
1037 48 : if ( !pSdrObj->GetPage() )
1038 : {
1039 0 : pFmt->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)->
1040 0 : InsertObject(pSdrObj, pSdrObj->GetOrdNumDirect());
1041 : }
1042 :
1043 : SwDrawContact* pNew =
1044 48 : static_cast<SwDrawContact*>(GetUserCall( pSdrObj ));
1045 48 : if ( !pNew->GetAnchorFrm() )
1046 : {
1047 48 : pFrm->AppendDrawObj( *(pNew->GetAnchoredObj( 0L )) );
1048 : }
1049 : // OD 19.06.2003 #108784# - add 'virtual' drawing object,
1050 : // if necessary. But control objects have to be excluded.
1051 0 : else if ( !::CheckControlLayer( pSdrObj ) &&
1052 0 : pNew->GetAnchorFrm() != pFrm &&
1053 0 : !pNew->GetDrawObjectByAnchorFrm( *pFrm ) )
1054 : {
1055 0 : SwDrawVirtObj* pDrawVirtObj = pNew->AddVirtObj();
1056 0 : pFrm->AppendDrawObj( *(pNew->GetAnchoredObj( pDrawVirtObj )) );
1057 :
1058 : // for repaint, use new ActionChanged()
1059 : // pDrawVirtObj->SendRepaintBroadcast();
1060 0 : pDrawVirtObj->ActionChanged();
1061 : }
1062 :
1063 : }
1064 : else
1065 : {
1066 : SwFlyFrm *pFly;
1067 30 : if( bFlyAtFly )
1068 0 : pFly = new SwFlyLayFrm( (SwFlyFrmFmt*)pFmt, pFrm, pFrm );
1069 : else
1070 30 : pFly = new SwFlyAtCntFrm( (SwFlyFrmFmt*)pFmt, pFrm, pFrm );
1071 30 : pFly->Lock();
1072 30 : pFrm->AppendFly( pFly );
1073 30 : pFly->Unlock();
1074 30 : if ( pPage )
1075 26 : ::RegistFlys( pPage, pFly );
1076 : }
1077 : }
1078 : }
1079 : }
1080 1349 : }
1081 :
1082 221 : static bool lcl_ObjConnected( SwFrmFmt *pFmt, const SwFrm* pSib )
1083 : {
1084 221 : SwIterator<SwFlyFrm,SwFmt> aIter( *pFmt );
1085 221 : if ( RES_FLYFRMFMT == pFmt->Which() )
1086 : {
1087 164 : const SwRootFrm* pRoot = pSib ? pSib->getRootFrm() : 0;
1088 : const SwFlyFrm* pTmpFrm;
1089 164 : for( pTmpFrm = aIter.First(); pTmpFrm; pTmpFrm = aIter.Next() )
1090 : {
1091 100 : if(! pRoot || pRoot == pTmpFrm->getRootFrm() )
1092 100 : return true;
1093 : }
1094 : }
1095 : else
1096 : {
1097 57 : SwDrawContact *pContact = SwIterator<SwDrawContact,SwFmt>::FirstElement(*pFmt);
1098 57 : if ( pContact )
1099 57 : return pContact->GetAnchorFrm() != 0;
1100 : }
1101 64 : return false;
1102 : }
1103 :
1104 : /** helper method to determine, if a <SwFrmFmt>, which has an object connected,
1105 : is located in header or footer.
1106 :
1107 : OD 23.06.2003 #108784#
1108 :
1109 : @author OD
1110 : */
1111 69 : static bool lcl_InHeaderOrFooter( SwFrmFmt& _rFmt )
1112 : {
1113 69 : bool bRetVal = false;
1114 :
1115 69 : const SwFmtAnchor& rAnch = _rFmt.GetAnchor();
1116 :
1117 69 : if (rAnch.GetAnchorId() != FLY_AT_PAGE)
1118 : {
1119 69 : bRetVal = _rFmt.GetDoc()->IsInHeaderFooter( rAnch.GetCntntAnchor()->nNode );
1120 : }
1121 :
1122 69 : return bRetVal;
1123 : }
1124 :
1125 795 : void AppendAllObjs( const SwFrmFmts *pTbl, const SwFrm* pSib )
1126 : {
1127 : //Connecting of all Objects, which are described in the SpzTbl with the
1128 : //layout.
1129 : //If nothing happens anymore we can stop. Then formats can still remain,
1130 : //because we neither use character bound frames nor objects which
1131 : //are anchored to character bounds.
1132 :
1133 795 : SwFrmFmts aCpy( *pTbl );
1134 :
1135 795 : sal_uInt16 nOldCnt = USHRT_MAX;
1136 :
1137 1773 : while ( !aCpy.empty() && aCpy.size() != nOldCnt )
1138 : {
1139 183 : nOldCnt = aCpy.size();
1140 540 : for ( int i = 0; i < int(aCpy.size()); ++i )
1141 : {
1142 357 : SwFrmFmt *pFmt = (SwFrmFmt*)aCpy[ sal_uInt16(i) ];
1143 357 : const SwFmtAnchor &rAnch = pFmt->GetAnchor();
1144 357 : sal_Bool bRemove = sal_False;
1145 690 : if ((rAnch.GetAnchorId() == FLY_AT_PAGE) ||
1146 333 : (rAnch.GetAnchorId() == FLY_AS_CHAR))
1147 : {
1148 : //Page bounded are already anchored, character bounded
1149 : //I don't want here.
1150 216 : bRemove = sal_True;
1151 : }
1152 210 : else if ( sal_False == (bRemove = ::lcl_ObjConnected( pFmt, pSib )) ||
1153 69 : ::lcl_InHeaderOrFooter( *pFmt ) )
1154 : {
1155 : // OD 23.06.2003 #108784# - correction: for objects in header
1156 : // or footer create frames, in spite of the fact that an connected
1157 : // objects already exists.
1158 : //Call for Flys and DrawObjs only a MakeFrms if nor
1159 : //no dependent exists, otherwise, or if the MakeDrms creates no
1160 : //dependents, remove.
1161 80 : pFmt->MakeFrms();
1162 80 : bRemove = ::lcl_ObjConnected( pFmt, pSib );
1163 : }
1164 357 : if ( bRemove )
1165 : {
1166 357 : aCpy.erase( aCpy.begin() + i );
1167 357 : --i;
1168 : }
1169 : }
1170 : }
1171 795 : aCpy.clear();
1172 795 : }
1173 :
1174 : /** local method to set 'working' position for newly inserted frames
1175 :
1176 : OD 12.08.2003 #i17969#
1177 :
1178 : @author OD
1179 : */
1180 4292 : static void lcl_SetPos( SwFrm& _rNewFrm,
1181 : const SwLayoutFrm& _rLayFrm )
1182 : {
1183 4292 : SWRECTFN( (&_rLayFrm) )
1184 4292 : (_rNewFrm.Frm().*fnRect->fnSetPos)( (_rLayFrm.Frm().*fnRect->fnGetPos)() );
1185 : // move position by one SwTwip in text flow direction in order to get
1186 : // notifications for a new calculated position after its formatting.
1187 4292 : if ( bVert )
1188 1 : _rNewFrm.Frm().Pos().X() -= 1;
1189 : else
1190 4291 : _rNewFrm.Frm().Pos().Y() += 1;
1191 4292 : }
1192 :
1193 2990 : void _InsertCnt( SwLayoutFrm *pLay, SwDoc *pDoc,
1194 : sal_uLong nIndex, sal_Bool bPages, sal_uLong nEndIndex,
1195 : SwFrm *pPrv )
1196 : {
1197 2990 : pDoc->BlockIdling();
1198 2990 : SwRootFrm* pLayout = pLay->getRootFrm();
1199 2990 : const sal_Bool bOldCallbackActionEnabled = pLayout ? pLayout->IsCallbackActionEnabled() : sal_False;
1200 2990 : if( bOldCallbackActionEnabled )
1201 816 : pLayout->SetCallbackActionEnabled( sal_False );
1202 :
1203 : //In the generation of the Layout will be bPage with sal_True handed over.
1204 : //Then will be new pages generated all x paragraphs already times in advance.
1205 : //On breaks and/or pagedescriptorchanges the correspondig will be generated
1206 : //immediately.
1207 : //The advantage is, that on one hand already a nearly realistic number of
1208 : //pages are created, but above all there are no almost endless long chain
1209 : //of paragraphs, which must be moved expensively until it reaches a tolarable
1210 : //reduced level.
1211 : //We'd like to think that 20 Paragraphs fit on one page.
1212 : //So that it does not become in extremly situations so violent we calculate depending
1213 : //on the node something to it.
1214 : //If in the DocStatistik a usable given pagenumber
1215 : //(Will be cared for while writing), so it will be presumed that this will be
1216 : //number of pages.
1217 2990 : const bool bStartPercent = bPages && !nEndIndex;
1218 :
1219 2990 : SwPageFrm *pPage = pLay->FindPageFrm();
1220 2990 : const SwFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
1221 2990 : SwFrm *pFrm = 0;
1222 2990 : sal_Bool bBreakAfter = sal_False;
1223 :
1224 2990 : SwActualSection *pActualSection = 0;
1225 : SwLayHelper *pPageMaker;
1226 :
1227 : //If the layout will be created (bPages == sal_True) we do head on the progress
1228 : //Flys and DrawObjekte are not connected immediately, this
1229 : //happens only at the end of the function.
1230 2990 : if ( bPages )
1231 : {
1232 : // Attention: the SwLayHelper class uses references to the content-,
1233 : // page-, layout-frame etc. and may change them!
1234 : pPageMaker = new SwLayHelper( pDoc, pFrm, pPrv, pPage, pLay,
1235 793 : pActualSection, bBreakAfter, nIndex, 0 == nEndIndex );
1236 793 : if( bStartPercent )
1237 : {
1238 793 : const sal_uLong nPageCount = pPageMaker->CalcPageCount();
1239 793 : if( nPageCount )
1240 183 : bObjsDirect = false;
1241 : }
1242 : }
1243 : else
1244 2197 : pPageMaker = NULL;
1245 :
1246 2996 : if( pLay->IsInSct() &&
1247 3 : ( pLay->IsSctFrm() || pLay->GetUpper() ) ) // Hereby will newbies
1248 : // be intercepted, of which flags could not determined yet,
1249 : // for e.g. while inserting a table
1250 : {
1251 3 : SwSectionFrm* pSct = pLay->FindSctFrm();
1252 : // If content will be inserted in a footnote, which in an column area,
1253 : // the column area it is not allowed to be broken up.
1254 : // Only if in the inner of the footnote lies an area, is this a candidate
1255 : // for pActualSection.
1256 : // The same applies for areas in tables, if inside the table will be
1257 : // something inserted, it's only allowed to break up areas, which
1258 : // lies in the inside also.
1259 9 : if( ( !pLay->IsInFtn() || pSct->IsInFtn() ) &&
1260 3 : ( !pLay->IsInTab() || pSct->IsInTab() ) )
1261 : {
1262 3 : pActualSection = new SwActualSection( 0, pSct, 0 );
1263 : OSL_ENSURE( !pLay->Lower() || !pLay->Lower()->IsColumnFrm(),
1264 : "_InsertCnt: Wrong Call" );
1265 : }
1266 : }
1267 :
1268 : //If a section is "open", the pActualSection points to an SwActualSection.
1269 : //If the page breaks, for "open" sections a follow will created.
1270 : //For nested sections (which have, however, not a nested layout),
1271 : //the SwActualSection class has a member, which points to an upper(section).
1272 : //When the "inner" section finishs, the upper will used instead.
1273 :
1274 : while( true )
1275 : {
1276 7634 : SwNode *pNd = pDoc->GetNodes()[nIndex];
1277 7634 : if ( pNd->IsCntntNode() )
1278 : {
1279 4073 : SwCntntNode* pNode = (SwCntntNode*)pNd;
1280 4073 : pFrm = pNode->MakeFrm(pLay);
1281 4073 : if( pPageMaker )
1282 1558 : pPageMaker->CheckInsert( nIndex );
1283 :
1284 4073 : pFrm->InsertBehind( pLay, pPrv );
1285 : // #i27138#
1286 : // notify accessibility paragraphs objects about changed
1287 : // CONTENT_FLOWS_FROM/_TO relation.
1288 : // Relation CONTENT_FLOWS_FROM for next paragraph will change
1289 : // and relation CONTENT_FLOWS_TO for previous paragraph will change.
1290 4073 : if ( pFrm->IsTxtFrm() )
1291 : {
1292 3873 : ViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
1293 : // no notification, if <ViewShell> is in construction
1294 8385 : if ( pViewShell && !pViewShell->IsInConstructor() &&
1295 5151 : pViewShell->GetLayout() &&
1296 639 : pViewShell->GetLayout()->IsAnyShellAccessible() )
1297 : {
1298 : pViewShell->InvalidateAccessibleParaFlowRelation(
1299 0 : dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
1300 0 : dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
1301 : // #i68958#
1302 : // The information flags of the text frame are validated
1303 : // in methods <FindNextCnt(..)> and <FindPrevCnt(..)>.
1304 : // The information flags have to be invalidated, because
1305 : // it is possible, that the one of its upper frames
1306 : // isn't inserted into the layout.
1307 0 : pFrm->InvalidateInfFlags();
1308 : }
1309 : }
1310 : // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
1311 : // for setting position at newly inserted frame
1312 4073 : lcl_SetPos( *pFrm, *pLay );
1313 4073 : pPrv = pFrm;
1314 :
1315 4073 : if ( !pTbl->empty() && bObjsDirect && !bDontCreateObjects )
1316 1085 : AppendObjs( pTbl, nIndex, pFrm, pPage );
1317 : }
1318 3561 : else if ( pNd->IsTableNode() )
1319 : { //Should we have encountered a table?
1320 113 : SwTableNode *pTblNode = (SwTableNode*)pNd;
1321 :
1322 : // #108116# loading may produce table structures that GCLines
1323 : // needs to clean up. To keep table formulas correct, change
1324 : // all table formulas to internal (BOXPTR) representation.
1325 113 : SwTableFmlUpdate aMsgHnt( &pTblNode->GetTable() );
1326 113 : aMsgHnt.eFlags = TBL_BOXPTR;
1327 113 : pDoc->UpdateTblFlds( &aMsgHnt );
1328 113 : pTblNode->GetTable().GCLines();
1329 :
1330 113 : pFrm = pTblNode->MakeFrm( pLay );
1331 :
1332 113 : if( pPageMaker )
1333 92 : pPageMaker->CheckInsert( nIndex );
1334 :
1335 113 : pFrm->InsertBehind( pLay, pPrv );
1336 : // #i27138#
1337 : // notify accessibility paragraphs objects about changed
1338 : // CONTENT_FLOWS_FROM/_TO relation.
1339 : // Relation CONTENT_FLOWS_FROM for next paragraph will change
1340 : // and relation CONTENT_FLOWS_TO for previous paragraph will change.
1341 : {
1342 113 : ViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
1343 : // no notification, if <ViewShell> is in construction
1344 226 : if ( pViewShell && !pViewShell->IsInConstructor() &&
1345 113 : pViewShell->GetLayout() &&
1346 0 : pViewShell->GetLayout()->IsAnyShellAccessible() )
1347 : {
1348 : pViewShell->InvalidateAccessibleParaFlowRelation(
1349 0 : dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
1350 0 : dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
1351 : }
1352 : }
1353 113 : if ( bObjsDirect && !pTbl->empty() )
1354 11 : ((SwTabFrm*)pFrm)->RegistFlys();
1355 : // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
1356 : // for setting position at newly inserted frame
1357 113 : lcl_SetPos( *pFrm, *pLay );
1358 :
1359 113 : pPrv = pFrm;
1360 : //Set the index to the endnode of the table section.
1361 113 : nIndex = pTblNode->EndOfSectionIndex();
1362 :
1363 113 : SwTabFrm* pTmpFrm = (SwTabFrm*)pFrm;
1364 351 : while ( pTmpFrm )
1365 : {
1366 125 : pTmpFrm->CheckDirChange();
1367 125 : pTmpFrm = pTmpFrm->IsFollow() ? pTmpFrm->FindMaster() : NULL;
1368 113 : }
1369 :
1370 : }
1371 3448 : else if ( pNd->IsSectionNode() )
1372 : {
1373 82 : SwSectionNode *pNode = (SwSectionNode*)pNd;
1374 82 : if( pNode->GetSection().CalcHiddenFlag() )
1375 : // is hidden, skip the area
1376 0 : nIndex = pNode->EndOfSectionIndex();
1377 : else
1378 : {
1379 82 : pFrm = pNode->MakeFrm( pLay );
1380 : pActualSection = new SwActualSection( pActualSection,
1381 82 : (SwSectionFrm*)pFrm, pNode );
1382 82 : if ( pActualSection->GetUpper() )
1383 : {
1384 : //Insert behind the Upper, the "Follow" of the Upper will be
1385 : //generated at the EndNode.
1386 24 : SwSectionFrm *pTmp = pActualSection->GetUpper()->GetSectionFrm();
1387 24 : pFrm->InsertBehind( pTmp->GetUpper(), pTmp );
1388 : // OD 25.03.2003 #108339# - direct initialization of section
1389 : // after insertion in the layout
1390 24 : static_cast<SwSectionFrm*>(pFrm)->Init();
1391 : }
1392 : else
1393 : {
1394 58 : pFrm->InsertBehind( pLay, pPrv );
1395 : // OD 25.03.2003 #108339# - direct initialization of section
1396 : // after insertion in the layout
1397 58 : static_cast<SwSectionFrm*>(pFrm)->Init();
1398 :
1399 : // #i33963#
1400 : // Do not trust the IsInFtn flag. If we are currently
1401 : // building up a table, the upper of pPrv may be a cell
1402 : // frame, but the cell frame does not have an upper yet.
1403 58 : if( pPrv && 0 != pPrv->ImplFindFtnFrm() )
1404 : {
1405 0 : if( pPrv->IsSctFrm() )
1406 0 : pPrv = ((SwSectionFrm*)pPrv)->ContainsCntnt();
1407 0 : if( pPrv && pPrv->IsTxtFrm() )
1408 0 : ((SwTxtFrm*)pPrv)->Prepare( PREP_QUOVADIS, 0, sal_False );
1409 : }
1410 : }
1411 : // #i27138#
1412 : // notify accessibility paragraphs objects about changed
1413 : // CONTENT_FLOWS_FROM/_TO relation.
1414 : // Relation CONTENT_FLOWS_FROM for next paragraph will change
1415 : // and relation CONTENT_FLOWS_TO for previous paragraph will change.
1416 : {
1417 82 : ViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
1418 : // no notification, if <ViewShell> is in construction
1419 205 : if ( pViewShell && !pViewShell->IsInConstructor() &&
1420 164 : pViewShell->GetLayout() &&
1421 41 : pViewShell->GetLayout()->IsAnyShellAccessible() )
1422 : {
1423 : pViewShell->InvalidateAccessibleParaFlowRelation(
1424 0 : dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
1425 0 : dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
1426 : }
1427 : }
1428 82 : pFrm->CheckDirChange();
1429 :
1430 : // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
1431 : // for setting position at newly inserted frame
1432 82 : lcl_SetPos( *pFrm, *pLay );
1433 :
1434 : // OD 20.11.2002 #105405# - no page, no invalidate.
1435 82 : if ( pPage )
1436 : {
1437 : // OD 18.09.2002 #100522#
1438 : // invalidate page in order to force format and paint of
1439 : // inserted section frame
1440 82 : pFrm->InvalidatePage( pPage );
1441 :
1442 : // FME 10.11.2003 #112243#
1443 : // Invalidate fly content flag:
1444 82 : if ( pFrm->IsInFly() )
1445 0 : pPage->InvalidateFlyCntnt();
1446 :
1447 : // OD 14.11.2002 #104684# - invalidate page content in order to
1448 : // force format and paint of section content.
1449 82 : pPage->InvalidateCntnt();
1450 : }
1451 :
1452 82 : pLay = (SwLayoutFrm*)pFrm;
1453 82 : if ( pLay->Lower() && pLay->Lower()->IsLayoutFrm() )
1454 5 : pLay = pLay->GetNextLayoutLeaf();
1455 82 : pPrv = 0;
1456 : }
1457 : }
1458 3366 : else if ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() )
1459 : {
1460 : OSL_ENSURE( pActualSection, "Sectionende ohne Anfang?" );
1461 : OSL_ENSURE( pActualSection->GetSectionNode() == pNd->StartOfSectionNode(),
1462 : "Sectionende mit falschen Start Node?" );
1463 :
1464 : //Close the section, where appropriate activate the surrounding
1465 : //section again.
1466 82 : SwActualSection *pTmp = pActualSection->GetUpper();
1467 82 : delete pActualSection;
1468 82 : pLay = pLay->FindSctFrm();
1469 82 : if ( 0 != (pActualSection = pTmp) )
1470 : {
1471 : //Could be, that the last SectionFrm remains empty.
1472 : //Then now is the time to remove them.
1473 24 : if ( !pLay->ContainsCntnt() )
1474 : {
1475 0 : SwFrm *pTmpFrm = pLay;
1476 0 : pLay = pTmpFrm->GetUpper();
1477 0 : pPrv = pTmpFrm->GetPrev();
1478 0 : pTmpFrm->Remove();
1479 0 : delete pTmpFrm;
1480 : }
1481 : else
1482 : {
1483 24 : pPrv = pLay;
1484 24 : pLay = pLay->GetUpper();
1485 : }
1486 :
1487 : // new section frame
1488 24 : pFrm = pActualSection->GetSectionNode()->MakeFrm( pLay );
1489 24 : pFrm->InsertBehind( pLay, pPrv );
1490 24 : static_cast<SwSectionFrm*>(pFrm)->Init();
1491 :
1492 : // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
1493 : // for setting position at newly inserted frame
1494 24 : lcl_SetPos( *pFrm, *pLay );
1495 :
1496 24 : SwSectionFrm* pOuterSectionFrm = pActualSection->GetSectionFrm();
1497 :
1498 : // a follow has to be appended to the new section frame
1499 24 : SwSectionFrm* pFollow = pOuterSectionFrm->GetFollow();
1500 24 : if ( pFollow )
1501 : {
1502 0 : pOuterSectionFrm->SetFollow( NULL );
1503 0 : pOuterSectionFrm->InvalidateSize();
1504 0 : ((SwSectionFrm*)pFrm)->SetFollow( pFollow );
1505 : }
1506 :
1507 : // We don't want to leave empty parts back.
1508 45 : if( ! pOuterSectionFrm->IsColLocked() &&
1509 21 : ! pOuterSectionFrm->ContainsCntnt() )
1510 : {
1511 21 : pOuterSectionFrm->DelEmpty( sal_True );
1512 21 : delete pOuterSectionFrm;
1513 : }
1514 24 : pActualSection->SetSectionFrm( (SwSectionFrm*)pFrm );
1515 :
1516 24 : pLay = (SwLayoutFrm*)pFrm;
1517 24 : if ( pLay->Lower() && pLay->Lower()->IsLayoutFrm() )
1518 0 : pLay = pLay->GetNextLayoutLeaf();
1519 24 : pPrv = 0;
1520 : }
1521 : else
1522 : {
1523 : //Nothing more with sections, it goes on right behind
1524 : //the SectionFrame.
1525 58 : pPrv = pLay;
1526 58 : pLay = pLay->GetUpper();
1527 : }
1528 : }
1529 3612 : else if( pNd->IsStartNode() &&
1530 328 : SwFlyStartNode == ((SwStartNode*)pNd)->GetStartNodeType() )
1531 : {
1532 328 : if ( !pTbl->empty() && bObjsDirect && !bDontCreateObjects )
1533 : {
1534 264 : SwFlyFrm* pFly = pLay->FindFlyFrm();
1535 264 : if( pFly )
1536 264 : AppendObjs( pTbl, nIndex, pFly, pPage );
1537 : }
1538 : }
1539 : else
1540 : // Neither Cntnt nor table nor section,
1541 : // so we have to be ready.
1542 2956 : break;
1543 :
1544 4678 : ++nIndex;
1545 : // Der Endnode wird nicht mehr mitgenommen, es muss vom
1546 : // Aufrufenden (Section/MakeFrms()) sichergestellt sein, dass das Ende
1547 : // des Bereichs vor dem EndIndex liegt!
1548 4678 : if ( nEndIndex && nIndex >= nEndIndex )
1549 34 : break;
1550 : }
1551 :
1552 2990 : if ( pActualSection )
1553 : {
1554 : //Kann passieren, dass noch eine leere (Follow-)Section uebrig geblieben ist.
1555 3 : if ( !(pLay = pActualSection->GetSectionFrm())->ContainsCntnt() )
1556 : {
1557 3 : pLay->Remove();
1558 3 : delete pLay;
1559 : }
1560 3 : delete pActualSection;
1561 : }
1562 :
1563 2990 : if ( bPages ) //Jetzt noch die Flys verbinden lassen.
1564 : {
1565 793 : if ( !bDontCreateObjects )
1566 793 : AppendAllObjs( pTbl, pLayout );
1567 793 : bObjsDirect = true;
1568 : }
1569 :
1570 2990 : if( pPageMaker )
1571 : {
1572 793 : pPageMaker->CheckFlyCache( pPage );
1573 793 : delete pPageMaker;
1574 793 : if( pDoc->GetLayoutCache() )
1575 : {
1576 : #ifdef DBG_UTIL
1577 : pDoc->GetLayoutCache()->CompareLayout( *pDoc );
1578 : #endif
1579 7 : pDoc->GetLayoutCache()->ClearImpl();
1580 : }
1581 : }
1582 :
1583 2990 : pDoc->UnblockIdling();
1584 2990 : if( bOldCallbackActionEnabled )
1585 5460 : pLayout->SetCallbackActionEnabled( bOldCallbackActionEnabled );
1586 2990 : }
1587 :
1588 :
1589 29 : void MakeFrms( SwDoc *pDoc, const SwNodeIndex &rSttIdx,
1590 : const SwNodeIndex &rEndIdx )
1591 : {
1592 29 : bObjsDirect = false;
1593 :
1594 29 : SwNodeIndex aTmp( rSttIdx );
1595 29 : sal_uLong nEndIdx = rEndIdx.GetIndex();
1596 29 : SwNode* pNd = pDoc->GetNodes().FindPrvNxtFrmNode( aTmp,
1597 58 : pDoc->GetNodes()[ nEndIdx-1 ]);
1598 29 : if ( pNd )
1599 : {
1600 27 : sal_Bool bApres = aTmp < rSttIdx;
1601 27 : SwNode2Layout aNode2Layout( *pNd, rSttIdx.GetIndex() );
1602 : SwFrm* pFrm;
1603 81 : while( 0 != (pFrm = aNode2Layout.NextFrm()) )
1604 : {
1605 27 : SwLayoutFrm *pUpper = pFrm->GetUpper();
1606 27 : SwFtnFrm* pFtnFrm = pUpper->FindFtnFrm();
1607 : sal_Bool bOldLock, bOldFtn;
1608 27 : if( pFtnFrm )
1609 : {
1610 2 : bOldFtn = pFtnFrm->IsColLocked();
1611 2 : pFtnFrm->ColLock();
1612 : }
1613 : else
1614 25 : bOldFtn = sal_True;
1615 27 : SwSectionFrm* pSct = pUpper->FindSctFrm();
1616 : // Es sind innerhalb von Fussnoten nur die Bereiche interessant,
1617 : // die in den Fussnoten liegen, nicht etwa die (spaltigen) Bereiche,
1618 : // in denen die Fussnoten(Container) liegen.
1619 : // #109767# Table frame is in section, insert section in cell frame.
1620 27 : if( pSct && ((pFtnFrm && !pSct->IsInFtn()) || pUpper->IsCellFrm()) )
1621 0 : pSct = NULL;
1622 27 : if( pSct )
1623 : { // damit der SectionFrm nicht zerstoert wird durch pTmp->MoveFwd()
1624 3 : bOldLock = pSct->IsColLocked();
1625 3 : pSct->ColLock();
1626 : }
1627 : else
1628 24 : bOldLock = sal_True;
1629 :
1630 : // Wenn pFrm sich nicht bewegen kann, koennen wir auch niemanden
1631 : // auf die naechste Seite schieben. Innerhalb eines Rahmens auch
1632 : // nicht ( in der 1. Spalte eines Rahmens waere pFrm Moveable()! )
1633 : // Auch in spaltigen Bereichen in Tabellen waere pFrm Moveable.
1634 27 : bool bMoveNext = nEndIdx - rSttIdx.GetIndex() > 120;
1635 77 : bool bAllowMove = !pFrm->IsInFly() && pFrm->IsMoveable() &&
1636 52 : (!pFrm->IsInTab() || pFrm->IsTabFrm() );
1637 27 : if ( bMoveNext && bAllowMove )
1638 : {
1639 0 : SwFrm *pMove = pFrm;
1640 0 : SwFrm *pPrev = pFrm->GetPrev();
1641 0 : SwFlowFrm *pTmp = SwFlowFrm::CastFlowFrm( pMove );
1642 : OSL_ENSURE( pTmp, "Missing FlowFrm" );
1643 :
1644 0 : if ( bApres )
1645 : {
1646 : // Wir wollen, dass der Rest der Seite leer ist, d.h.
1647 : // der naechste muss auf die naechste Seite wandern.
1648 : // Dieser kann auch in der naechsten Spalte stehen!
1649 : OSL_ENSURE( !pTmp->HasFollow(), "Follows forbidden" );
1650 0 : pPrev = pFrm;
1651 : // Wenn unser umgebender SectionFrm einen Next besitzt,
1652 : // so soll dieser ebenfalls gemoved werden!
1653 0 : pMove = pFrm->GetIndNext();
1654 0 : SwColumnFrm* pCol = (SwColumnFrm*)pFrm->FindColFrm();
1655 0 : if( pCol )
1656 0 : pCol = (SwColumnFrm*)pCol->GetNext();
1657 0 : do
1658 : {
1659 0 : if( pCol && !pMove )
1660 : { // Bisher haben wir keinen Nachfolger gefunden
1661 : // jetzt gucken wir in die naechste Spalte
1662 0 : pMove = pCol->ContainsAny();
1663 0 : if( pCol->GetNext() )
1664 0 : pCol = (SwColumnFrm*)pCol->GetNext();
1665 0 : else if( pCol->IsInSct() )
1666 : { // Wenn es keine naechste Spalte gibt, wir aber
1667 : // innerhalb eines spaltigen Bereichs sind,
1668 : // koennte es noch ausserhalb des Bereich
1669 : // (Seiten-)Spalten geben
1670 0 : pCol = (SwColumnFrm*)pCol->FindSctFrm()->FindColFrm();
1671 0 : if( pCol )
1672 0 : pCol = (SwColumnFrm*)pCol->GetNext();
1673 : }
1674 : else
1675 0 : pCol = NULL;
1676 : }
1677 : // Falls hier verschrottete SectionFrms herumgammeln,
1678 : // muessen diese uebersprungen werden.
1679 0 : while( pMove && pMove->IsSctFrm() &&
1680 0 : !((SwSectionFrm*)pMove)->GetSection() )
1681 0 : pMove = pMove->GetNext();
1682 0 : } while( !pMove && pCol );
1683 :
1684 0 : if( pMove )
1685 : {
1686 0 : if ( pMove->IsCntntFrm() )
1687 0 : pTmp = (SwCntntFrm*)pMove;
1688 0 : else if ( pMove->IsTabFrm() )
1689 0 : pTmp = (SwTabFrm*)pMove;
1690 0 : else if ( pMove->IsSctFrm() )
1691 : {
1692 0 : pMove = ((SwSectionFrm*)pMove)->ContainsAny();
1693 0 : if( pMove )
1694 0 : pTmp = SwFlowFrm::CastFlowFrm( pMove );
1695 : else
1696 0 : pTmp = NULL;
1697 : }
1698 : }
1699 : else
1700 0 : pTmp = 0;
1701 : }
1702 : else
1703 : {
1704 : OSL_ENSURE( !pTmp->IsFollow(), "Follows really forbidden" );
1705 : // Bei Bereichen muss natuerlich der Inhalt auf die Reise
1706 : // geschickt werden.
1707 0 : if( pMove->IsSctFrm() )
1708 : {
1709 0 : while( pMove && pMove->IsSctFrm() &&
1710 0 : !((SwSectionFrm*)pMove)->GetSection() )
1711 0 : pMove = pMove->GetNext();
1712 0 : if( pMove && pMove->IsSctFrm() )
1713 0 : pMove = ((SwSectionFrm*)pMove)->ContainsAny();
1714 0 : if( pMove )
1715 0 : pTmp = SwFlowFrm::CastFlowFrm( pMove );
1716 : else
1717 0 : pTmp = NULL;
1718 : }
1719 : }
1720 :
1721 0 : if( pTmp )
1722 : {
1723 0 : SwFrm* pOldUp = pTmp->GetFrm()->GetUpper();
1724 : // MoveFwd==sal_True bedeutet, dass wir auf der gleichen
1725 : // Seite geblieben sind, wir wollen aber die Seite wechseln,
1726 : // sofern dies moeglich ist
1727 0 : sal_Bool bTmpOldLock = pTmp->IsJoinLocked();
1728 0 : pTmp->LockJoin();
1729 0 : while( pTmp->MoveFwd( sal_True, sal_False, sal_True ) )
1730 : {
1731 0 : if( pOldUp == pTmp->GetFrm()->GetUpper() )
1732 0 : break;
1733 0 : pOldUp = pTmp->GetFrm()->GetUpper();
1734 : }
1735 0 : if( !bTmpOldLock )
1736 0 : pTmp->UnlockJoin();
1737 : }
1738 : ::_InsertCnt( pUpper, pDoc, rSttIdx.GetIndex(),
1739 0 : pFrm->IsInDocBody(), nEndIdx, pPrev );
1740 : }
1741 : else
1742 : {
1743 : sal_Bool bSplit;
1744 27 : SwFrm* pPrv = bApres ? pFrm : pFrm->GetPrev();
1745 : // Wenn in einen SectionFrm ein anderer eingefuegt wird,
1746 : // muss dieser aufgebrochen werden
1747 27 : if( pSct && rSttIdx.GetNode().IsSectionNode() )
1748 : {
1749 3 : bSplit = pSct->SplitSect( pFrm, bApres );
1750 : // Wenn pSct nicht aufgespalten werden konnte
1751 3 : if( !bSplit && !bApres )
1752 : {
1753 0 : pUpper = pSct->GetUpper();
1754 0 : pPrv = pSct->GetPrev();
1755 : }
1756 : }
1757 : else
1758 24 : bSplit = sal_False;
1759 : ::_InsertCnt( pUpper, pDoc, rSttIdx.GetIndex(), sal_False,
1760 27 : nEndIdx, pPrv );
1761 : // OD 23.06.2003 #108784# - correction: append objects doesn't
1762 : // depend on value of <bAllowMove>
1763 27 : if( !bDontCreateObjects )
1764 : {
1765 27 : const SwFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
1766 27 : if( !pTbl->empty() )
1767 2 : AppendAllObjs( pTbl, pUpper );
1768 : }
1769 :
1770 : // Wenn nichts eingefuegt wurde, z.B. ein ausgeblendeter Bereich,
1771 : // muss das Splitten rueckgaengig gemacht werden
1772 30 : if( bSplit && pSct && pSct->GetNext()
1773 30 : && pSct->GetNext()->IsSctFrm() )
1774 3 : pSct->MergeNext( (SwSectionFrm*)pSct->GetNext() );
1775 27 : if( pFrm->IsInFly() )
1776 0 : pFrm->FindFlyFrm()->_Invalidate();
1777 27 : if( pFrm->IsInTab() )
1778 2 : pFrm->InvalidateSize();
1779 : }
1780 :
1781 27 : SwPageFrm *pPage = pUpper->FindPageFrm();
1782 27 : SwFrm::CheckPageDescs( pPage, sal_False );
1783 27 : if( !bOldFtn )
1784 2 : pFtnFrm->ColUnlock();
1785 27 : if( !bOldLock )
1786 : {
1787 3 : pSct->ColUnlock();
1788 : // Zum Beispiel beim Einfuegen von gelinkten Bereichen,
1789 : // die wiederum Bereiche enthalten, kann pSct jetzt leer sein
1790 : // und damit ruhig zerstoert werden.
1791 3 : if( !pSct->ContainsCntnt() )
1792 : {
1793 0 : pSct->DelEmpty( sal_True );
1794 0 : pUpper->getRootFrm()->RemoveFromList( pSct );
1795 0 : delete pSct;
1796 : }
1797 : }
1798 27 : }
1799 : }
1800 :
1801 29 : bObjsDirect = true;
1802 29 : }
1803 :
1804 :
1805 : /*************************************************************************/
1806 :
1807 9787 : SwBorderAttrs::SwBorderAttrs( const SwModify *pMod, const SwFrm *pConstructor ) :
1808 : SwCacheObj( pMod ),
1809 9787 : rAttrSet( pConstructor->IsCntntFrm()
1810 5808 : ? ((SwCntntFrm*)pConstructor)->GetNode()->GetSwAttrSet()
1811 3979 : : ((SwLayoutFrm*)pConstructor)->GetFmt()->GetAttrSet() ),
1812 9787 : rUL ( rAttrSet.GetULSpace() ),
1813 : // #i96772#
1814 : // LRSpaceItem is copied due to the possibility that it is adjusted - see below
1815 9787 : rLR ( rAttrSet.GetLRSpace() ),
1816 9787 : rBox ( rAttrSet.GetBox() ),
1817 9787 : rShadow ( rAttrSet.GetShadow() ),
1818 68509 : aFrmSize( rAttrSet.GetFrmSize().GetSize() )
1819 : {
1820 : // #i96772#
1821 9787 : const SwTxtFrm* pTxtFrm = dynamic_cast<const SwTxtFrm*>(pConstructor);
1822 9787 : if ( pTxtFrm )
1823 : {
1824 5606 : pTxtFrm->GetTxtNode()->ClearLRSpaceItemDueToListLevelIndents( rLR );
1825 : }
1826 4181 : else if ( pConstructor->IsNoTxtFrm() )
1827 : {
1828 202 : rLR = SvxLRSpaceItem ( RES_LR_SPACE );
1829 : }
1830 :
1831 : //Achtung: Die USHORTs fuer die gecache'ten Werte werden absichtlich
1832 : //nicht initialisiert!
1833 :
1834 : //Muessen alle einmal berechnet werden:
1835 : bTopLine = bBottomLine = bLeftLine = bRightLine =
1836 9787 : bTop = bBottom = bLine = sal_True;
1837 :
1838 9787 : bCacheGetLine = bCachedGetTopLine = bCachedGetBottomLine = sal_False;
1839 : // OD 21.05.2003 #108789# - init cache status for values <bJoinedWithPrev>
1840 : // and <bJoinedWithNext>, which aren't initialized by default.
1841 9787 : bCachedJoinedWithPrev = sal_False;
1842 9787 : bCachedJoinedWithNext = sal_False;
1843 :
1844 9787 : bBorderDist = 0 != (pConstructor->GetType() & (FRM_CELL));
1845 9787 : }
1846 :
1847 29361 : SwBorderAttrs::~SwBorderAttrs()
1848 : {
1849 9787 : ((SwModify*)pOwner)->SetInCache( sal_False );
1850 19574 : }
1851 :
1852 : /*************************************************************************
1853 : |*
1854 : |* SwBorderAttrs::CalcTop(), CalcBottom(), CalcLeft(), CalcRight()
1855 : |*
1856 : |* Beschreibung Die Calc-Methoden errechnen zusaetzlich zu den
1857 : |* von den Attributen vorgegebenen Groessen einen Sicherheitsabstand.
1858 : |* der Sicherheitsabstand wird nur einkalkuliert, wenn Umrandung und/oder
1859 : |* Schatten im Spiel sind; er soll vermeiden, dass aufgrund der
1860 : |* groben physikalischen Gegebenheiten Raender usw. uebermalt werden.
1861 : |*
1862 : |*************************************************************************/
1863 :
1864 1064 : void SwBorderAttrs::_CalcTop()
1865 : {
1866 1064 : nTop = CalcTopLine() + rUL.GetUpper();
1867 1064 : bTop = sal_False;
1868 1064 : }
1869 :
1870 1064 : void SwBorderAttrs::_CalcBottom()
1871 : {
1872 1064 : nBottom = CalcBottomLine() + rUL.GetLower();
1873 1064 : bBottom = sal_False;
1874 1064 : }
1875 :
1876 28468 : long SwBorderAttrs::CalcRight( const SwFrm* pCaller ) const
1877 : {
1878 28468 : long nRight=0;
1879 :
1880 28468 : if (!pCaller->IsTxtFrm() || !((SwTxtFrm*)pCaller)->GetTxtNode()->GetDoc()->get(IDocumentSettingAccess::INVERT_BORDER_SPACING)) {
1881 : // OD 23.01.2003 #106895# - for cell frame in R2L text direction the left
1882 : // and right border are painted on the right respectively left.
1883 19167 : if ( pCaller->IsCellFrm() && pCaller->IsRightToLeft() )
1884 0 : nRight = CalcLeftLine();
1885 : else
1886 19167 : nRight = CalcRightLine();
1887 :
1888 : }
1889 : // for paragraphs, "left" is "before text" and "right" is "after text"
1890 28468 : if ( pCaller->IsTxtFrm() && pCaller->IsRightToLeft() )
1891 18 : nRight += rLR.GetLeft();
1892 : else
1893 28450 : nRight += rLR.GetRight();
1894 :
1895 : // correction: retrieve left margin for numbering in R2L-layout
1896 28468 : if ( pCaller->IsTxtFrm() && pCaller->IsRightToLeft() )
1897 : {
1898 18 : nRight += ((SwTxtFrm*)pCaller)->GetTxtNode()->GetLeftMarginWithNum();
1899 : }
1900 :
1901 28468 : return nRight;
1902 : }
1903 :
1904 : /// Tries to detect if this paragraph has a floating table attached.
1905 7031 : static bool lcl_hasTabFrm(const SwTxtFrm* pTxtFrm)
1906 : {
1907 7031 : if (pTxtFrm->GetDrawObjs())
1908 : {
1909 1213 : const SwSortedObjs* pSortedObjs = pTxtFrm->GetDrawObjs();
1910 1213 : if (pSortedObjs->Count() > 0)
1911 : {
1912 1213 : SwAnchoredObject* pObject = (*pSortedObjs)[0];
1913 1213 : if (pObject->IsA(TYPE(SwFlyFrm)))
1914 : {
1915 1067 : SwFlyFrm* pFly = (SwFlyFrm*)pObject;
1916 1067 : if (pFly->Lower() && pFly->Lower()->IsTabFrm())
1917 24 : return true;
1918 : }
1919 : }
1920 : }
1921 7007 : return false;
1922 : }
1923 :
1924 29546 : long SwBorderAttrs::CalcLeft( const SwFrm *pCaller ) const
1925 : {
1926 29546 : long nLeft=0;
1927 :
1928 29546 : if (!pCaller->IsTxtFrm() || !((SwTxtFrm*)pCaller)->GetTxtNode()->GetDoc()->get(IDocumentSettingAccess::INVERT_BORDER_SPACING)) {
1929 : // OD 23.01.2003 #106895# - for cell frame in R2L text direction the left
1930 : // and right border are painted on the right respectively left.
1931 20039 : if ( pCaller->IsCellFrm() && pCaller->IsRightToLeft() )
1932 0 : nLeft = CalcRightLine();
1933 : else
1934 20039 : nLeft = CalcLeftLine();
1935 : }
1936 :
1937 : // for paragraphs, "left" is "before text" and "right" is "after text"
1938 29546 : if ( pCaller->IsTxtFrm() && pCaller->IsRightToLeft() )
1939 38 : nLeft += rLR.GetRight();
1940 : else
1941 : {
1942 29508 : bool bIgnoreMargin = false;
1943 29508 : if (pCaller->IsTxtFrm())
1944 : {
1945 26543 : const SwTxtFrm* pTxtFrm = (const SwTxtFrm*)pCaller;
1946 26543 : if (pTxtFrm->GetTxtNode()->GetDoc()->get(IDocumentSettingAccess::FLOATTABLE_NOMARGINS))
1947 : {
1948 : // If this is explicitly requested, ignore the margins next to the floating table.
1949 4328 : if (lcl_hasTabFrm(pTxtFrm))
1950 16 : bIgnoreMargin = true;
1951 : // TODO here we only handle the first two paragraphs, would be nice to generalize this.
1952 4312 : else if (pTxtFrm->FindPrev() && pTxtFrm->FindPrev()->IsTxtFrm() && lcl_hasTabFrm((const SwTxtFrm*)pTxtFrm->FindPrev()))
1953 8 : bIgnoreMargin = true;
1954 : }
1955 : }
1956 29508 : if (!bIgnoreMargin)
1957 29484 : nLeft += rLR.GetLeft();
1958 : }
1959 :
1960 :
1961 : // correction: do not retrieve left margin for numbering in R2L-layout
1962 : // if ( pCaller->IsTxtFrm() )
1963 29546 : if ( pCaller->IsTxtFrm() && !pCaller->IsRightToLeft() )
1964 : {
1965 26543 : nLeft += ((SwTxtFrm*)pCaller)->GetTxtNode()->GetLeftMarginWithNum();
1966 : }
1967 :
1968 29546 : return nLeft;
1969 : }
1970 :
1971 : /*************************************************************************
1972 : |*
1973 : |* SwBorderAttrs::CalcTopLine(), CalcBottomLine(),
1974 : |* CalcLeftLine(), CalcRightLine()
1975 : |*
1976 : |* Beschreibung Berechnung der Groessen fuer Umrandung und Schatten.
1977 : |* Es kann auch ohne Linien ein Abstand erwuenscht sein,
1978 : |* dieser wird dann nicht vom Attribut sondern hier
1979 : |* beruecksichtigt (bBorderDist, z.B. fuer Zellen).
1980 : |*
1981 : |*************************************************************************/
1982 :
1983 6885 : void SwBorderAttrs::_CalcTopLine()
1984 : {
1985 11 : nTopLine = (bBorderDist && !rBox.GetTop())
1986 11 : ? rBox.GetDistance (BOX_LINE_TOP)
1987 6896 : : rBox.CalcLineSpace(BOX_LINE_TOP);
1988 6885 : nTopLine = nTopLine + rShadow.CalcShadowSpace(SHADOW_TOP);
1989 6885 : bTopLine = sal_False;
1990 6885 : }
1991 :
1992 6884 : void SwBorderAttrs::_CalcBottomLine()
1993 : {
1994 11 : nBottomLine = (bBorderDist && !rBox.GetBottom())
1995 11 : ? rBox.GetDistance (BOX_LINE_BOTTOM)
1996 6895 : : rBox.CalcLineSpace(BOX_LINE_BOTTOM);
1997 6884 : nBottomLine = nBottomLine + rShadow.CalcShadowSpace(SHADOW_BOTTOM);
1998 6884 : bBottomLine = sal_False;
1999 6884 : }
2000 :
2001 5393 : void SwBorderAttrs::_CalcLeftLine()
2002 : {
2003 11 : nLeftLine = (bBorderDist && !rBox.GetLeft())
2004 11 : ? rBox.GetDistance (BOX_LINE_LEFT)
2005 5404 : : rBox.CalcLineSpace(BOX_LINE_LEFT);
2006 5393 : nLeftLine = nLeftLine + rShadow.CalcShadowSpace(SHADOW_LEFT);
2007 5393 : bLeftLine = sal_False;
2008 5393 : }
2009 :
2010 5393 : void SwBorderAttrs::_CalcRightLine()
2011 : {
2012 11 : nRightLine = (bBorderDist && !rBox.GetRight())
2013 11 : ? rBox.GetDistance (BOX_LINE_RIGHT)
2014 5404 : : rBox.CalcLineSpace(BOX_LINE_RIGHT);
2015 5393 : nRightLine = nRightLine + rShadow.CalcShadowSpace(SHADOW_RIGHT);
2016 5393 : bRightLine = sal_False;
2017 5393 : }
2018 :
2019 : /*************************************************************************/
2020 :
2021 3584 : void SwBorderAttrs::_IsLine()
2022 : {
2023 10653 : bIsLine = rBox.GetTop() || rBox.GetBottom() ||
2024 10650 : rBox.GetLeft()|| rBox.GetRight();
2025 3584 : bLine = sal_False;
2026 3584 : }
2027 :
2028 : /*************************************************************************
2029 : |*
2030 : |* SwBorderAttrs::CmpLeftRightLine(), IsTopLine(), IsBottomLine()
2031 : |*
2032 : |* Die Umrandungen benachbarter Absaetze werden nach folgendem
2033 : |* Algorithmus zusammengefasst:
2034 : |*
2035 : |* 1. Die Umrandung oben faellt weg, wenn der Vorgaenger dieselbe
2036 : |* Umrandung oben aufweist und 3. Zutrifft.
2037 : |* Zusaetzlich muss der Absatz mindestens rechts oder links oder
2038 : |* unten eine Umrandung haben.
2039 : |* 2. Die Umrandung unten faellt weg, wenn der Nachfolger dieselbe
2040 : |* Umrandung untern aufweist und 3. Zustrifft.
2041 : |* Zusaetzlich muss der Absatz mindestens rechts oder links oder
2042 : |* oben eine Umrandung haben.
2043 : |* 3. Die Umrandungen links und rechts vor Vorgaenger bzw. Nachfolger
2044 : |* sind identisch.
2045 : |*
2046 : |*************************************************************************/
2047 33128 : inline int CmpLines( const editeng::SvxBorderLine *pL1, const editeng::SvxBorderLine *pL2 )
2048 : {
2049 33128 : return ( ((pL1 && pL2) && (*pL1 == *pL2)) || (!pL1 && !pL2) );
2050 : }
2051 :
2052 : // OD 21.05.2003 #108789# - change name of 1st parameter - "rAttrs" -> "rCmpAttrs"
2053 : // OD 21.05.2003 #108789# - compare <CalcRight()> and <rCmpAttrs.CalcRight()>
2054 : // instead of only the right LR-spacing, because R2L-layout has to be
2055 : // considered.
2056 8265 : sal_Bool SwBorderAttrs::CmpLeftRight( const SwBorderAttrs &rCmpAttrs,
2057 : const SwFrm *pCaller,
2058 : const SwFrm *pCmp ) const
2059 : {
2060 16530 : return ( CmpLines( rCmpAttrs.GetBox().GetLeft(), GetBox().GetLeft() ) &&
2061 16530 : CmpLines( rCmpAttrs.GetBox().GetRight(),GetBox().GetRight() ) &&
2062 24513 : CalcLeft( pCaller ) == rCmpAttrs.CalcLeft( pCmp ) &&
2063 : // OD 21.05.2003 #108789# - compare <CalcRight> with <rCmpAttrs.CalcRight>.
2064 16248 : CalcRight( pCaller ) == rCmpAttrs.CalcRight( pCmp ) );
2065 : }
2066 :
2067 8305 : sal_Bool SwBorderAttrs::_JoinWithCmp( const SwFrm& _rCallerFrm,
2068 : const SwFrm& _rCmpFrm ) const
2069 : {
2070 8305 : sal_Bool bReturnVal = sal_False;
2071 :
2072 8305 : SwBorderAttrAccess aCmpAccess( SwFrm::GetCache(), &_rCmpFrm );
2073 8305 : const SwBorderAttrs &rCmpAttrs = *aCmpAccess.Get();
2074 24915 : if ( rShadow == rCmpAttrs.GetShadow() &&
2075 16598 : CmpLines( rBox.GetTop(), rCmpAttrs.GetBox().GetTop() ) &&
2076 24863 : CmpLines( rBox.GetBottom(), rCmpAttrs.GetBox().GetBottom() ) &&
2077 8265 : CmpLeftRight( rCmpAttrs, &_rCallerFrm, &_rCmpFrm )
2078 : )
2079 : {
2080 7973 : bReturnVal = sal_True;
2081 : }
2082 :
2083 8305 : return bReturnVal;
2084 : }
2085 :
2086 : // OD 21.05.2003 #108789# - method to determine, if borders are joined with
2087 : // previous frame. Calculated value saved in cached value <bJoinedWithPrev>
2088 : // OD 2004-02-26 #i25029# - add 2nd parameter <_pPrevFrm>
2089 23106 : void SwBorderAttrs::_CalcJoinedWithPrev( const SwFrm& _rFrm,
2090 : const SwFrm* _pPrevFrm )
2091 : {
2092 : // set default
2093 23106 : bJoinedWithPrev = sal_False;
2094 :
2095 23106 : if ( _rFrm.IsTxtFrm() )
2096 : {
2097 : // text frame can potentially join with previous text frame, if
2098 : // corresponding attribute set is set at previous text frame.
2099 : // OD 2004-02-26 #i25029# - If parameter <_pPrevFrm> is set, take this
2100 : // one as previous frame.
2101 22056 : const SwFrm* pPrevFrm = _pPrevFrm ? _pPrevFrm : _rFrm.GetPrev();
2102 : // OD 2004-02-13 #i25029# - skip hidden text frames.
2103 50183 : while ( pPrevFrm && pPrevFrm->IsTxtFrm() &&
2104 6071 : static_cast<const SwTxtFrm*>(pPrevFrm)->IsHiddenNow() )
2105 : {
2106 0 : pPrevFrm = pPrevFrm->GetPrev();
2107 : }
2108 28127 : if ( pPrevFrm && pPrevFrm->IsTxtFrm() &&
2109 6071 : pPrevFrm->GetAttrSet()->GetParaConnectBorder().GetValue()
2110 : )
2111 : {
2112 6071 : bJoinedWithPrev = _JoinWithCmp( _rFrm, *(pPrevFrm) );
2113 : }
2114 : }
2115 :
2116 : // valid cache status, if demanded
2117 : // OD 2004-02-26 #i25029# - Do not validate cache, if parameter <_pPrevFrm>
2118 : // is set.
2119 23106 : bCachedJoinedWithPrev = bCacheGetLine && !_pPrevFrm;
2120 23106 : }
2121 :
2122 : // OD 21.05.2003 #108789# - method to determine, if borders are joined with
2123 : // next frame. Calculated value saved in cached value <bJoinedWithNext>
2124 10157 : void SwBorderAttrs::_CalcJoinedWithNext( const SwFrm& _rFrm )
2125 : {
2126 : // set default
2127 10157 : bJoinedWithNext = sal_False;
2128 :
2129 10157 : if ( _rFrm.IsTxtFrm() )
2130 : {
2131 : // text frame can potentially join with next text frame, if
2132 : // corresponding attribute set is set at current text frame.
2133 : // OD 2004-02-13 #i25029# - get next frame, but skip hidden text frames.
2134 9944 : const SwFrm* pNextFrm = _rFrm.GetNext();
2135 22122 : while ( pNextFrm && pNextFrm->IsTxtFrm() &&
2136 2234 : static_cast<const SwTxtFrm*>(pNextFrm)->IsHiddenNow() )
2137 : {
2138 0 : pNextFrm = pNextFrm->GetNext();
2139 : }
2140 12178 : if ( pNextFrm && pNextFrm->IsTxtFrm() &&
2141 2234 : _rFrm.GetAttrSet()->GetParaConnectBorder().GetValue()
2142 : )
2143 : {
2144 2234 : bJoinedWithNext = _JoinWithCmp( _rFrm, *(pNextFrm) );
2145 : }
2146 : }
2147 :
2148 : // valid cache status, if demanded
2149 10157 : bCachedJoinedWithNext = bCacheGetLine;
2150 10157 : }
2151 :
2152 : // OD 21.05.2003 #108789# - accessor for cached values <bJoinedWithPrev>
2153 : // OD 2004-02-26 #i25029# - add 2nd parameter <_pPrevFrm>, which is passed to
2154 : // method <_CalcJoindWithPrev(..)>.
2155 23110 : sal_Bool SwBorderAttrs::JoinedWithPrev( const SwFrm& _rFrm,
2156 : const SwFrm* _pPrevFrm ) const
2157 : {
2158 23110 : if ( !bCachedJoinedWithPrev || _pPrevFrm )
2159 : {
2160 : // OD 2004-02-26 #i25029# - pass <_pPrevFrm> as 2nd parameter
2161 23106 : const_cast<SwBorderAttrs*>(this)->_CalcJoinedWithPrev( _rFrm, _pPrevFrm );
2162 : }
2163 :
2164 23110 : return bJoinedWithPrev;
2165 : }
2166 :
2167 10161 : sal_Bool SwBorderAttrs::JoinedWithNext( const SwFrm& _rFrm ) const
2168 : {
2169 10161 : if ( !bCachedJoinedWithNext )
2170 : {
2171 10157 : const_cast<SwBorderAttrs*>(this)->_CalcJoinedWithNext( _rFrm );
2172 : }
2173 :
2174 10161 : return bJoinedWithNext;
2175 : }
2176 :
2177 : // OD 2004-02-26 #i25029# - added 2nd parameter <_pPrevFrm>, which is passed to
2178 : // method <JoinedWithPrev>
2179 11712 : void SwBorderAttrs::_GetTopLine( const SwFrm& _rFrm,
2180 : const SwFrm* _pPrevFrm )
2181 : {
2182 11712 : sal_uInt16 nRet = CalcTopLine();
2183 :
2184 : // OD 21.05.2003 #108789# - use new method <JoinWithPrev()>
2185 : // OD 2004-02-26 #i25029# - add 2nd parameter
2186 11712 : if ( JoinedWithPrev( _rFrm, _pPrevFrm ) )
2187 : {
2188 2581 : nRet = 0;
2189 : }
2190 :
2191 11712 : bCachedGetTopLine = bCacheGetLine;
2192 :
2193 11712 : nGetTopLine = nRet;
2194 11712 : }
2195 :
2196 10157 : void SwBorderAttrs::_GetBottomLine( const SwFrm& _rFrm )
2197 : {
2198 10157 : sal_uInt16 nRet = CalcBottomLine();
2199 :
2200 : // OD 21.05.2003 #108789# - use new method <JoinWithPrev()>
2201 10157 : if ( JoinedWithNext( _rFrm ) )
2202 : {
2203 2110 : nRet = 0;
2204 : }
2205 :
2206 10157 : bCachedGetBottomLine = bCacheGetLine;
2207 :
2208 10157 : nGetBottomLine = nRet;
2209 10157 : }
2210 :
2211 : /*************************************************************************/
2212 :
2213 83182 : SwBorderAttrAccess::SwBorderAttrAccess( SwCache &rCach, const SwFrm *pFrm ) :
2214 83182 : SwCacheAccess( rCach, (pFrm->IsCntntFrm() ?
2215 : (void*)((SwCntntFrm*)pFrm)->GetNode() :
2216 37808 : (void*)((SwLayoutFrm*)pFrm)->GetFmt()),
2217 83182 : (sal_Bool)(pFrm->IsCntntFrm() ?
2218 45374 : ((SwModify*)((SwCntntFrm*)pFrm)->GetNode())->IsInCache() :
2219 37808 : ((SwModify*)((SwLayoutFrm*)pFrm)->GetFmt())->IsInCache()) ),
2220 287354 : pConstructor( pFrm )
2221 : {
2222 83182 : }
2223 :
2224 : /*************************************************************************/
2225 :
2226 9787 : SwCacheObj *SwBorderAttrAccess::NewObj()
2227 : {
2228 9787 : ((SwModify*)pOwner)->SetInCache( sal_True );
2229 9787 : return new SwBorderAttrs( (SwModify*)pOwner, pConstructor );
2230 : }
2231 :
2232 83182 : SwBorderAttrs *SwBorderAttrAccess::Get()
2233 : {
2234 83182 : return (SwBorderAttrs*)SwCacheAccess::Get();
2235 : }
2236 :
2237 : /*************************************************************************/
2238 :
2239 834 : SwOrderIter::SwOrderIter( const SwPageFrm *pPg, sal_Bool bFlys ) :
2240 : pPage( pPg ),
2241 : pCurrent( 0 ),
2242 834 : bFlysOnly( bFlys )
2243 : {
2244 834 : }
2245 :
2246 : /*************************************************************************/
2247 :
2248 0 : const SdrObject *SwOrderIter::Top()
2249 : {
2250 0 : pCurrent = 0;
2251 0 : if ( pPage->GetSortedObjs() )
2252 : {
2253 0 : const SwSortedObjs *pObjs = pPage->GetSortedObjs();
2254 0 : if ( pObjs->Count() )
2255 : {
2256 0 : sal_uInt32 nTopOrd = 0;
2257 0 : (*pObjs)[0]->GetDrawObj()->GetOrdNum(); //Aktualisieren erzwingen!
2258 0 : for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
2259 : {
2260 0 : const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
2261 0 : if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
2262 0 : continue;
2263 0 : sal_uInt32 nTmp = pObj->GetOrdNumDirect();
2264 0 : if ( nTmp >= nTopOrd )
2265 : {
2266 0 : nTopOrd = nTmp;
2267 0 : pCurrent = pObj;
2268 : }
2269 : }
2270 : }
2271 : }
2272 0 : return pCurrent;
2273 : }
2274 :
2275 : /*************************************************************************/
2276 :
2277 88 : const SdrObject *SwOrderIter::Bottom()
2278 : {
2279 88 : pCurrent = 0;
2280 88 : if ( pPage->GetSortedObjs() )
2281 : {
2282 88 : sal_uInt32 nBotOrd = USHRT_MAX;
2283 88 : const SwSortedObjs *pObjs = pPage->GetSortedObjs();
2284 88 : if ( pObjs->Count() )
2285 : {
2286 88 : (*pObjs)[0]->GetDrawObj()->GetOrdNum(); //Aktualisieren erzwingen!
2287 240 : for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
2288 : {
2289 152 : const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
2290 152 : if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
2291 0 : continue;
2292 152 : sal_uInt32 nTmp = pObj->GetOrdNumDirect();
2293 152 : if ( nTmp < nBotOrd )
2294 : {
2295 152 : nBotOrd = nTmp;
2296 152 : pCurrent = pObj;
2297 : }
2298 : }
2299 : }
2300 : }
2301 88 : return pCurrent;
2302 : }
2303 :
2304 : /*************************************************************************/
2305 :
2306 1242 : const SdrObject *SwOrderIter::Next()
2307 : {
2308 1242 : const sal_uInt32 nCurOrd = pCurrent ? pCurrent->GetOrdNumDirect() : 0;
2309 1242 : pCurrent = 0;
2310 1242 : if ( pPage->GetSortedObjs() )
2311 : {
2312 1242 : sal_uInt32 nOrd = USHRT_MAX;
2313 1242 : const SwSortedObjs *pObjs = pPage->GetSortedObjs();
2314 1242 : if ( pObjs->Count() )
2315 : {
2316 1242 : (*pObjs)[0]->GetDrawObj()->GetOrdNum(); //Aktualisieren erzwingen!
2317 3476 : for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
2318 : {
2319 2234 : const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
2320 2234 : if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
2321 0 : continue;
2322 2234 : sal_uInt32 nTmp = pObj->GetOrdNumDirect();
2323 2234 : if ( nTmp > nCurOrd && nTmp < nOrd )
2324 : {
2325 408 : nOrd = nTmp;
2326 408 : pCurrent = pObj;
2327 : }
2328 : }
2329 : }
2330 : }
2331 1242 : return pCurrent;
2332 : }
2333 :
2334 : /*************************************************************************/
2335 :
2336 0 : const SdrObject *SwOrderIter::Prev()
2337 : {
2338 0 : const sal_uInt32 nCurOrd = pCurrent ? pCurrent->GetOrdNumDirect() : 0;
2339 0 : pCurrent = 0;
2340 0 : if ( pPage->GetSortedObjs() )
2341 : {
2342 0 : const SwSortedObjs *pObjs = pPage->GetSortedObjs();
2343 0 : if ( pObjs->Count() )
2344 : {
2345 0 : sal_uInt32 nOrd = 0;
2346 0 : (*pObjs)[0]->GetDrawObj()->GetOrdNum(); //Aktualisieren erzwingen!
2347 0 : for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
2348 : {
2349 0 : const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
2350 0 : if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
2351 0 : continue;
2352 0 : sal_uInt32 nTmp = pObj->GetOrdNumDirect();
2353 0 : if ( nTmp < nCurOrd && nTmp >= nOrd )
2354 : {
2355 0 : nOrd = nTmp;
2356 0 : pCurrent = pObj;
2357 : }
2358 : }
2359 : }
2360 : }
2361 0 : return pCurrent;
2362 : }
2363 :
2364 : /*************************************************************************/
2365 :
2366 : //Unterstruktur eines LayoutFrms fuer eine Aktion aufheben und wieder
2367 : //restaurieren.
2368 : //Neuer Algorithmus: Es ist unuetz jeden Nachbarn einzeln zu betrachten und
2369 : //die Pointer sauber zu setzen (Upper, Nachbarn, usw.)
2370 : //Es reicht vollkommen jeweils eine Einzelkette zu loesen, und mit dem
2371 : //Letzen der Einzelkette nachzuschauen ob noch eine weitere Kette
2372 : //angeheangt werden muss. Es brauchen nur die Pointer korrigiert werden,
2373 : //die zur Verkettung notwendig sind. So koennen Beipspielsweise die Pointer
2374 : //auf die Upper auf den alten Uppern stehenbleiben. Korrigiert werden die
2375 : //Pointer dann im RestoreCntnt. Zwischenzeitlich ist sowieso jeder Zugriff
2376 : //verboten.
2377 : //Unterwegs werden die Flys bei der Seite abgemeldet.
2378 :
2379 : // #115759# - 'remove' also drawing object from page and
2380 : // at-fly anchored objects from page
2381 0 : static void lcl_RemoveObjsFromPage( SwFrm* _pFrm )
2382 : {
2383 : OSL_ENSURE( _pFrm->GetDrawObjs(), "Keine DrawObjs fuer lcl_RemoveFlysFromPage." );
2384 0 : SwSortedObjs &rObjs = *_pFrm->GetDrawObjs();
2385 0 : for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
2386 : {
2387 0 : SwAnchoredObject* pObj = rObjs[i];
2388 : // #115759# - reset member, at which the anchored
2389 : // object orients its vertical position
2390 0 : pObj->ClearVertPosOrientFrm();
2391 : // #i43913#
2392 0 : pObj->ResetLayoutProcessBools();
2393 : // #115759# - remove also lower objects of as-character
2394 : // anchored Writer fly frames from page
2395 0 : if ( pObj->ISA(SwFlyFrm) )
2396 : {
2397 0 : SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
2398 :
2399 : // #115759# - remove also direct lowers of Writer
2400 : // fly frame from page
2401 0 : if ( pFlyFrm->GetDrawObjs() )
2402 : {
2403 0 : ::lcl_RemoveObjsFromPage( pFlyFrm );
2404 : }
2405 :
2406 0 : SwCntntFrm* pCnt = pFlyFrm->ContainsCntnt();
2407 0 : while ( pCnt )
2408 : {
2409 0 : if ( pCnt->GetDrawObjs() )
2410 0 : ::lcl_RemoveObjsFromPage( pCnt );
2411 0 : pCnt = pCnt->GetNextCntntFrm();
2412 : }
2413 0 : if ( pFlyFrm->IsFlyFreeFrm() )
2414 : {
2415 : // #i28701# - use new method <GetPageFrm()>
2416 0 : pFlyFrm->GetPageFrm()->RemoveFlyFromPage( pFlyFrm );
2417 : }
2418 : }
2419 : // #115759# - remove also drawing objects from page
2420 0 : else if ( pObj->ISA(SwAnchoredDrawObject) )
2421 : {
2422 0 : if (pObj->GetFrmFmt().GetAnchor().GetAnchorId() != FLY_AS_CHAR)
2423 : {
2424 : pObj->GetPageFrm()->RemoveDrawObjFromPage(
2425 0 : *(static_cast<SwAnchoredDrawObject*>(pObj)) );
2426 : }
2427 : }
2428 : }
2429 0 : }
2430 :
2431 40 : SwFrm *SaveCntnt( SwLayoutFrm *pLay, SwFrm *pStart )
2432 : {
2433 40 : if( pLay->IsSctFrm() && pLay->Lower() && pLay->Lower()->IsColumnFrm() )
2434 9 : sw_RemoveFtns( (SwColumnFrm*)pLay->Lower(), sal_True, sal_True );
2435 :
2436 : SwFrm *pSav;
2437 40 : if ( 0 == (pSav = pLay->ContainsAny()) )
2438 22 : return 0;
2439 :
2440 18 : if( pSav->IsInFtn() && !pLay->IsInFtn() )
2441 : {
2442 0 : do
2443 0 : pSav = pSav->FindNext();
2444 0 : while( pSav && pSav->IsInFtn() );
2445 0 : if( !pSav || !pLay->IsAnLower( pSav ) )
2446 0 : return NULL;
2447 : }
2448 :
2449 : // Tables should be saved as a whole, expection:
2450 : // The contents of a section or a cell inside a table should be saved
2451 18 : if ( pSav->IsInTab() && !( ( pLay->IsSctFrm() || pLay->IsCellFrm() ) && pLay->IsInTab() ) )
2452 0 : while ( !pSav->IsTabFrm() )
2453 0 : pSav = pSav->GetUpper();
2454 :
2455 18 : if( pSav->IsInSct() )
2456 : { // Jetzt wird der oberste Bereich gesucht, der innerhalb von pLay ist.
2457 18 : SwFrm* pSect = pLay->FindSctFrm();
2458 18 : SwFrm *pTmp = pSav;
2459 18 : do
2460 : {
2461 18 : pSav = pTmp;
2462 18 : pTmp = pSav->GetUpper() ? pSav->GetUpper()->FindSctFrm() : NULL;
2463 : } while ( pTmp != pSect );
2464 : }
2465 :
2466 18 : SwFrm *pFloat = pSav;
2467 18 : if( !pStart )
2468 15 : pStart = pSav;
2469 18 : bool bGo = pStart == pSav;
2470 18 : do
2471 : {
2472 18 : if( bGo )
2473 15 : pFloat->GetUpper()->pLower = 0; //Die Teilkette ausklinken.
2474 :
2475 : //Das Ende der Teilkette suchen, unterwegs die Flys abmelden.
2476 3 : do
2477 : {
2478 21 : if( bGo )
2479 : {
2480 18 : if ( pFloat->IsCntntFrm() )
2481 : {
2482 18 : if ( pFloat->GetDrawObjs() )
2483 0 : ::lcl_RemoveObjsFromPage( (SwCntntFrm*)pFloat );
2484 : }
2485 0 : else if ( pFloat->IsTabFrm() || pFloat->IsSctFrm() )
2486 : {
2487 0 : SwCntntFrm *pCnt = ((SwLayoutFrm*)pFloat)->ContainsCntnt();
2488 0 : if( pCnt )
2489 : {
2490 0 : do
2491 0 : { if ( pCnt->GetDrawObjs() )
2492 0 : ::lcl_RemoveObjsFromPage( pCnt );
2493 0 : pCnt = pCnt->GetNextCntntFrm();
2494 0 : } while ( pCnt && ((SwLayoutFrm*)pFloat)->IsAnLower( pCnt ) );
2495 : }
2496 : }
2497 : else {
2498 : OSL_ENSURE( !pFloat, "Neuer Float-Frame?" );
2499 : }
2500 : }
2501 21 : if ( pFloat->GetNext() )
2502 : {
2503 3 : if( bGo )
2504 0 : pFloat->mpUpper = NULL;
2505 3 : pFloat = pFloat->GetNext();
2506 3 : if( !bGo && pFloat == pStart )
2507 : {
2508 3 : bGo = true;
2509 3 : pFloat->mpPrev->mpNext = NULL;
2510 3 : pFloat->mpPrev = NULL;
2511 : }
2512 : }
2513 : else
2514 18 : break;
2515 :
2516 : } while ( pFloat );
2517 :
2518 : //Die naechste Teilkette suchen und die Ketten miteinander verbinden.
2519 18 : SwFrm *pTmp = pFloat->FindNext();
2520 18 : if( bGo )
2521 18 : pFloat->mpUpper = NULL;
2522 :
2523 18 : if( !pLay->IsInFtn() )
2524 34 : while( pTmp && pTmp->IsInFtn() )
2525 0 : pTmp = pTmp->FindNext();
2526 :
2527 18 : if ( !pLay->IsAnLower( pTmp ) )
2528 18 : pTmp = 0;
2529 :
2530 18 : if ( pTmp && bGo )
2531 : {
2532 0 : pFloat->mpNext = pTmp; //Die beiden Ketten verbinden.
2533 0 : pFloat->mpNext->mpPrev = pFloat;
2534 : }
2535 18 : pFloat = pTmp;
2536 18 : bGo = bGo || ( pStart == pFloat );
2537 : } while ( pFloat );
2538 :
2539 18 : return bGo ? pStart : NULL;
2540 : }
2541 :
2542 : // #115759# - add also drawing objects to page and at-fly
2543 : // anchored objects to page
2544 0 : static void lcl_AddObjsToPage( SwFrm* _pFrm, SwPageFrm* _pPage )
2545 : {
2546 : OSL_ENSURE( _pFrm->GetDrawObjs(), "Keine DrawObjs fuer lcl_AddFlysToPage." );
2547 0 : SwSortedObjs &rObjs = *_pFrm->GetDrawObjs();
2548 0 : for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
2549 : {
2550 0 : SwAnchoredObject* pObj = rObjs[i];
2551 :
2552 : // #115759# - unlock position of anchored object
2553 : // in order to get the object's position calculated.
2554 0 : pObj->UnlockPosition();
2555 : // #115759# - add also lower objects of as-character
2556 : // anchored Writer fly frames from page
2557 0 : if ( pObj->ISA(SwFlyFrm) )
2558 : {
2559 0 : SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
2560 0 : if ( pObj->ISA(SwFlyFreeFrm) )
2561 : {
2562 0 : _pPage->AppendFlyToPage( pFlyFrm );
2563 : }
2564 0 : pFlyFrm->_InvalidatePos();
2565 0 : pFlyFrm->_InvalidateSize();
2566 0 : pFlyFrm->InvalidatePage( _pPage );
2567 :
2568 : // #115759# - add also at-fly anchored objects
2569 : // to page
2570 0 : if ( pFlyFrm->GetDrawObjs() )
2571 : {
2572 0 : ::lcl_AddObjsToPage( pFlyFrm, _pPage );
2573 : }
2574 :
2575 0 : SwCntntFrm *pCnt = pFlyFrm->ContainsCntnt();
2576 0 : while ( pCnt )
2577 : {
2578 0 : if ( pCnt->GetDrawObjs() )
2579 0 : ::lcl_AddObjsToPage( pCnt, _pPage );
2580 0 : pCnt = pCnt->GetNextCntntFrm();
2581 : }
2582 : }
2583 : // #115759# - remove also drawing objects from page
2584 0 : else if ( pObj->ISA(SwAnchoredDrawObject) )
2585 : {
2586 0 : if (pObj->GetFrmFmt().GetAnchor().GetAnchorId() != FLY_AS_CHAR)
2587 : {
2588 0 : pObj->InvalidateObjPos();
2589 : _pPage->AppendDrawObjToPage(
2590 0 : *(static_cast<SwAnchoredDrawObject*>(pObj)) );
2591 : }
2592 : }
2593 : }
2594 0 : }
2595 :
2596 18 : void RestoreCntnt( SwFrm *pSav, SwLayoutFrm *pParent, SwFrm *pSibling, bool bGrow )
2597 : {
2598 : OSL_ENSURE( pSav && pParent, "Kein Save oder Parent fuer Restore." );
2599 18 : SWRECTFN( pParent )
2600 :
2601 : //Wenn es bereits FlowFrms unterhalb des neuen Parent gibt, so wird die
2602 : //Kette, beginnend mit pSav, hinter dem letzten angehaengt.
2603 : //Die Teile werden kurzerhand insertet und geeignet invalidiert.
2604 : //Unterwegs werden die Flys der CntntFrms bei der Seite angemeldet.
2605 :
2606 18 : SwPageFrm *pPage = pParent->FindPageFrm();
2607 :
2608 18 : if ( pPage )
2609 18 : pPage->InvalidatePage( pPage ); //Invalides Layout anmelden.
2610 :
2611 : //Vorgaenger festellen und die Verbindung herstellen bzw. initialisieren.
2612 18 : pSav->mpPrev = pSibling;
2613 : SwFrm* pNxt;
2614 18 : if ( pSibling )
2615 : {
2616 1 : pNxt = pSibling->mpNext;
2617 1 : pSibling->mpNext = pSav;
2618 1 : pSibling->_InvalidatePrt();
2619 1 : ((SwCntntFrm*)pSibling)->InvalidatePage( pPage );//Invaliden Cntnt anmelden.
2620 1 : if ( ((SwCntntFrm*)pSibling)->GetFollow() )
2621 1 : pSibling->Prepare( PREP_CLEAR, 0, sal_False );
2622 : }
2623 : else
2624 17 : { pNxt = pParent->pLower;
2625 17 : pParent->pLower = pSav;
2626 17 : pSav->mpUpper = pParent; //Schon mal setzen, sonst ist fuer das
2627 : //invalidate der Parent (z.B. ein Fly) nicht klar.
2628 : //Invaliden Cntnt anmelden.
2629 17 : if ( pSav->IsCntntFrm() )
2630 17 : ((SwCntntFrm*)pSav)->InvalidatePage( pPage );
2631 : else
2632 : { // pSav koennte auch ein leerer SectFrm sein
2633 0 : SwCntntFrm* pCnt = pParent->ContainsCntnt();
2634 0 : if( pCnt )
2635 0 : pCnt->InvalidatePage( pPage );
2636 : }
2637 : }
2638 :
2639 : //Der Parent muss entsprechend gegrow'ed werden.
2640 18 : SwTwips nGrowVal = 0;
2641 : SwFrm* pLast;
2642 18 : do
2643 18 : { pSav->mpUpper = pParent;
2644 18 : nGrowVal += (pSav->Frm().*fnRect->fnGetHeight)();
2645 18 : pSav->_InvalidateAll();
2646 :
2647 : //Jetzt die Flys anmelden, fuer TxtFrms gleich geeignet invalidieren.
2648 18 : if ( pSav->IsCntntFrm() )
2649 : {
2650 36 : if ( pSav->IsTxtFrm() &&
2651 18 : ((SwTxtFrm*)pSav)->GetCacheIdx() != USHRT_MAX )
2652 11 : ((SwTxtFrm*)pSav)->Init(); //Ich bin sein Freund.
2653 :
2654 18 : if ( pPage && pSav->GetDrawObjs() )
2655 0 : ::lcl_AddObjsToPage( (SwCntntFrm*)pSav, pPage );
2656 : }
2657 : else
2658 0 : { SwCntntFrm *pBlub = ((SwLayoutFrm*)pSav)->ContainsCntnt();
2659 0 : if( pBlub )
2660 : {
2661 0 : do
2662 0 : { if ( pPage && pBlub->GetDrawObjs() )
2663 0 : ::lcl_AddObjsToPage( pBlub, pPage );
2664 0 : if( pBlub->IsTxtFrm() && ((SwTxtFrm*)pBlub)->HasFtn() &&
2665 0 : ((SwTxtFrm*)pBlub)->GetCacheIdx() != USHRT_MAX )
2666 0 : ((SwTxtFrm*)pBlub)->Init(); //Ich bin sein Freund.
2667 0 : pBlub = pBlub->GetNextCntntFrm();
2668 0 : } while ( pBlub && ((SwLayoutFrm*)pSav)->IsAnLower( pBlub ));
2669 : }
2670 : }
2671 18 : pLast = pSav;
2672 18 : pSav = pSav->GetNext();
2673 :
2674 : } while ( pSav );
2675 :
2676 18 : if( pNxt )
2677 : {
2678 4 : pLast->mpNext = pNxt;
2679 4 : pNxt->mpPrev = pLast;
2680 : }
2681 :
2682 18 : if ( bGrow )
2683 18 : pParent->Grow( nGrowVal );
2684 18 : }
2685 :
2686 : /*************************************************************************
2687 : |*
2688 : |* SqRt() Berechnung der Quadratwurzel, damit die math.lib
2689 : |* nicht auch noch dazugelinkt werden muss.
2690 : |*
2691 : |*************************************************************************/
2692 :
2693 123 : sal_uLong SqRt( BigInt nX )
2694 : {
2695 123 : BigInt nErg = 1;
2696 :
2697 123 : if ( !nX.IsNeg() )
2698 : {
2699 123 : BigInt nOldErg = 1;
2700 861 : for ( int i = 0; i <= 5; i++ )
2701 : {
2702 738 : nErg = (nOldErg + (nX / nOldErg)) / BigInt(2);
2703 738 : nOldErg = nErg;
2704 : }
2705 : }
2706 123 : return nErg >= BigInt(SAL_MAX_UINT32) ? ULONG_MAX : (sal_uLong)nErg;
2707 : }
2708 :
2709 : /*************************************************************************/
2710 :
2711 890 : SwPageFrm * InsertNewPage( SwPageDesc &rDesc, SwFrm *pUpper,
2712 : bool bOdd, bool bFirst, bool bInsertEmpty, sal_Bool bFtn,
2713 : SwFrm *pSibling )
2714 : {
2715 : SwPageFrm *pRet;
2716 890 : SwDoc *pDoc = ((SwLayoutFrm*)pUpper)->GetFmt()->GetDoc();
2717 890 : if (bFirst)
2718 : {
2719 820 : if (rDesc.IsFirstShared())
2720 : {
2721 : // We need to fallback to left or right page format, decide it now.
2722 810 : if (bOdd)
2723 : {
2724 796 : rDesc.GetFirst().SetFmtAttr( rDesc.GetMaster().GetHeader() );
2725 796 : rDesc.GetFirst().SetFmtAttr( rDesc.GetMaster().GetFooter() );
2726 : // fdo#60250 copy margins for mirrored pages
2727 796 : rDesc.GetFirst().SetFmtAttr( rDesc.GetMaster().GetLRSpace() );
2728 : }
2729 : else
2730 : {
2731 14 : rDesc.GetFirst().SetFmtAttr( rDesc.GetLeft().GetHeader() );
2732 14 : rDesc.GetFirst().SetFmtAttr( rDesc.GetLeft().GetFooter() );
2733 14 : rDesc.GetFirst().SetFmtAttr( rDesc.GetLeft().GetLRSpace() );
2734 : }
2735 : }
2736 : }
2737 890 : SwFrmFmt *pFmt(bOdd ? rDesc.GetRightFmt(bFirst) : rDesc.GetLeftFmt(bFirst));
2738 : //Wenn ich kein FrmFmt fuer die Seite gefunden habe, muss ich eben
2739 : //eine Leerseite einfuegen.
2740 890 : if ( !pFmt )
2741 : {
2742 1 : pFmt = bOdd ? rDesc.GetLeftFmt() : rDesc.GetRightFmt();
2743 : OSL_ENSURE( pFmt, "Descriptor without any format?!" );
2744 1 : bInsertEmpty = !bInsertEmpty;
2745 : }
2746 890 : if( bInsertEmpty )
2747 : {
2748 0 : SwPageDesc *pTmpDesc = pSibling && pSibling->GetPrev() ?
2749 1 : ((SwPageFrm*)pSibling->GetPrev())->GetPageDesc() : &rDesc;
2750 1 : pRet = new SwPageFrm( pDoc->GetEmptyPageFmt(), pUpper, pTmpDesc );
2751 1 : pRet->Paste( pUpper, pSibling );
2752 1 : pRet->PreparePage( bFtn );
2753 : }
2754 890 : pRet = new SwPageFrm( pFmt, pUpper, &rDesc );
2755 890 : pRet->Paste( pUpper, pSibling );
2756 890 : pRet->PreparePage( bFtn );
2757 890 : if ( pRet->GetNext() )
2758 0 : ((SwRootFrm*)pRet->GetUpper())->AssertPageFlys( pRet );
2759 890 : return pRet;
2760 : }
2761 :
2762 :
2763 : /*************************************************************************
2764 : |*
2765 : |* RegistFlys(), Regist() Die beiden folgenden Methoden durchsuchen rekursiv
2766 : |* eine Layoutstruktur und melden alle FlyFrms, die einen beliebigen Frm
2767 : |* innerhalb der Struktur als Anker haben bei der Seite an.
2768 : |*
2769 : |*************************************************************************/
2770 :
2771 16 : static void lcl_Regist( SwPageFrm *pPage, const SwFrm *pAnch )
2772 : {
2773 16 : SwSortedObjs *pObjs = (SwSortedObjs*)pAnch->GetDrawObjs();
2774 36 : for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
2775 : {
2776 20 : SwAnchoredObject* pObj = (*pObjs)[i];
2777 20 : if ( pObj->ISA(SwFlyFrm) )
2778 : {
2779 4 : SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pObj);
2780 : //Ggf. ummelden, nicht anmelden wenn bereits bekannt.
2781 : // #i28701# - use new method <GetPageFrm()>
2782 4 : SwPageFrm *pPg = pFly->IsFlyFreeFrm()
2783 4 : ? pFly->GetPageFrm() : pFly->FindPageFrm();
2784 4 : if ( pPg != pPage )
2785 : {
2786 4 : if ( pPg )
2787 0 : pPg->RemoveFlyFromPage( pFly );
2788 4 : pPage->AppendFlyToPage( pFly );
2789 : }
2790 4 : ::RegistFlys( pPage, pFly );
2791 : }
2792 : else
2793 : {
2794 : // #i87493#
2795 16 : if ( pPage != pObj->GetPageFrm() )
2796 : {
2797 : // #i28701#
2798 16 : if ( pObj->GetPageFrm() )
2799 0 : pObj->GetPageFrm()->RemoveDrawObjFromPage( *pObj );
2800 16 : pPage->AppendDrawObjToPage( *pObj );
2801 : }
2802 : }
2803 :
2804 20 : const SwFlyFrm* pFly = pAnch->FindFlyFrm();
2805 20 : if ( pFly &&
2806 20 : pObj->GetDrawObj()->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() &&
2807 0 : pObj->GetDrawObj()->GetPage() )
2808 : {
2809 : //#i119945# set pFly's OrdNum to pObj's. So when pFly is removed by Undo, the original OrdNum will not be changed.
2810 0 : pObj->DrawObj()->GetPage()->SetObjectOrdNum( pFly->GetVirtDrawObj()->GetOrdNumDirect(),
2811 0 : pObj->GetDrawObj()->GetOrdNumDirect() );
2812 : }
2813 : }
2814 16 : }
2815 :
2816 5565 : void RegistFlys( SwPageFrm *pPage, const SwLayoutFrm *pLay )
2817 : {
2818 5565 : if ( pLay->GetDrawObjs() )
2819 0 : ::lcl_Regist( pPage, pLay );
2820 5565 : const SwFrm *pFrm = pLay->Lower();
2821 18533 : while ( pFrm )
2822 : {
2823 7403 : if ( pFrm->IsLayoutFrm() )
2824 4051 : ::RegistFlys( pPage, (const SwLayoutFrm*)pFrm );
2825 3352 : else if ( pFrm->GetDrawObjs() )
2826 16 : ::lcl_Regist( pPage, pFrm );
2827 7403 : pFrm = pFrm->GetNext();
2828 : }
2829 5565 : }
2830 :
2831 : /*************************************************************************
2832 : |*
2833 : |* void Notify()
2834 : |*
2835 : |* Beschreibung Benachrichtigt den Hintergrund je nach der
2836 : |* Veraenderung zwischen altem und neuem Rechteckt.
2837 : |*
2838 : |*************************************************************************/
2839 :
2840 782 : void Notify( SwFlyFrm *pFly, SwPageFrm *pOld, const SwRect &rOld,
2841 : const SwRect* pOldPrt )
2842 : {
2843 782 : const SwRect aFrm( pFly->GetObjRectWithSpaces() );
2844 782 : if ( rOld.Pos() != aFrm.Pos() )
2845 : { //Positionsaenderung, alten und neuen Bereich invalidieren
2846 648 : if ( rOld.HasArea() &&
2847 324 : rOld.Left()+pFly->GetFmt()->GetLRSpace().GetLeft() < FAR_AWAY )
2848 : {
2849 12 : pFly->NotifyBackground( pOld, rOld, PREP_FLY_LEAVE );
2850 : }
2851 324 : pFly->NotifyBackground( pFly->FindPageFrm(), aFrm, PREP_FLY_ARRIVE );
2852 : }
2853 458 : else if ( rOld.SSize() != aFrm.SSize() )
2854 : { //Groessenaenderung, den Bereich der Verlassen wurde bzw. jetzt
2855 : //ueberdeckt wird invalidieren.
2856 : //Der Einfachheit halber wird hier bewusst jeweils ein Twip
2857 : //unnoetig invalidiert.
2858 :
2859 168 : ViewShell *pSh = pFly->getRootFrm()->GetCurrShell();
2860 168 : if( pSh && rOld.HasArea() )
2861 168 : pSh->InvalidateWindows( rOld );
2862 :
2863 : // #i51941# - consider case that fly frame isn't
2864 : // registered at the old page <pOld>
2865 168 : SwPageFrm* pPageFrm = pFly->FindPageFrm();
2866 168 : if ( pOld != pPageFrm )
2867 : {
2868 13 : pFly->NotifyBackground( pPageFrm, aFrm, PREP_FLY_ARRIVE );
2869 : }
2870 :
2871 168 : if ( rOld.Left() != aFrm.Left() )
2872 : {
2873 0 : SwRect aTmp( rOld );
2874 0 : aTmp.Union( aFrm );
2875 0 : aTmp.Left( std::min(aFrm.Left(), rOld.Left()) );
2876 0 : aTmp.Right( std::max(aFrm.Left(), rOld.Left()) );
2877 0 : pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
2878 : }
2879 168 : SwTwips nOld = rOld.Right();
2880 168 : SwTwips nNew = aFrm.Right();
2881 168 : if ( nOld != nNew )
2882 : {
2883 2 : SwRect aTmp( rOld );
2884 2 : aTmp.Union( aFrm );
2885 2 : aTmp.Left( std::min(nNew, nOld) );
2886 2 : aTmp.Right( std::max(nNew, nOld) );
2887 2 : pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
2888 : }
2889 168 : if ( rOld.Top() != aFrm.Top() )
2890 : {
2891 0 : SwRect aTmp( rOld );
2892 0 : aTmp.Union( aFrm );
2893 0 : aTmp.Top( std::min(aFrm.Top(), rOld.Top()) );
2894 0 : aTmp.Bottom( std::max(aFrm.Top(), rOld.Top()) );
2895 0 : pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
2896 : }
2897 168 : nOld = rOld.Bottom();
2898 168 : nNew = aFrm.Bottom();
2899 168 : if ( nOld != nNew )
2900 : {
2901 166 : SwRect aTmp( rOld );
2902 166 : aTmp.Union( aFrm );
2903 166 : aTmp.Top( std::min(nNew, nOld) );
2904 166 : aTmp.Bottom( std::max(nNew, nOld) );
2905 166 : pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
2906 : }
2907 : }
2908 294 : else if ( pOldPrt && *pOldPrt != pFly->Prt() &&
2909 4 : pFly->GetFmt()->GetSurround().IsContour() )
2910 : {
2911 : // #i24097#
2912 0 : pFly->NotifyBackground( pFly->FindPageFrm(), aFrm, PREP_FLY_ARRIVE );
2913 : }
2914 782 : }
2915 :
2916 : /*************************************************************************/
2917 :
2918 934 : static void lcl_CheckFlowBack( SwFrm* pFrm, const SwRect &rRect )
2919 : {
2920 934 : SwTwips nBottom = rRect.Bottom();
2921 3553 : while( pFrm )
2922 : {
2923 1685 : if( pFrm->IsLayoutFrm() )
2924 : {
2925 932 : if( rRect.IsOver( pFrm->Frm() ) )
2926 658 : lcl_CheckFlowBack( ((SwLayoutFrm*)pFrm)->Lower(), rRect );
2927 : }
2928 753 : else if( !pFrm->GetNext() && nBottom > pFrm->Frm().Bottom() )
2929 : {
2930 257 : if( pFrm->IsCntntFrm() && ((SwCntntFrm*)pFrm)->HasFollow() )
2931 1 : pFrm->InvalidateSize();
2932 : else
2933 256 : pFrm->InvalidateNextPos();
2934 : }
2935 1685 : pFrm = pFrm->GetNext();
2936 : }
2937 934 : }
2938 :
2939 6217 : static void lcl_NotifyCntnt( const SdrObject *pThis, SwCntntFrm *pCnt,
2940 : const SwRect &rRect, const PrepareHint eHint )
2941 : {
2942 6217 : if ( pCnt->IsTxtFrm() )
2943 : {
2944 6195 : SwRect aCntPrt( pCnt->Prt() );
2945 6195 : aCntPrt.Pos() += pCnt->Frm().Pos();
2946 6195 : if ( eHint == PREP_FLY_ATTR_CHG )
2947 : {
2948 : // #i35640# - use given rectangle <rRect> instead
2949 : // of current bound rectangle
2950 38 : if ( aCntPrt.IsOver( rRect ) )
2951 20 : pCnt->Prepare( PREP_FLY_ATTR_CHG );
2952 : }
2953 : // #i23129# - only invalidate, if the text frame
2954 : // printing area overlaps with the given rectangle.
2955 6157 : else if ( aCntPrt.IsOver( rRect ) )
2956 635 : pCnt->Prepare( eHint, (void*)&aCntPrt._Intersection( rRect ) );
2957 6195 : if ( pCnt->GetDrawObjs() )
2958 : {
2959 625 : const SwSortedObjs &rObjs = *pCnt->GetDrawObjs();
2960 1569 : for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
2961 : {
2962 944 : SwAnchoredObject* pObj = rObjs[i];
2963 944 : if ( pObj->ISA(SwFlyFrm) )
2964 : {
2965 593 : SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pObj);
2966 593 : if ( pFly->IsFlyInCntFrm() )
2967 : {
2968 30 : SwCntntFrm *pCntnt = pFly->ContainsCntnt();
2969 90 : while ( pCntnt )
2970 : {
2971 30 : ::lcl_NotifyCntnt( pThis, pCntnt, rRect, eHint );
2972 30 : pCntnt = pCntnt->GetNextCntntFrm();
2973 : }
2974 : }
2975 : }
2976 : }
2977 : }
2978 : }
2979 6217 : }
2980 :
2981 609 : void Notify_Background( const SdrObject* pObj,
2982 : SwPageFrm* pPage,
2983 : const SwRect& rRect,
2984 : const PrepareHint eHint,
2985 : const sal_Bool bInva )
2986 : {
2987 :
2988 : //Wenn der Frm gerade erstmalig sinnvoll positioniert wurde, braucht der
2989 : //alte Bereich nicht benachrichtigt werden.
2990 609 : if ( eHint == PREP_FLY_LEAVE && rRect.Top() == FAR_AWAY )
2991 612 : return;
2992 :
2993 : SwLayoutFrm* pArea;
2994 606 : SwFlyFrm *pFlyFrm = 0;
2995 : SwFrm* pAnchor;
2996 606 : if( pObj->ISA(SwVirtFlyDrawObj) )
2997 : {
2998 383 : pFlyFrm = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
2999 383 : pAnchor = pFlyFrm->AnchorFrm();
3000 : }
3001 : else
3002 : {
3003 223 : pFlyFrm = NULL;
3004 : pAnchor = const_cast<SwFrm*>(
3005 223 : GetUserCall(pObj)->GetAnchoredObj( pObj )->GetAnchorFrm() );
3006 : }
3007 606 : if( PREP_FLY_LEAVE != eHint && pAnchor->IsInFly() )
3008 0 : pArea = pAnchor->FindFlyFrm();
3009 : else
3010 606 : pArea = pPage;
3011 606 : SwCntntFrm *pCnt = 0;
3012 606 : if ( pArea )
3013 : {
3014 606 : if( PREP_FLY_ARRIVE != eHint )
3015 276 : lcl_CheckFlowBack( pArea, rRect );
3016 :
3017 : //Es reagieren sowieso nur die auf den Anker folgenden auf den Fly, also
3018 : //brauchen diese nicht abgeklappert werden.
3019 : //Ausnahme sind ist natuerlich das LEAVE, denn der Fly koennte ja von
3020 : //"oben" kommen.
3021 : // Wenn der Anker auf der vorhergehenden Seite liegt, muss ebenfalls
3022 : // die gesamte Seite abgearbeitet werden. (47722)
3023 : // OD 2004-05-13 #i28701# - If the wrapping style has to be considered
3024 : // on the object positioning, the complete area has to be processed,
3025 : // because content frames before the anchor frame also have to consider
3026 : // the object for the text wrapping.
3027 : // #i3317# - The complete area has always been
3028 : // processed.
3029 : {
3030 606 : pCnt = pArea->ContainsCntnt();
3031 : }
3032 : }
3033 606 : SwFrm *pLastTab = 0;
3034 :
3035 7240 : while ( pCnt && pArea && pArea->IsAnLower( pCnt ) )
3036 : {
3037 6028 : ::lcl_NotifyCntnt( pObj, pCnt, rRect, eHint );
3038 6028 : if ( pCnt->IsInTab() )
3039 : {
3040 3338 : SwLayoutFrm* pCell = pCnt->GetUpper();
3041 : // #i40606# - use <GetLastBoundRect()>
3042 : // instead of <GetCurrentBoundRect()>, because a recalculation
3043 : // of the bounding rectangle isn't intended here.
3044 13588 : if ( pCell->IsCellFrm() &&
3045 16477 : ( pCell->Frm().IsOver( pObj->GetLastBoundRect() ) ||
3046 3125 : pCell->Frm().IsOver( rRect ) ) )
3047 : {
3048 236 : const SwFmtVertOrient &rOri = pCell->GetFmt()->GetVertOrient();
3049 236 : if ( text::VertOrientation::NONE != rOri.GetVertOrient() )
3050 128 : pCell->InvalidatePrt();
3051 : }
3052 3338 : SwTabFrm *pTab = pCnt->FindTabFrm();
3053 3338 : if ( pTab != pLastTab )
3054 : {
3055 154 : pLastTab = pTab;
3056 : // #i40606# - use <GetLastBoundRect()>
3057 : // instead of <GetCurrentBoundRect()>, because a recalculation
3058 : // of the bounding rectangle isn't intended here.
3059 205 : if ( pTab->Frm().IsOver( pObj->GetLastBoundRect() ) ||
3060 51 : pTab->Frm().IsOver( rRect ) )
3061 : {
3062 109 : if ( !pFlyFrm || !pFlyFrm->IsLowerOf( pTab ) )
3063 104 : pTab->InvalidatePrt();
3064 : }
3065 : }
3066 : }
3067 6028 : pCnt = pCnt->GetNextCntntFrm();
3068 : }
3069 : // #108745# Sorry, but this causes nothing but trouble. I remove these lines
3070 : // taking the risk that the footer frame will have a wrong height
3071 : // if( pPage->Lower() )
3072 : // {
3073 : // SwFrm* pFrm = pPage->Lower();
3074 : // while( pFrm->GetNext() )
3075 : // pFrm = pFrm->GetNext();
3076 : // if( pFrm->IsFooterFrm() &&
3077 : // ( ( pFrm->Frm().IsOver( pObj->GetBoundRect() ) ||
3078 : // pFrm->Frm().IsOver( rRect ) ) ) )
3079 : // pFrm->InvalidateSize();
3080 : // }
3081 : // #128702# - make code robust
3082 606 : if ( pPage && pPage->GetSortedObjs() )
3083 : {
3084 604 : pObj->GetOrdNum();
3085 604 : const SwSortedObjs &rObjs = *pPage->GetSortedObjs();
3086 1805 : for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
3087 : {
3088 1201 : SwAnchoredObject* pAnchoredObj = rObjs[i];
3089 1201 : if ( pAnchoredObj->ISA(SwFlyFrm) )
3090 : {
3091 695 : if( pAnchoredObj->GetDrawObj() == pObj )
3092 383 : continue;
3093 312 : SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
3094 312 : if ( pFly->Frm().Top() == FAR_AWAY )
3095 118 : continue;
3096 :
3097 509 : if ( !pFlyFrm ||
3098 318 : (!pFly->IsLowerOf( pFlyFrm ) &&
3099 159 : pFly->GetVirtDrawObj()->GetOrdNumDirect() < pObj->GetOrdNumDirect()))
3100 : {
3101 156 : pCnt = pFly->ContainsCntnt();
3102 471 : while ( pCnt )
3103 : {
3104 159 : ::lcl_NotifyCntnt( pObj, pCnt, rRect, eHint );
3105 159 : pCnt = pCnt->GetNextCntntFrm();
3106 : }
3107 : }
3108 194 : if( pFly->IsFlyLayFrm() )
3109 : {
3110 120 : if( pFly->Lower() && pFly->Lower()->IsColumnFrm() &&
3111 0 : pFly->Frm().Bottom() >= rRect.Top() &&
3112 0 : pFly->Frm().Top() <= rRect.Bottom() &&
3113 40 : pFly->Frm().Right() >= rRect.Left() &&
3114 0 : pFly->Frm().Left() <= rRect.Right() )
3115 : {
3116 0 : pFly->InvalidateSize();
3117 : }
3118 : }
3119 : //Flys, die ueber mir liegen muessen/mussten evtl.
3120 : //ausweichen, wenn sie eine automatische Ausrichtung haben.
3121 : //das ist unabhaengig von meinem Attribut, weil dies sich
3122 : //gerade geaendert haben kann und eben deshalb
3123 : //umformatiert wurde.
3124 462 : else if ( pFly->IsFlyAtCntFrm() &&
3125 154 : pObj->GetOrdNumDirect() <
3126 218 : pFly->GetVirtDrawObj()->GetOrdNumDirect() &&
3127 186 : pFlyFrm && !pFly->IsLowerOf( pFlyFrm ) )
3128 : {
3129 32 : const SwFmtHoriOrient &rH = pFly->GetFmt()->GetHoriOrient();
3130 71 : if ( text::HoriOrientation::NONE != rH.GetHoriOrient() &&
3131 7 : text::HoriOrientation::CENTER != rH.GetHoriOrient() &&
3132 32 : ( !pFly->IsAutoPos() || text::RelOrientation::CHAR != rH.GetRelationOrient() ) &&
3133 0 : (pFly->Frm().Bottom() >= rRect.Top() &&
3134 0 : pFly->Frm().Top() <= rRect.Bottom()) )
3135 0 : pFly->InvalidatePos();
3136 : }
3137 : }
3138 : }
3139 : }
3140 606 : if ( pFlyFrm && pAnchor->GetUpper() && pAnchor->IsInTab() )//MA_FLY_HEIGHT
3141 5 : pAnchor->GetUpper()->InvalidateSize();
3142 :
3143 : // #i82258# - make code robust
3144 606 : ViewShell* pSh = 0;
3145 1212 : if ( bInva && pPage &&
3146 606 : 0 != (pSh = pPage->getRootFrm()->GetCurrShell()) )
3147 : {
3148 585 : pSh->InvalidateWindows( rRect );
3149 : }
3150 : }
3151 :
3152 : /*************************************************************************
3153 : |*
3154 : |* GetVirtualUpper() liefert bei absatzgebundenen Objekten den Upper
3155 : |* des Ankers. Falls es sich dabei um verkettete Rahmen oder
3156 : |* Fussnoten handelt, wird ggf. der "virtuelle" Upper ermittelt.
3157 : |*
3158 : |*************************************************************************/
3159 :
3160 210 : const SwFrm* GetVirtualUpper( const SwFrm* pFrm, const Point& rPos )
3161 : {
3162 210 : if( pFrm->IsTxtFrm() )
3163 : {
3164 186 : pFrm = pFrm->GetUpper();
3165 186 : if( !pFrm->Frm().IsInside( rPos ) )
3166 : {
3167 43 : if( pFrm->IsFtnFrm() )
3168 : {
3169 0 : const SwFtnFrm* pTmp = ((SwFtnFrm*)pFrm)->GetFollow();
3170 0 : while( pTmp )
3171 : {
3172 0 : if( pTmp->Frm().IsInside( rPos ) )
3173 0 : return pTmp;
3174 0 : pTmp = pTmp->GetFollow();
3175 : }
3176 : }
3177 : else
3178 : {
3179 43 : SwFlyFrm* pTmp = (SwFlyFrm*)pFrm->FindFlyFrm();
3180 86 : while( pTmp )
3181 : {
3182 0 : if( pTmp->Frm().IsInside( rPos ) )
3183 0 : return pTmp;
3184 0 : pTmp = pTmp->GetNextLink();
3185 : }
3186 : }
3187 : }
3188 : }
3189 210 : return pFrm;
3190 : }
3191 :
3192 : /*************************************************************************/
3193 :
3194 167 : bool Is_Lower_Of( const SwFrm *pCurrFrm, const SdrObject* pObj )
3195 : {
3196 167 : Point aPos;
3197 : const SwFrm* pFrm;
3198 167 : if( pObj->ISA(SwVirtFlyDrawObj) )
3199 : {
3200 161 : const SwFlyFrm* pFly = ( (SwVirtFlyDrawObj*)pObj )->GetFlyFrm();
3201 161 : pFrm = pFly->GetAnchorFrm();
3202 161 : aPos = pFly->Frm().Pos();
3203 : }
3204 : else
3205 : {
3206 6 : pFrm = ( (SwDrawContact*)GetUserCall(pObj) )->GetAnchorFrm(pObj);
3207 6 : aPos = pObj->GetCurrentBoundRect().TopLeft();
3208 : }
3209 : OSL_ENSURE( pFrm, "8-( Fly is lost in Space." );
3210 167 : pFrm = GetVirtualUpper( pFrm, aPos );
3211 495 : do
3212 495 : { if ( pFrm == pCurrFrm )
3213 0 : return true;
3214 495 : if( pFrm->IsFlyFrm() )
3215 : {
3216 0 : aPos = pFrm->Frm().Pos();
3217 0 : pFrm = GetVirtualUpper( ((const SwFlyFrm*)pFrm)->GetAnchorFrm(), aPos );
3218 : }
3219 : else
3220 495 : pFrm = pFrm->GetUpper();
3221 : } while ( pFrm );
3222 167 : return false;
3223 : }
3224 :
3225 1231 : const SwFrm *FindKontext( const SwFrm *pFrm, sal_uInt16 nAdditionalKontextTyp )
3226 : {
3227 : //Liefert die Umgebung des Frm in die kein Fly aus einer anderen
3228 : //Umgebung hineinragen kann.
3229 : const sal_uInt16 nTyp = FRM_ROOT | FRM_HEADER | FRM_FOOTER | FRM_FTNCONT |
3230 : FRM_FTN | FRM_FLY |
3231 : FRM_TAB | FRM_ROW | FRM_CELL |
3232 1231 : nAdditionalKontextTyp;
3233 3168 : do
3234 4399 : { if ( pFrm->GetType() & nTyp )
3235 1231 : break;
3236 3168 : pFrm = pFrm->GetUpper();
3237 : } while( pFrm );
3238 1231 : return pFrm;
3239 : }
3240 :
3241 201 : bool IsFrmInSameKontext( const SwFrm *pInnerFrm, const SwFrm *pFrm )
3242 : {
3243 201 : const SwFrm *pKontext = FindKontext( pInnerFrm, 0 );
3244 :
3245 : const sal_uInt16 nTyp = FRM_ROOT | FRM_HEADER | FRM_FOOTER | FRM_FTNCONT |
3246 : FRM_FTN | FRM_FLY |
3247 201 : FRM_TAB | FRM_ROW | FRM_CELL;
3248 336 : do
3249 529 : { if ( pFrm->GetType() & nTyp )
3250 : {
3251 244 : if( pFrm == pKontext )
3252 43 : return true;
3253 201 : if( pFrm->IsCellFrm() )
3254 150 : return false;
3255 : }
3256 336 : if( pFrm->IsFlyFrm() )
3257 : {
3258 43 : Point aPos( pFrm->Frm().Pos() );
3259 43 : pFrm = GetVirtualUpper( ((const SwFlyFrm*)pFrm)->GetAnchorFrm(), aPos );
3260 : }
3261 : else
3262 293 : pFrm = pFrm->GetUpper();
3263 : } while( pFrm );
3264 :
3265 8 : return false;
3266 : }
3267 :
3268 :
3269 : //---------------------------------
3270 :
3271 0 : static SwTwips lcl_CalcCellRstHeight( SwLayoutFrm *pCell )
3272 : {
3273 0 : if ( pCell->Lower()->IsCntntFrm() || pCell->Lower()->IsSctFrm() )
3274 : {
3275 0 : SwFrm *pLow = pCell->Lower();
3276 0 : long nHeight = 0, nFlyAdd = 0;
3277 0 : do
3278 : {
3279 0 : long nLow = pLow->Frm().Height();
3280 0 : if( pLow->IsTxtFrm() && ((SwTxtFrm*)pLow)->IsUndersized() )
3281 0 : nLow += ((SwTxtFrm*)pLow)->GetParHeight()-pLow->Prt().Height();
3282 0 : else if( pLow->IsSctFrm() && ((SwSectionFrm*)pLow)->IsUndersized() )
3283 0 : nLow += ((SwSectionFrm*)pLow)->Undersize();
3284 0 : nFlyAdd = std::max( 0L, nFlyAdd - nLow );
3285 0 : nFlyAdd = std::max( nFlyAdd, ::CalcHeightWidthFlys( pLow ) );
3286 0 : nHeight += nLow;
3287 0 : pLow = pLow->GetNext();
3288 : } while ( pLow );
3289 0 : if ( nFlyAdd )
3290 0 : nHeight += nFlyAdd;
3291 :
3292 : //Der Border will natuerlich auch mitspielen, er kann leider nicht
3293 : //aus PrtArea und Frm errechnet werden, da diese in beliebiger
3294 : //Kombination ungueltig sein koennen.
3295 0 : SwBorderAttrAccess aAccess( SwFrm::GetCache(), pCell );
3296 0 : const SwBorderAttrs &rAttrs = *aAccess.Get();
3297 0 : nHeight += rAttrs.CalcTop() + rAttrs.CalcBottom();
3298 :
3299 0 : return pCell->Frm().Height() - nHeight;
3300 : }
3301 : else
3302 : {
3303 0 : long nRstHeight = 0;
3304 0 : SwFrm *pLow = pCell->Lower();
3305 0 : do
3306 0 : { nRstHeight += ::CalcRowRstHeight( (SwLayoutFrm*)pLow );
3307 0 : pLow = pLow->GetNext();
3308 :
3309 : } while ( pLow );
3310 :
3311 0 : return nRstHeight;
3312 : }
3313 : }
3314 :
3315 0 : SwTwips CalcRowRstHeight( SwLayoutFrm *pRow )
3316 : {
3317 0 : SwTwips nRstHeight = LONG_MAX;
3318 0 : SwLayoutFrm *pLow = (SwLayoutFrm*)pRow->Lower();
3319 0 : while ( pLow )
3320 : {
3321 0 : nRstHeight = std::min( nRstHeight, ::lcl_CalcCellRstHeight( pLow ) );
3322 0 : pLow = (SwLayoutFrm*)pLow->GetNext();
3323 : }
3324 0 : return nRstHeight;
3325 : }
3326 :
3327 115 : const SwFrm* FindPage( const SwRect &rRect, const SwFrm *pPage )
3328 : {
3329 115 : if ( !rRect.IsOver( pPage->Frm() ) )
3330 : {
3331 2 : const SwRootFrm* pRootFrm = static_cast<const SwRootFrm*>(pPage->GetUpper());
3332 2 : const SwFrm* pTmpPage = pRootFrm ? pRootFrm->GetPageAtPos( rRect.TopLeft(), &rRect.SSize(), true ) : 0;
3333 2 : if ( pTmpPage )
3334 2 : pPage = pTmpPage;
3335 : }
3336 :
3337 115 : return pPage;
3338 : }
3339 :
3340 226100 : class SwFrmHolder : private SfxListener
3341 : {
3342 : SwFrm* pFrm;
3343 : bool bSet;
3344 : virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
3345 : public:
3346 226100 : SwFrmHolder() : pFrm(0), bSet(false) {}
3347 : void SetFrm( SwFrm* pHold );
3348 22 : SwFrm* GetFrm() { return pFrm; }
3349 : void Reset();
3350 84373 : bool IsSet() { return bSet; }
3351 : };
3352 :
3353 22 : void SwFrmHolder::SetFrm( SwFrm* pHold )
3354 : {
3355 22 : bSet = true;
3356 22 : pFrm = pHold;
3357 22 : StartListening(*pHold);
3358 22 : }
3359 :
3360 310451 : void SwFrmHolder::Reset()
3361 : {
3362 310451 : if (pFrm)
3363 0 : EndListening(*pFrm);
3364 310451 : bSet = false;
3365 310451 : pFrm = 0;
3366 310451 : }
3367 :
3368 0 : void SwFrmHolder::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
3369 : {
3370 0 : if ( rHint.IsA(TYPE(SfxSimpleHint)) )
3371 : {
3372 0 : if ( ( (SfxSimpleHint&) rHint ).GetId() == SFX_HINT_DYING && &rBC == pFrm )
3373 0 : pFrm = 0;
3374 : }
3375 0 : }
3376 :
3377 226100 : SwFrm* GetFrmOfModify( const SwRootFrm* pLayout, SwModify const& rMod, sal_uInt16 const nFrmType,
3378 : const Point* pPoint, const SwPosition *pPos, const sal_Bool bCalcFrm )
3379 : {
3380 226100 : SwFrm *pMinFrm = 0, *pTmpFrm;
3381 226100 : SwFrmHolder aHolder;
3382 226100 : SwRect aCalcRect;
3383 226100 : bool bClientIterChanged = false;
3384 :
3385 452200 : SwIterator<SwFrm,SwModify> aIter( rMod );
3386 226100 : do {
3387 226100 : pMinFrm = 0;
3388 226100 : aHolder.Reset();
3389 226100 : sal_uInt64 nMinDist = 0;
3390 226100 : bClientIterChanged = false;
3391 :
3392 290231 : for( pTmpFrm = aIter.First(); pTmpFrm; pTmpFrm = aIter.Next() )
3393 : {
3394 759903 : if( pTmpFrm->GetType() & nFrmType &&
3395 982501 : ( !pLayout || pLayout == pTmpFrm->getRootFrm() ) &&
3396 506393 : (!pTmpFrm->IsFlowFrm() ||
3397 253092 : !SwFlowFrm::CastFlowFrm( pTmpFrm )->IsFollow() ))
3398 : {
3399 222983 : if( pPoint )
3400 : {
3401 : // watch for Frm being deleted
3402 84373 : if ( pMinFrm )
3403 22 : aHolder.SetFrm( pMinFrm );
3404 : else
3405 84351 : aHolder.Reset();
3406 :
3407 84373 : if( bCalcFrm )
3408 : {
3409 : // - format parent Writer
3410 : // fly frame, if it isn't been formatted yet.
3411 : // Note: The Writer fly frame could be the frame itself.
3412 3117 : SwFlyFrm* pFlyFrm( pTmpFrm->FindFlyFrm() );
3413 3117 : if ( pFlyFrm &&
3414 3117 : pFlyFrm->Frm().Pos().X() == FAR_AWAY &&
3415 0 : pFlyFrm->Frm().Pos().Y() == FAR_AWAY )
3416 : {
3417 0 : SwObjectFormatter::FormatObj( *pFlyFrm );
3418 : }
3419 3117 : pTmpFrm->Calc();
3420 : }
3421 :
3422 : // #127369#
3423 : // aIter.IsChanged checks if the current pTmpFrm has been deleted while
3424 : // it is the current iterator
3425 : // FrmHolder watches for deletion of the current pMinFrm
3426 84373 : if( aIter.IsChanged() || ( aHolder.IsSet() && !aHolder.GetFrm() ) )
3427 : {
3428 : // restart iteration
3429 0 : bClientIterChanged = true;
3430 50560 : break;
3431 : }
3432 :
3433 : // bei Flys ggfs. ueber den Parent gehen wenn sie selbst
3434 : // nocht nicht "formatiert" sind
3435 165735 : if( !bCalcFrm && nFrmType & FRM_FLY &&
3436 211 : ((SwFlyFrm*)pTmpFrm)->GetAnchorFrm() &&
3437 84478 : FAR_AWAY == pTmpFrm->Frm().Pos().getX() &&
3438 0 : FAR_AWAY == pTmpFrm->Frm().Pos().getY() )
3439 0 : aCalcRect = ((SwFlyFrm*)pTmpFrm)->GetAnchorFrm()->Frm();
3440 : else
3441 84373 : aCalcRect = pTmpFrm->Frm();
3442 :
3443 84373 : if ( aCalcRect.IsInside( *pPoint ) )
3444 : {
3445 50560 : pMinFrm = pTmpFrm;
3446 50560 : break;
3447 : }
3448 :
3449 : // Point not in rectangle. Compare distances:
3450 33813 : const Point aCalcRectCenter = aCalcRect.Center();
3451 33813 : const Point aDiff = aCalcRectCenter - *pPoint;
3452 33813 : const sal_uInt64 nCurrentDist = aDiff.getX() * aDiff.getX() + aDiff.getY() * aDiff.getY(); // opt: no sqrt
3453 33813 : if ( !pMinFrm || nCurrentDist < nMinDist )
3454 : {
3455 33791 : pMinFrm = pTmpFrm;
3456 33791 : nMinDist = nCurrentDist;
3457 : }
3458 : }
3459 : else
3460 : {
3461 : // Wenn kein pPoint angegeben ist, dann reichen
3462 : // wir irgendeinen raus: den ersten!
3463 138610 : pMinFrm = pTmpFrm;
3464 138610 : break;
3465 : }
3466 : }
3467 : }
3468 : } while( bClientIterChanged );
3469 :
3470 226100 : if( pPos && pMinFrm && pMinFrm->IsTxtFrm() )
3471 84040 : return ((SwTxtFrm*)pMinFrm)->GetFrmAtPos( *pPos );
3472 :
3473 368160 : return pMinFrm;
3474 : }
3475 :
3476 44237 : bool IsExtraData( const SwDoc *pDoc )
3477 : {
3478 44237 : const SwLineNumberInfo &rInf = pDoc->GetLineNumberInfo();
3479 88436 : return rInf.IsPaintLineNumbers() ||
3480 88573 : rInf.IsCountInFlys() ||
3481 88398 : ((sal_Int16)SW_MOD()->GetRedlineMarkPos() != text::HoriOrientation::NONE &&
3482 88436 : !pDoc->GetRedlineTbl().empty());
3483 : }
3484 :
3485 : // OD 22.09.2003 #110978#
3486 9 : const SwRect SwPageFrm::PrtWithoutHeaderAndFooter() const
3487 : {
3488 9 : SwRect aPrtWithoutHeaderFooter( Prt() );
3489 9 : aPrtWithoutHeaderFooter.Pos() += Frm().Pos();
3490 :
3491 9 : const SwFrm* pLowerFrm = Lower();
3492 27 : while ( pLowerFrm )
3493 : {
3494 : // Note: independent on text direction page header and page footer are
3495 : // always at top respectively at bottom of the page frame.
3496 9 : if ( pLowerFrm->IsHeaderFrm() )
3497 : {
3498 0 : aPrtWithoutHeaderFooter.Top( aPrtWithoutHeaderFooter.Top() +
3499 0 : pLowerFrm->Frm().Height() );
3500 : }
3501 9 : if ( pLowerFrm->IsFooterFrm() )
3502 : {
3503 0 : aPrtWithoutHeaderFooter.Bottom( aPrtWithoutHeaderFooter.Bottom() -
3504 0 : pLowerFrm->Frm().Height() );
3505 : }
3506 :
3507 9 : pLowerFrm = pLowerFrm->GetNext();
3508 : }
3509 :
3510 9 : return aPrtWithoutHeaderFooter;
3511 : }
3512 :
3513 : /** method to determine the spacing values of a frame
3514 :
3515 : OD 2004-03-10 #i28701#
3516 : OD 2009-08-28 #i102458#
3517 : Add output parameter <obIsLineSpacingProportional>
3518 :
3519 : @author OD
3520 : */
3521 3971 : void GetSpacingValuesOfFrm( const SwFrm& rFrm,
3522 : SwTwips& onLowerSpacing,
3523 : SwTwips& onLineSpacing,
3524 : bool& obIsLineSpacingProportional )
3525 : {
3526 3971 : if ( !rFrm.IsFlowFrm() )
3527 : {
3528 0 : onLowerSpacing = 0;
3529 0 : onLineSpacing = 0;
3530 : }
3531 : else
3532 : {
3533 3971 : const SvxULSpaceItem& rULSpace = rFrm.GetAttrSet()->GetULSpace();
3534 3971 : onLowerSpacing = rULSpace.GetLower();
3535 :
3536 3971 : onLineSpacing = 0;
3537 3971 : obIsLineSpacingProportional = false;
3538 3971 : if ( rFrm.IsTxtFrm() )
3539 : {
3540 3640 : onLineSpacing = static_cast<const SwTxtFrm&>(rFrm).GetLineSpace();
3541 : obIsLineSpacingProportional =
3542 4014 : onLineSpacing != 0 &&
3543 4014 : static_cast<const SwTxtFrm&>(rFrm).GetLineSpace( true ) == 0;
3544 : }
3545 :
3546 : OSL_ENSURE( onLowerSpacing >= 0 && onLineSpacing >= 0,
3547 : "<GetSpacingValuesOfFrm(..)> - spacing values aren't positive!" );
3548 : }
3549 3971 : }
3550 :
3551 : /** method to get the content of the table cell, skipping content from nested tables
3552 : */
3553 1 : const SwCntntFrm* GetCellCntnt( const SwLayoutFrm& rCell )
3554 : {
3555 1 : const SwCntntFrm* pCntnt = rCell.ContainsCntnt();
3556 1 : const SwTabFrm* pTab = rCell.FindTabFrm();
3557 :
3558 2 : while ( pCntnt && rCell.IsAnLower( pCntnt ) )
3559 : {
3560 1 : const SwTabFrm* pTmpTab = pCntnt->FindTabFrm();
3561 1 : if ( pTmpTab != pTab )
3562 : {
3563 0 : pCntnt = pTmpTab->FindLastCntnt();
3564 0 : if ( pCntnt )
3565 :
3566 0 : pCntnt = pCntnt->FindNextCnt();
3567 :
3568 : }
3569 : else
3570 1 : break;
3571 : }
3572 1 : return pCntnt;
3573 : }
3574 :
3575 : /** Can be used to check if a frame has been deleted
3576 : */
3577 1 : bool SwDeletionChecker::HasBeenDeleted()
3578 : {
3579 1 : if ( !mpFrm || !mpRegIn )
3580 0 : return false;
3581 :
3582 1 : SwIterator<SwFrm,SwModify> aIter(*mpRegIn);
3583 1 : SwFrm* pLast = aIter.First();
3584 2 : while ( pLast )
3585 : {
3586 1 : if ( pLast == mpFrm )
3587 1 : return false;
3588 0 : pLast = aIter.Next();
3589 : }
3590 :
3591 0 : return true;
3592 99 : }
3593 :
3594 :
3595 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|