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 <svx/svdmodel.hxx>
21 : #include <svx/svdpage.hxx>
22 : #include <editeng/brushitem.hxx>
23 : #include <editeng/shaditem.hxx>
24 : #include <editeng/ulspitem.hxx>
25 : #include <editeng/boxitem.hxx>
26 : #include <editeng/lspcitem.hxx>
27 :
28 : #include <drawdoc.hxx>
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 : #include <DocumentSettingManager.hxx>
65 : #include <IDocumentTimerAccess.hxx>
66 : #include <IDocumentRedlineAccess.hxx>
67 : #include <IDocumentFieldsAccess.hxx>
68 : #include <IDocumentState.hxx>
69 :
70 : //UUUU
71 : #include <svx/sdr/attribute/sdrallfillattributeshelper.hxx>
72 :
73 : using namespace ::com::sun::star;
74 :
75 : bool bObjsDirect = true;
76 : bool bDontCreateObjects = false;
77 : bool bSetCompletePaintOnInvalidate = false;
78 :
79 : sal_uInt8 StackHack::nCnt = 0;
80 : bool StackHack::bLocked = false;
81 :
82 304559 : SwFrmNotify::SwFrmNotify( SwFrm *pF ) :
83 : pFrm( pF ),
84 304559 : aFrm( pF->Frm() ),
85 304559 : aPrt( pF->Prt() ),
86 : bInvaKeep( false ),
87 304559 : bValidSize( pF->GetValidSizeFlag() ),
88 1218236 : mbFrmDeleted( false ) // #i49383#
89 : {
90 304559 : if ( pF->IsTxtFrm() )
91 : {
92 131023 : mnFlyAnchorOfst = ((SwTxtFrm*)pF)->GetBaseOfstForFly( true );
93 131023 : mnFlyAnchorOfstNoWrap = ((SwTxtFrm*)pF)->GetBaseOfstForFly( false );
94 : }
95 : else
96 : {
97 173536 : mnFlyAnchorOfst = 0;
98 173536 : mnFlyAnchorOfstNoWrap = 0;
99 : }
100 :
101 438931 : bHadFollow = pF->IsCntntFrm() ?
102 134372 : (((SwCntntFrm*)pF)->GetFollow() ? sal_True : sal_False) :
103 304559 : sal_False;
104 304559 : }
105 :
106 304559 : SwFrmNotify::~SwFrmNotify()
107 : {
108 : // #i49383#
109 304559 : if ( mbFrmDeleted )
110 : {
111 0 : return;
112 : }
113 :
114 304559 : SWRECTFN( pFrm )
115 304559 : const bool bAbsP = POS_DIFF( aFrm, pFrm->Frm() );
116 : const bool bChgWidth =
117 304559 : (aFrm.*fnRect->fnGetWidth)() != (pFrm->Frm().*fnRect->fnGetWidth)();
118 : const bool bChgHeight =
119 304559 : (aFrm.*fnRect->fnGetHeight)()!=(pFrm->Frm().*fnRect->fnGetHeight)();
120 435720 : const bool bChgFlyBasePos = pFrm->IsTxtFrm() &&
121 261992 : ( ( mnFlyAnchorOfst != ((SwTxtFrm*)pFrm)->GetBaseOfstForFly( true ) ) ||
122 435528 : ( mnFlyAnchorOfstNoWrap != ((SwTxtFrm*)pFrm)->GetBaseOfstForFly( false ) ) );
123 :
124 304559 : if ( pFrm->IsFlowFrm() && !pFrm->IsInFtn() )
125 : {
126 142988 : SwFlowFrm *pFlow = SwFlowFrm::CastFlowFrm( pFrm );
127 :
128 142988 : if ( !pFlow->IsFollow() )
129 : {
130 138979 : if ( !pFrm->GetIndPrev() )
131 : {
132 81009 : if ( bInvaKeep )
133 : {
134 7228 : SwFrm *pPre = pFrm->FindPrev();
135 7228 : if ( pPre && pPre->IsFlowFrm() )
136 : {
137 : // 1. pPre wants to keep with me:
138 2616 : bool bInvalidPrePos = SwFlowFrm::CastFlowFrm( pPre )->IsKeep( *pPre->GetAttrSet() ) && pPre->GetIndPrev();
139 :
140 : // 2. pPre is a table and the last row wants to keep with me:
141 2616 : if ( !bInvalidPrePos && pPre->IsTabFrm() )
142 : {
143 356 : SwTabFrm* pPreTab = static_cast<SwTabFrm*>(pPre);
144 356 : if ( pPreTab->GetFmt()->GetDoc()->GetDocumentSettingManager().get(IDocumentSettingAccess::TABLE_ROW_KEEP) )
145 : {
146 342 : SwRowFrm* pLastRow = static_cast<SwRowFrm*>(pPreTab->GetLastLower());
147 342 : if ( pLastRow && pLastRow->ShouldRowKeepWithNext() )
148 0 : bInvalidPrePos = true;
149 : }
150 : }
151 :
152 2616 : if ( bInvalidPrePos )
153 58 : pPre->InvalidatePos();
154 : }
155 : }
156 : }
157 57970 : else if ( !pFlow->HasFollow() )
158 : {
159 57069 : long nOldHeight = (aFrm.*fnRect->fnGetHeight)();
160 57069 : long nNewHeight = (pFrm->Frm().*fnRect->fnGetHeight)();
161 57069 : if( (nOldHeight > nNewHeight) || (!nOldHeight && nNewHeight) )
162 31340 : pFlow->CheckKeep();
163 : }
164 : }
165 : }
166 :
167 304559 : if ( bAbsP )
168 : {
169 177489 : pFrm->SetCompletePaint();
170 :
171 177489 : SwFrm* pNxt = pFrm->GetIndNext();
172 : // #121888# - skip empty section frames
173 436346 : while ( pNxt &&
174 182123 : pNxt->IsSctFrm() && !static_cast<SwSectionFrm*>(pNxt)->GetSection() )
175 : {
176 1886 : pNxt = pNxt->GetIndNext();
177 : }
178 :
179 177489 : if ( pNxt )
180 77596 : pNxt->InvalidatePos();
181 : else
182 : {
183 : // #104100# - correct condition for setting retouche
184 : // flag for vertical layout.
185 157864 : if( pFrm->IsRetoucheFrm() &&
186 57971 : (aFrm.*fnRect->fnTopDist)( (pFrm->Frm().*fnRect->fnGetTop)() ) > 0 )
187 : {
188 21050 : pFrm->SetRetouche();
189 : }
190 :
191 : // A fresh follow frame does not have to be invalidated, because
192 : // it is already formatted:
193 99893 : if ( bHadFollow || !pFrm->IsCntntFrm() || !((SwCntntFrm*)pFrm)->GetFollow() )
194 : {
195 99497 : if ( !pFrm->IsTabFrm() || !((SwTabFrm*)pFrm)->GetFollow() )
196 99363 : pFrm->InvalidateNextPos();
197 : }
198 : }
199 : }
200 :
201 : //For each resize of the background graphics is a repaint necessary.
202 : const bool bPrtWidth =
203 304559 : (aPrt.*fnRect->fnGetWidth)() != (pFrm->Prt().*fnRect->fnGetWidth)();
204 : const bool bPrtHeight =
205 304559 : (aPrt.*fnRect->fnGetHeight)()!=(pFrm->Prt().*fnRect->fnGetHeight)();
206 304559 : if ( bPrtWidth || bPrtHeight )
207 : {
208 : //UUUU
209 141221 : bool bUseNewFillProperties(false);
210 141221 : if (pFrm->supportsFullDrawingLayerFillAttributeSet())
211 : {
212 110985 : drawinglayer::attribute::SdrAllFillAttributesHelperPtr aFillAttributes(pFrm->getSdrAllFillAttributesHelper());
213 110985 : if(aFillAttributes.get() && aFillAttributes->isUsed())
214 : {
215 2492 : bUseNewFillProperties = true;
216 : //UUUU use SetCompletePaint if needed
217 2492 : if(aFillAttributes->needCompleteRepaint())
218 : {
219 40 : pFrm->SetCompletePaint();
220 : }
221 110985 : }
222 : }
223 141221 : if (!bUseNewFillProperties)
224 : {
225 138729 : const SvxGraphicPosition ePos = pFrm->GetAttrSet()->GetBackground().GetGraphicPos();
226 138729 : if(GPOS_NONE != ePos && GPOS_TILED != ePos)
227 14 : pFrm->SetCompletePaint();
228 141221 : }
229 : }
230 : else
231 : {
232 : // #97597# - consider case that *only* margins between
233 : // frame and printing area has changed. Then, frame has to be repainted,
234 : // in order to force paint of the margin areas.
235 163338 : if ( !bAbsP && (bChgWidth || bChgHeight) )
236 : {
237 622 : pFrm->SetCompletePaint();
238 : }
239 : }
240 :
241 304559 : const bool bPrtP = POS_DIFF( aPrt, pFrm->Prt() );
242 304559 : if ( bAbsP || bPrtP || bChgWidth || bChgHeight ||
243 110444 : bPrtWidth || bPrtHeight || bChgFlyBasePos )
244 : {
245 206615 : if( pFrm->IsAccessibleFrm() )
246 : {
247 158565 : SwRootFrm *pRootFrm = pFrm->getRootFrm();
248 158569 : if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
249 4 : pRootFrm->GetCurrShell() )
250 : {
251 4 : pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( pFrm, aFrm );
252 : }
253 : }
254 :
255 : // Notification of anchored objects
256 206615 : if ( pFrm->GetDrawObjs() )
257 : {
258 5704 : const SwSortedObjs &rObjs = *pFrm->GetDrawObjs();
259 5704 : SwPageFrm* pPageFrm = 0;
260 14829 : for ( size_t i = 0; i < rObjs.size(); ++i )
261 : {
262 : // OD 2004-03-31 #i26791# - no general distinction between
263 : // Writer fly frames and drawing objects
264 9125 : bool bNotify = false;
265 9125 : bool bNotifySize = false;
266 9125 : SwAnchoredObject* pObj = rObjs[i];
267 9125 : SwContact* pContact = ::GetUserCall( pObj->GetDrawObj() );
268 : // #115759#
269 9125 : const bool bAnchoredAsChar = pContact->ObjAnchoredAsChar();
270 9125 : if ( !bAnchoredAsChar )
271 : {
272 : // Notify object, which aren't anchored as-character:
273 :
274 : // always notify objects, if frame position has changed
275 : // or if the object is to-page|to-fly anchored.
276 7108 : if ( bAbsP ||
277 7056 : pContact->ObjAnchoredAtPage() ||
278 913 : pContact->ObjAnchoredAtFly() )
279 : {
280 5236 : bNotify = true;
281 :
282 : // assure that to-fly anchored Writer fly frames are
283 : // registered at the correct page frame, if frame
284 : // position has changed.
285 5286 : if ( bAbsP && pContact->ObjAnchoredAtFly() &&
286 50 : pObj->ISA(SwFlyFrm) )
287 : {
288 : // determine to-fly anchored Writer fly frame
289 0 : SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
290 : // determine page frame of to-fly anchored
291 : // Writer fly frame
292 0 : SwPageFrm* pFlyPageFrm = pFlyFrm->FindPageFrm();
293 : // determine page frame, if needed.
294 0 : if ( !pPageFrm )
295 : {
296 0 : pPageFrm = pFrm->FindPageFrm();
297 : }
298 0 : if ( pPageFrm != pFlyPageFrm )
299 : {
300 : OSL_ENSURE( pFlyPageFrm, "~SwFrmNotify: Fly from Nowhere" );
301 0 : if( pFlyPageFrm )
302 0 : pFlyPageFrm->MoveFly( pFlyFrm, pPageFrm );
303 : else
304 0 : pPageFrm->AppendFlyToPage( pFlyFrm );
305 : }
306 : }
307 : }
308 : // otherwise the objects are notified in dependence to
309 : // its positioning and alignment
310 : else
311 : {
312 : const SwFmtVertOrient& rVert =
313 907 : pContact->GetFmt()->GetVertOrient();
314 2511 : if ( ( rVert.GetVertOrient() == text::VertOrientation::CENTER ||
315 1388 : rVert.GetVertOrient() == text::VertOrientation::BOTTOM ||
316 2040 : rVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA ) &&
317 0 : ( bChgHeight || bPrtHeight ) )
318 : {
319 221 : bNotify = true;
320 : }
321 907 : if ( !bNotify )
322 : {
323 : const SwFmtHoriOrient& rHori =
324 686 : pContact->GetFmt()->GetHoriOrient();
325 2000 : if ( ( rHori.GetHoriOrient() != text::HoriOrientation::NONE ||
326 1256 : rHori.GetRelationOrient()== text::RelOrientation::PRINT_AREA ||
327 1938 : rHori.GetRelationOrient()== text::RelOrientation::FRAME ) &&
328 536 : ( bChgWidth || bPrtWidth || bChgFlyBasePos ) )
329 : {
330 88 : bNotify = true;
331 : }
332 : }
333 : }
334 : }
335 2982 : else if ( bPrtWidth )
336 : {
337 : // Notify as-character anchored objects, if printing area
338 : // width has changed.
339 1964 : bNotify = true;
340 1964 : bNotifySize = true;
341 : }
342 :
343 : // perform notification via the corresponding invalidations
344 9125 : if ( bNotify )
345 : {
346 7509 : if ( pObj->ISA(SwFlyFrm) )
347 : {
348 4105 : SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
349 4105 : if ( bNotifySize )
350 1432 : pFlyFrm->_InvalidateSize();
351 : // #115759# - no invalidation of
352 : // position for as-character anchored objects.
353 4105 : if ( !bAnchoredAsChar )
354 : {
355 2673 : pFlyFrm->_InvalidatePos();
356 : }
357 4105 : pFlyFrm->_Invalidate();
358 : }
359 3404 : else if ( pObj->ISA(SwAnchoredDrawObject) )
360 : {
361 : // #115759# - no invalidation of
362 : // position for as-character anchored objects.
363 3404 : if ( !bAnchoredAsChar )
364 : {
365 2872 : pObj->InvalidateObjPos();
366 : }
367 : }
368 : else
369 : {
370 : OSL_FAIL( "<SwCntntNotify::~SwCntntNotify()> - unknown anchored object type. Please inform OD." );
371 : }
372 : }
373 : }
374 206615 : }
375 : }
376 97944 : else if( pFrm->IsTxtFrm() && bValidSize != pFrm->GetValidSizeFlag() )
377 : {
378 39815 : SwRootFrm *pRootFrm = pFrm->getRootFrm();
379 39815 : if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
380 0 : pRootFrm->GetCurrShell() )
381 : {
382 0 : pRootFrm->GetCurrShell()->Imp()->InvalidateAccessibleFrmContent( pFrm );
383 : }
384 : }
385 :
386 : // #i9046# Automatic frame width
387 304559 : SwFlyFrm* pFly = 0;
388 : // #i35879# Do not trust the inf flags. pFrm does not
389 : // necessarily have to have an upper!
390 304559 : if ( !pFrm->IsFlyFrm() && 0 != ( pFly = pFrm->ImplFindFlyFrm() ) )
391 : {
392 : // #i61999#
393 : // no invalidation of columned Writer fly frames, because automatic
394 : // width doesn't make sense for such Writer fly frames.
395 13988 : if ( pFly->Lower() && !pFly->Lower()->IsColumnFrm() )
396 : {
397 13988 : const SwFmtFrmSize &rFrmSz = pFly->GetFmt()->GetFrmSize();
398 :
399 : // This could be optimized. Basically the fly frame only has to
400 : // be invalidated, if the first line of pFrm (if pFrm is a content
401 : // frame, for other frame types its the print area) has changed its
402 : // size and pFrm was responsible for the current width of pFly. On
403 : // the other hand, this is only rarely used and re-calculation of
404 : // the fly frame does not cause too much trouble. So we keep it this
405 : // way:
406 13988 : if ( ATT_FIX_SIZE != rFrmSz.GetWidthSizeType() )
407 : {
408 : // #i50668#, #i50998# - invalidation of position
409 : // of as-character anchored fly frames not needed and can cause
410 : // layout loops
411 486 : if ( !pFly->ISA(SwFlyInCntFrm) )
412 : {
413 486 : pFly->InvalidatePos();
414 : }
415 486 : pFly->InvalidateSize();
416 : }
417 : }
418 : }
419 609118 : }
420 :
421 170187 : SwLayNotify::SwLayNotify( SwLayoutFrm *pLayFrm ) :
422 : SwFrmNotify( pLayFrm ),
423 170187 : bLowersComplete( false )
424 : {
425 170187 : }
426 :
427 : // OD 2004-05-11 #i28701# - local method to invalidate the position of all
428 : // frames inclusive its floating screen objects, which are lowers of the given
429 : // layout frame
430 396 : static void lcl_InvalidatePosOfLowers( SwLayoutFrm& _rLayoutFrm )
431 : {
432 396 : if( _rLayoutFrm.IsFlyFrm() && _rLayoutFrm.GetDrawObjs() )
433 : {
434 0 : _rLayoutFrm.InvalidateObjs( true, false );
435 : }
436 :
437 396 : SwFrm* pLowerFrm = _rLayoutFrm.Lower();
438 1274 : while ( pLowerFrm )
439 : {
440 482 : pLowerFrm->InvalidatePos();
441 482 : if ( pLowerFrm->IsTxtFrm() )
442 : {
443 474 : static_cast<SwTxtFrm*>(pLowerFrm)->Prepare( PREP_POS_CHGD );
444 : }
445 8 : else if ( pLowerFrm->IsTabFrm() )
446 : {
447 0 : pLowerFrm->InvalidatePrt();
448 : }
449 :
450 482 : pLowerFrm->InvalidateObjs( true, false );
451 :
452 482 : pLowerFrm = pLowerFrm->GetNext();
453 : }
454 396 : }
455 :
456 340374 : SwLayNotify::~SwLayNotify()
457 : {
458 : // #i49383#
459 170187 : if ( mbFrmDeleted )
460 : {
461 0 : return;
462 : }
463 :
464 170187 : SwLayoutFrm *pLay = GetLay();
465 170187 : SWRECTFN( pLay )
466 170187 : bool bNotify = false;
467 170187 : if ( pLay->Prt().SSize() != aPrt.SSize() )
468 : {
469 68820 : if ( !IsLowersComplete() )
470 : {
471 : bool bInvaPercent;
472 :
473 68742 : if ( pLay->IsRowFrm() )
474 : {
475 6248 : bInvaPercent = true;
476 6248 : long nNew = (pLay->Prt().*fnRect->fnGetHeight)();
477 6248 : if( nNew != (aPrt.*fnRect->fnGetHeight)() )
478 5532 : ((SwRowFrm*)pLay)->AdjustCells( nNew, true);
479 12496 : if( (pLay->Prt().*fnRect->fnGetWidth)()
480 6248 : != (aPrt.*fnRect->fnGetWidth)() )
481 5862 : ((SwRowFrm*)pLay)->AdjustCells( 0, false );
482 : }
483 : else
484 : {
485 : //Proportional adoption of the internal.
486 : //1. If the formatted is no Fly
487 : //2. If he contains no columns
488 : //3. If the Fly has a fixed hight and the columns
489 : // are next to be.
490 : // Hoehe danebenliegen.
491 : //4. Never at SectionFrms.
492 : bool bLow;
493 62494 : if( pLay->IsFlyFrm() )
494 : {
495 4906 : if ( pLay->Lower() )
496 : {
497 4898 : bLow = !pLay->Lower()->IsColumnFrm() ||
498 0 : (pLay->Lower()->Frm().*fnRect->fnGetHeight)()
499 4898 : != (pLay->Prt().*fnRect->fnGetHeight)();
500 : }
501 : else
502 8 : bLow = false;
503 : }
504 57588 : else if( pLay->IsSctFrm() )
505 : {
506 348 : if ( pLay->Lower() )
507 : {
508 348 : if( pLay->Lower()->IsColumnFrm() && pLay->Lower()->GetNext() )
509 152 : bLow = pLay->Lower()->Frm().Height() != pLay->Prt().Height();
510 : else
511 196 : bLow = pLay->Prt().Width() != aPrt.Width();
512 : }
513 : else
514 0 : bLow = false;
515 : }
516 57240 : else if( pLay->IsFooterFrm() && !pLay->HasFixSize() )
517 1964 : bLow = pLay->Prt().Width() != aPrt.Width();
518 : else
519 55276 : bLow = true;
520 62494 : bInvaPercent = bLow;
521 62494 : if ( bLow )
522 : {
523 62174 : pLay->ChgLowersProp( aPrt.SSize() );
524 : }
525 : // If the PrtArea has been extended, it might be possible that the chain of parts
526 : // can take another frame. As a result, the "possible right one" needs to be
527 : // invalidated. This only pays off if this or its Uppers are moveable sections.
528 : // A PrtArea has been extended if width or height are larger than before.
529 145356 : if ( (pLay->Prt().Height() > aPrt.Height() ||
530 119338 : pLay->Prt().Width() > aPrt.Width()) &&
531 100430 : (pLay->IsMoveable() || pLay->IsFlyFrm()) )
532 : {
533 6046 : SwFrm *pTmpFrm = pLay->Lower();
534 6046 : if ( pTmpFrm && pTmpFrm->IsFlowFrm() )
535 : {
536 10956 : while ( pTmpFrm->GetNext() )
537 1160 : pTmpFrm = pTmpFrm->GetNext();
538 4898 : pTmpFrm->InvalidateNextPos();
539 : }
540 : }
541 : }
542 68742 : bNotify = true;
543 : //EXPENSIVE!! But how we do it more elegant?
544 68742 : if( bInvaPercent )
545 68422 : pLay->InvaPercentLowers( pLay->Prt().Height() - aPrt.Height() );
546 : }
547 68820 : if ( pLay->IsTabFrm() )
548 : //So that _only_ the shadow is drawn while resizing.
549 1700 : ((SwTabFrm*)pLay)->SetComplete();
550 : else
551 : {
552 67120 : const SwViewShell *pSh = pLay->getRootFrm()->GetCurrShell();
553 67222 : if( !( pSh && pSh->GetViewOptions()->getBrowseMode() ) ||
554 102 : !(pLay->GetType() & (FRM_BODY | FRM_PAGE)) )
555 : //Thereby the subordinates are retouched clean.
556 : //Example problem: Take the Flys with the handles and downsize.
557 : //Not for body and page, otherwise it flickers when loading HTML.
558 67044 : pLay->SetCompletePaint();
559 : }
560 : }
561 : //Notify Lower if the position has changed.
562 170187 : const bool bPrtPos = POS_DIFF( aPrt, pLay->Prt() );
563 170187 : const bool bPos = bPrtPos || POS_DIFF( aFrm, pLay->Frm() );
564 170187 : const bool bSize = pLay->Frm().SSize() != aFrm.SSize();
565 :
566 170187 : if ( bPos && pLay->Lower() && !IsLowersComplete() )
567 84708 : pLay->Lower()->InvalidatePos();
568 :
569 170187 : if ( bPrtPos )
570 25884 : pLay->SetCompletePaint();
571 :
572 : //Inform the Follower if the SSize has changed.
573 170187 : if ( bSize )
574 : {
575 31986 : if( pLay->GetNext() )
576 : {
577 17876 : if ( pLay->GetNext()->IsLayoutFrm() )
578 15890 : pLay->GetNext()->_InvalidatePos();
579 : else
580 1986 : pLay->GetNext()->InvalidatePos();
581 : }
582 14110 : else if( pLay->IsSctFrm() )
583 274 : pLay->InvalidateNextPos();
584 : }
585 510477 : if ( !IsLowersComplete() &&
586 186906 : !(pLay->GetType()&(FRM_FLY|FRM_SECTION) &&
587 33574 : pLay->Lower() && pLay->Lower()->IsColumnFrm()) &&
588 237988 : (bPos || bNotify) && !(pLay->GetType() & 0x1823) ) //Tab, Row, FtnCont, Root, Page
589 : {
590 : // #i44016# - force unlock of position of lower objects.
591 : // #i43913# - no unlock of position of objects,
592 : // if <pLay> is a cell frame, and its table frame resp. its parent table
593 : // frame is locked.
594 : // #i47458# - force unlock of position of lower objects,
595 : // only if position of layout frame has changed.
596 84764 : bool bUnlockPosOfObjs( bPos );
597 84764 : if ( bUnlockPosOfObjs && pLay->IsCellFrm() )
598 : {
599 47124 : SwTabFrm* pTabFrm( pLay->FindTabFrm() );
600 125932 : if ( pTabFrm &&
601 62564 : ( pTabFrm->IsJoinLocked() ||
602 16310 : ( pTabFrm->IsFollow() &&
603 870 : pTabFrm->FindMaster()->IsJoinLocked() ) ) )
604 : {
605 31684 : bUnlockPosOfObjs = false;
606 : }
607 : }
608 : // #i49383# - check for footnote frame, if unlock
609 : // of position of lower objects is allowed.
610 37640 : else if ( bUnlockPosOfObjs && pLay->IsFtnFrm() )
611 : {
612 396 : bUnlockPosOfObjs = static_cast<SwFtnFrm*>(pLay)->IsUnlockPosOfLowerObjs();
613 : }
614 : // #i51303# - no unlock of object positions for sections
615 37244 : else if ( bUnlockPosOfObjs && pLay->IsSctFrm() )
616 : {
617 604 : bUnlockPosOfObjs = false;
618 : }
619 84764 : pLay->NotifyLowerObjs( bUnlockPosOfObjs );
620 : }
621 170187 : if ( bPos && pLay->IsFtnFrm() && pLay->Lower() )
622 : {
623 : // OD 2004-05-11 #i28701#
624 396 : ::lcl_InvalidatePosOfLowers( *pLay );
625 : }
626 238086 : if( ( bPos || bSize ) && pLay->IsFlyFrm() && ((SwFlyFrm*)pLay)->GetAnchorFrm()
627 178175 : && ((SwFlyFrm*)pLay)->GetAnchorFrm()->IsFlyFrm() )
628 0 : ((SwFlyFrm*)pLay)->AnchorFrm()->InvalidateSize();
629 170187 : }
630 :
631 15269 : SwFlyNotify::SwFlyNotify( SwFlyFrm *pFlyFrm ) :
632 : SwLayNotify( pFlyFrm ),
633 : // #115759# - keep correct page frame - the page frame
634 : // the Writer fly frame is currently registered at.
635 15269 : pOldPage( pFlyFrm->GetPageFrm() ),
636 30538 : aFrmAndSpace( pFlyFrm->GetObjRectWithSpaces() )
637 : {
638 15269 : }
639 :
640 30538 : SwFlyNotify::~SwFlyNotify()
641 : {
642 : // #i49383#
643 15269 : if ( mbFrmDeleted )
644 : {
645 0 : return;
646 : }
647 :
648 15269 : SwFlyFrm *pFly = GetFly();
649 15269 : if ( pFly->IsNotifyBack() )
650 : {
651 9077 : SwViewShell *pSh = pFly->getRootFrm()->GetCurrShell();
652 9077 : SwViewImp *pImp = pSh ? pSh->Imp() : 0;
653 9077 : if ( !pImp || !pImp->IsAction() || !pImp->GetLayAction().IsAgain() )
654 : {
655 : //If in the LayAction the IsAgain is set it can be
656 : //that the old page is destroyed in the meantime!
657 9045 : ::Notify( pFly, pOldPage, aFrmAndSpace, &aPrt );
658 : // #i35640# - additional notify anchor text frame,
659 : // if Writer fly frame has changed its page
660 17862 : if ( pFly->GetAnchorFrm()->IsTxtFrm() &&
661 8817 : pFly->GetPageFrm() != pOldPage )
662 : {
663 32 : pFly->AnchorFrm()->Prepare( PREP_FLY_LEAVE );
664 : }
665 : }
666 9077 : pFly->ResetNotifyBack();
667 : }
668 :
669 : //Have the size or the position changed,
670 : //so should the view know this.
671 15269 : SWRECTFN( pFly )
672 15269 : const bool bPosChgd = POS_DIFF( aFrm, pFly->Frm() );
673 15269 : const bool bFrmChgd = pFly->Frm().SSize() != aFrm.SSize();
674 15269 : const bool bPrtChgd = aPrt != pFly->Prt();
675 15269 : if ( bPosChgd || bFrmChgd || bPrtChgd )
676 : {
677 7994 : pFly->NotifyDrawObj();
678 : }
679 15269 : if ( bPosChgd && aFrm.Pos().X() != FAR_AWAY )
680 : {
681 : // OD 2004-05-10 #i28701# - no direct move of lower Writer fly frames.
682 : // reason: New positioning and alignment (e.g. to-paragraph anchored,
683 : // but aligned at page) are introduced.
684 : // <SwLayNotify::~SwLayNotify()> takes care of invalidation of lower
685 : // floating screen objects by calling method <SwLayoutFrm::NotifyLowerObjs()>.
686 :
687 3138 : if ( pFly->IsFlyAtCntFrm() )
688 : {
689 516 : SwFrm *pNxt = pFly->AnchorFrm()->FindNext();
690 516 : if ( pNxt )
691 : {
692 396 : pNxt->InvalidatePos();
693 : }
694 : }
695 :
696 : // #i26945# - notify anchor.
697 : // Needed for negative positioned Writer fly frames
698 3138 : if ( pFly->GetAnchorFrm()->IsTxtFrm() )
699 : {
700 3132 : pFly->AnchorFrm()->Prepare( PREP_FLY_LEAVE );
701 : }
702 : }
703 :
704 : // OD 2004-05-13 #i28701#
705 : // #i45180# - no adjustment of layout process flags and
706 : // further notifications/invalidations, if format is called by grow/shrink
707 18463 : if ( pFly->ConsiderObjWrapInfluenceOnObjPos() &&
708 3952 : ( !pFly->ISA(SwFlyFreeFrm) ||
709 1976 : !static_cast<SwFlyFreeFrm*>(pFly)->IsNoMoveOnCheckClip() ) )
710 : {
711 : // #i54138# - suppress restart of the layout process
712 : // on changed frame height.
713 : // Note: It doesn't seem to be necessary and can cause layout loops.
714 1218 : if ( bPosChgd )
715 : {
716 : // indicate a restart of the layout process
717 552 : pFly->SetRestartLayoutProcess( true );
718 : }
719 : else
720 : {
721 : // lock position
722 666 : pFly->LockPosition();
723 :
724 666 : if ( !pFly->ConsiderForTextWrap() )
725 : {
726 : // indicate that object has to be considered for text wrap
727 614 : pFly->SetConsiderForTextWrap( true );
728 : // invalidate 'background' in order to allow its 'background'
729 : // to wrap around it.
730 : pFly->NotifyBackground( pFly->GetPageFrm(),
731 614 : pFly->GetObjRectWithSpaces(),
732 1228 : PREP_FLY_ARRIVE );
733 : // invalidate position of anchor frame in order to force
734 : // a re-format of the anchor frame, which also causes a
735 : // re-format of the invalid previous frames of the anchor frame.
736 614 : pFly->AnchorFrm()->InvalidatePos();
737 : }
738 : }
739 : }
740 15269 : }
741 :
742 134372 : SwCntntNotify::SwCntntNotify( SwCntntFrm *pCntntFrm ) :
743 : SwFrmNotify( pCntntFrm ),
744 : // OD 08.01.2004 #i11859#
745 : mbChkHeightOfLastLine( false ),
746 : mnHeightOfLastLine( 0L ),
747 : // OD 2004-02-26 #i25029#
748 : mbInvalidatePrevPrtArea( false ),
749 134372 : mbBordersJoinedWithPrev( false )
750 : {
751 : // OD 08.01.2004 #i11859#
752 134372 : if ( pCntntFrm->IsTxtFrm() )
753 : {
754 131023 : SwTxtFrm* pTxtFrm = static_cast<SwTxtFrm*>(pCntntFrm);
755 131023 : if ( !pTxtFrm->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::OLD_LINE_SPACING) )
756 : {
757 130973 : const SwAttrSet* pSet = pTxtFrm->GetAttrSet();
758 130973 : const SvxLineSpacingItem &rSpace = pSet->GetLineSpacing();
759 130973 : if ( rSpace.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_PROP )
760 : {
761 17808 : mbChkHeightOfLastLine = true;
762 17808 : mnHeightOfLastLine = pTxtFrm->GetHeightOfLastLine();
763 : }
764 : }
765 : }
766 134372 : }
767 :
768 268744 : SwCntntNotify::~SwCntntNotify()
769 : {
770 : // #i49383#
771 134372 : if ( mbFrmDeleted )
772 : {
773 0 : return;
774 : }
775 :
776 134372 : SwCntntFrm *pCnt = GetCnt();
777 134372 : if ( bSetCompletePaintOnInvalidate )
778 1960 : pCnt->SetCompletePaint();
779 :
780 134372 : SWRECTFN( pCnt )
781 151282 : if ( pCnt->IsInTab() && ( POS_DIFF( pCnt->Frm(), aFrm ) ||
782 16910 : pCnt->Frm().SSize() != aFrm.SSize()))
783 : {
784 29862 : SwLayoutFrm* pCell = pCnt->GetUpper();
785 59728 : while( !pCell->IsCellFrm() && pCell->GetUpper() )
786 4 : pCell = pCell->GetUpper();
787 : OSL_ENSURE( pCell->IsCellFrm(), "Where's my cell?" );
788 29862 : if ( text::VertOrientation::NONE != pCell->GetFmt()->GetVertOrient().GetVertOrient() )
789 7090 : pCell->InvalidatePrt(); //for the vertical allign.
790 : }
791 :
792 : // OD 2004-02-26 #i25029#
793 138196 : if ( mbInvalidatePrevPrtArea && mbBordersJoinedWithPrev &&
794 948 : pCnt->IsTxtFrm() &&
795 135320 : !pCnt->IsFollow() && !pCnt->GetIndPrev() )
796 : {
797 : // determine previous frame
798 474 : SwFrm* pPrevFrm = pCnt->FindPrev();
799 : // skip empty section frames and hidden text frames
800 : {
801 1420 : while ( pPrevFrm &&
802 472 : ( ( pPrevFrm->IsSctFrm() &&
803 472 : !static_cast<SwSectionFrm*>(pPrevFrm)->GetSection() ) ||
804 944 : ( pPrevFrm->IsTxtFrm() &&
805 472 : static_cast<SwTxtFrm*>(pPrevFrm)->IsHiddenNow() ) ) )
806 : {
807 0 : pPrevFrm = pPrevFrm->FindPrev();
808 : }
809 : }
810 :
811 : // Invalidate printing area of found previous frame
812 474 : if ( pPrevFrm )
813 : {
814 472 : if ( pPrevFrm->IsSctFrm() )
815 : {
816 0 : if ( pCnt->IsInSct() )
817 : {
818 : // Note: found previous frame is a section frame and
819 : // <pCnt> is also inside a section.
820 : // Thus due to <mbBordersJoinedWithPrev>,
821 : // <pCnt> had joined its borders/shadow with the
822 : // last content of the found section.
823 : // Invalidate printing area of last content in found section.
824 : SwFrm* pLstCntntOfSctFrm =
825 0 : static_cast<SwSectionFrm*>(pPrevFrm)->FindLastCntnt();
826 0 : if ( pLstCntntOfSctFrm )
827 : {
828 0 : pLstCntntOfSctFrm->InvalidatePrt();
829 : }
830 : }
831 : }
832 : else
833 : {
834 472 : pPrevFrm->InvalidatePrt();
835 : }
836 : }
837 : }
838 :
839 134372 : const bool bFirst = (aFrm.*fnRect->fnGetWidth)() == 0;
840 :
841 134372 : if ( pCnt->IsNoTxtFrm() )
842 : {
843 : //Active PlugIn's or OLE-Objects should know something of the change
844 : //thereby they move their window appropriate.
845 3349 : SwViewShell *pSh = pCnt->getRootFrm()->GetCurrShell();
846 3349 : if ( pSh )
847 : {
848 : SwOLENode *pNd;
849 6649 : if ( 0 != (pNd = pCnt->GetNode()->GetOLENode()) &&
850 1650 : (pNd->GetOLEObj().IsOleRef() ||
851 0 : pNd->IsOLESizeInvalid()) )
852 : {
853 : const bool bNoTxtFrmPrtAreaChanged =
854 2460 : ( aPrt.SSize().Width() != 0 &&
855 2460 : aPrt.SSize().Height() != 0 ) &&
856 2460 : aPrt.SSize() != pCnt->Prt().SSize();
857 : OSL_ENSURE( pCnt->IsInFly(), "OLE not in FlyFrm" );
858 1650 : SwFlyFrm *pFly = pCnt->FindFlyFrm();
859 1650 : svt::EmbeddedObjectRef& xObj = pNd->GetOLEObj().GetObject();
860 1650 : SwFEShell *pFESh = 0;
861 1650 : SwViewShell *pTmp = pSh;
862 1650 : do
863 1650 : { if ( pTmp->ISA( SwCrsrShell ) )
864 : {
865 1632 : pFESh = (SwFEShell*)pTmp;
866 : // #108369#: Here used to be the condition if (!bFirst).
867 : // I think this should mean "do not call CalcAndSetScale"
868 : // if the frame is formatted for the first time.
869 : // Unfortunately this is not valid anymore since the
870 : // SwNoTxtFrm already gets a width during CalcLowerPreps.
871 : // Nevertheless, the indention of !bFirst seemed to be
872 : // to assure that the OLE objects have already been notified
873 : // if necessary before calling CalcAndSetScale.
874 : // So I replaced !bFirst by !IsOLESizeInvalid. There is
875 : // one additional problem specific to the word import:
876 : // The layout is calculated _before_ calling PrtOLENotify,
877 : // and the OLE objects are not invalidated during import.
878 : // Therefore I added the condition !IsUpdateExpFld,
879 : // have a look at the occurrence of CalcLayout in
880 : // uiview/view.cxx.
881 3250 : if ( !pNd->IsOLESizeInvalid() &&
882 1618 : !pSh->GetDoc()->getIDocumentState().IsUpdateExpFld() )
883 : pFESh->CalcAndSetScale( xObj,
884 1618 : &pFly->Prt(), &pFly->Frm(),
885 3236 : bNoTxtFrmPrtAreaChanged );
886 : }
887 1650 : pTmp = (SwViewShell*)pTmp->GetNext();
888 : } while ( pTmp != pSh );
889 :
890 1650 : if ( pFESh && pNd->IsOLESizeInvalid() )
891 : {
892 14 : pNd->SetOLESizeInvalid( false );
893 14 : pFESh->CalcAndSetScale( xObj ); // create client
894 : }
895 : }
896 : //dito animated graphics
897 3349 : if ( Frm().HasArea() && ((SwNoTxtFrm*)pCnt)->HasAnimation() )
898 : {
899 0 : ((SwNoTxtFrm*)pCnt)->StopAnimation();
900 0 : pSh->InvalidateWindows( Frm() );
901 : }
902 : }
903 : }
904 :
905 134372 : if ( bFirst )
906 : {
907 57903 : pCnt->SetRetouche(); //fix(13870)
908 :
909 57903 : SwDoc *pDoc = pCnt->GetNode()->GetDoc();
910 145534 : if ( !pDoc->GetSpzFrmFmts()->empty() &&
911 57903 : pDoc->DoesContainAtPageObjWithContentAnchor() && !pDoc->getIDocumentState().IsNewDoc() )
912 : {
913 : // If certain import filters for foreign file format import
914 : // AT_PAGE anchored objects, the corresponding page number is
915 : // typically not known. In this case the content position is
916 : // stored at which the anchored object is found in the
917 : // imported document.
918 : // When this content is formatted it is the time at which
919 : // the page is known. Thus, this data can be corrected now.
920 :
921 0 : const SwPageFrm *pPage = 0;
922 0 : SwNodeIndex *pIdx = 0;
923 0 : SwFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
924 :
925 0 : for ( sal_uInt16 i = 0; i < pTbl->size(); ++i )
926 : {
927 0 : SwFrmFmt *pFmt = (*pTbl)[i];
928 0 : const SwFmtAnchor &rAnch = pFmt->GetAnchor();
929 0 : if ( FLY_AT_PAGE != rAnch.GetAnchorId() ||
930 0 : rAnch.GetCntntAnchor() == 0 )
931 : {
932 0 : continue;
933 : }
934 :
935 0 : if ( !pIdx )
936 : {
937 0 : pIdx = new SwNodeIndex( *pCnt->GetNode() );
938 : }
939 0 : if ( rAnch.GetCntntAnchor()->nNode == *pIdx )
940 : {
941 : OSL_FAIL( "<SwCntntNotify::~SwCntntNotify()> - to page anchored object with content position. Please inform OD." );
942 0 : if ( !pPage )
943 : {
944 0 : pPage = pCnt->FindPageFrm();
945 : }
946 0 : SwFmtAnchor aAnch( rAnch );
947 0 : aAnch.SetAnchor( 0 );
948 0 : aAnch.SetPageNum( pPage->GetPhyPageNum() );
949 0 : pFmt->SetFmtAttr( aAnch );
950 0 : if ( RES_DRAWFRMFMT != pFmt->Which() )
951 : {
952 0 : pFmt->MakeFrms();
953 0 : }
954 : }
955 : }
956 0 : delete pIdx;
957 : }
958 : }
959 :
960 : // OD 12.01.2004 #i11859# - invalidate printing area of following frame,
961 : // if height of last line has changed.
962 134372 : if ( pCnt->IsTxtFrm() && mbChkHeightOfLastLine )
963 : {
964 17808 : if ( mnHeightOfLastLine != static_cast<SwTxtFrm*>(pCnt)->GetHeightOfLastLine() )
965 : {
966 9984 : pCnt->InvalidateNextPrtArea();
967 : }
968 : }
969 :
970 : // #i44049#
971 134372 : if ( pCnt->IsTxtFrm() && POS_DIFF( aFrm, pCnt->Frm() ) )
972 : {
973 79539 : pCnt->InvalidateObjs( true );
974 : }
975 :
976 : // #i43255# - move code to invalidate at-character
977 : // anchored objects due to a change of its anchor character from
978 : // method <SwTxtFrm::Format(..)>.
979 134372 : if ( pCnt->IsTxtFrm() )
980 : {
981 131023 : SwTxtFrm* pMasterFrm = pCnt->IsFollow()
982 3193 : ? static_cast<SwTxtFrm*>(pCnt)->FindMaster()
983 134216 : : static_cast<SwTxtFrm*>(pCnt);
984 262046 : if ( pMasterFrm && !pMasterFrm->IsFlyLock() &&
985 131023 : pMasterFrm->GetDrawObjs() )
986 : {
987 13686 : SwSortedObjs* pObjs = pMasterFrm->GetDrawObjs();
988 130736 : for ( size_t i = 0; i < pObjs->size(); ++i )
989 : {
990 117050 : SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
991 117050 : if ( pAnchoredObj->GetFrmFmt().GetAnchor().GetAnchorId()
992 : == FLY_AT_CHAR )
993 : {
994 3508 : pAnchoredObj->CheckCharRectAndTopOfLine( !pMasterFrm->IsEmpty() );
995 : }
996 : }
997 : }
998 : }
999 134372 : }
1000 :
1001 25362 : void AppendObjs( const SwFrmFmts *pTbl, sal_uLong nIndex,
1002 : SwFrm *pFrm, SwPageFrm *pPage )
1003 : {
1004 204208 : for ( sal_uInt16 i = 0; i < pTbl->size(); ++i )
1005 : {
1006 178846 : SwFrmFmt *pFmt = (SwFrmFmt*)(*pTbl)[i];
1007 178846 : const SwFmtAnchor &rAnch = pFmt->GetAnchor();
1008 339906 : if ( rAnch.GetCntntAnchor() &&
1009 161060 : (rAnch.GetCntntAnchor()->nNode.GetIndex() == nIndex) )
1010 : {
1011 2930 : const bool bFlyAtFly = rAnch.GetAnchorId() == FLY_AT_FLY; // LAYER_IMPL
1012 : //Is a frame or a SdrObject described?
1013 2930 : const bool bSdrObj = RES_DRAWFRMFMT == pFmt->Which();
1014 : // OD 23.06.2003 #108784# - append also drawing objects anchored
1015 : // as character.
1016 4472 : const bool bDrawObjInCntnt = bSdrObj &&
1017 4472 : (rAnch.GetAnchorId() == FLY_AS_CHAR);
1018 :
1019 5844 : if( bFlyAtFly ||
1020 4264 : (rAnch.GetAnchorId() == FLY_AT_PARA) ||
1021 5032 : (rAnch.GetAnchorId() == FLY_AT_CHAR) ||
1022 : bDrawObjInCntnt )
1023 : {
1024 2488 : SdrObject* pSdrObj = 0;
1025 2488 : if ( bSdrObj && 0 == (pSdrObj = pFmt->FindSdrObject()) )
1026 : {
1027 : OSL_ENSURE( !bSdrObj, "DrawObject not found." );
1028 0 : pFmt->GetDoc()->DelFrmFmt( pFmt );
1029 0 : --i;
1030 0 : continue;
1031 : }
1032 2488 : if ( pSdrObj )
1033 : {
1034 1542 : if ( !pSdrObj->GetPage() )
1035 : {
1036 0 : pFmt->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)->
1037 0 : InsertObject(pSdrObj, pSdrObj->GetOrdNumDirect());
1038 : }
1039 :
1040 : SwDrawContact* pNew =
1041 1542 : static_cast<SwDrawContact*>(GetUserCall( pSdrObj ));
1042 1542 : if ( !pNew->GetAnchorFrm() )
1043 : {
1044 1116 : pFrm->AppendDrawObj( *(pNew->GetAnchoredObj( 0L )) );
1045 : }
1046 : // OD 19.06.2003 #108784# - add 'virtual' drawing object,
1047 : // if necessary. But control objects have to be excluded.
1048 1278 : else if ( !::CheckControlLayer( pSdrObj ) &&
1049 852 : pNew->GetAnchorFrm() != pFrm &&
1050 426 : !pNew->GetDrawObjectByAnchorFrm( *pFrm ) )
1051 : {
1052 426 : SwDrawVirtObj* pDrawVirtObj = pNew->AddVirtObj();
1053 426 : pFrm->AppendDrawObj( *(pNew->GetAnchoredObj( pDrawVirtObj )) );
1054 :
1055 426 : pDrawVirtObj->ActionChanged();
1056 : }
1057 :
1058 : }
1059 : else
1060 : {
1061 : SwFlyFrm *pFly;
1062 946 : if( bFlyAtFly )
1063 0 : pFly = new SwFlyLayFrm( (SwFlyFrmFmt*)pFmt, pFrm, pFrm );
1064 : else
1065 946 : pFly = new SwFlyAtCntFrm( (SwFlyFrmFmt*)pFmt, pFrm, pFrm );
1066 946 : pFly->Lock();
1067 946 : pFrm->AppendFly( pFly );
1068 946 : pFly->Unlock();
1069 946 : if ( pPage )
1070 170 : ::RegistFlys( pPage, pFly );
1071 : }
1072 : }
1073 : }
1074 : }
1075 25362 : }
1076 :
1077 6494 : static bool lcl_ObjConnected( SwFrmFmt *pFmt, const SwFrm* pSib )
1078 : {
1079 6494 : SwIterator<SwFlyFrm,SwFmt> aIter( *pFmt );
1080 6494 : if ( RES_FLYFRMFMT == pFmt->Which() )
1081 : {
1082 2994 : const SwRootFrm* pRoot = pSib ? pSib->getRootFrm() : 0;
1083 : const SwFlyFrm* pTmpFrm;
1084 2994 : for( pTmpFrm = aIter.First(); pTmpFrm; pTmpFrm = aIter.Next() )
1085 : {
1086 1736 : if(! pRoot || pRoot == pTmpFrm->getRootFrm() )
1087 1736 : return true;
1088 : }
1089 : }
1090 : else
1091 : {
1092 3500 : SwDrawContact *pContact = SwIterator<SwDrawContact,SwFmt>::FirstElement(*pFmt);
1093 3500 : if ( pContact )
1094 3500 : return pContact->GetAnchorFrm() != 0;
1095 : }
1096 1258 : return false;
1097 : }
1098 :
1099 : /** helper method to determine, if a <SwFrmFmt>, which has an object connected,
1100 : is located in header or footer.
1101 :
1102 : OD 23.06.2003 #108784#
1103 : */
1104 1218 : static bool lcl_InHeaderOrFooter( SwFrmFmt& _rFmt )
1105 : {
1106 1218 : bool bRetVal = false;
1107 :
1108 1218 : const SwFmtAnchor& rAnch = _rFmt.GetAnchor();
1109 :
1110 1218 : if (rAnch.GetAnchorId() != FLY_AT_PAGE)
1111 : {
1112 1218 : bRetVal = _rFmt.GetDoc()->IsInHeaderFooter( rAnch.GetCntntAnchor()->nNode );
1113 : }
1114 :
1115 1218 : return bRetVal;
1116 : }
1117 :
1118 5284 : void AppendAllObjs( const SwFrmFmts *pTbl, const SwFrm* pSib )
1119 : {
1120 : //Connecting of all Objects, which are described in the SpzTbl with the
1121 : //layout.
1122 : //If nothing happens anymore we can stop. Then formats can still remain,
1123 : //because we neither use character bound frames nor objects which
1124 : //are anchored to character bounds.
1125 :
1126 5284 : SwFrmFmts aCpy( *pTbl );
1127 :
1128 5284 : sal_uInt16 nOldCnt = USHRT_MAX;
1129 :
1130 12596 : while ( !aCpy.empty() && aCpy.size() != nOldCnt )
1131 : {
1132 2028 : nOldCnt = aCpy.size();
1133 7360 : for ( int i = 0; i < int(aCpy.size()); ++i )
1134 : {
1135 5332 : SwFrmFmt *pFmt = (SwFrmFmt*)aCpy[ sal_uInt16(i) ];
1136 5332 : const SwFmtAnchor &rAnch = pFmt->GetAnchor();
1137 5332 : bool bRemove = false;
1138 10590 : if ((rAnch.GetAnchorId() == FLY_AT_PAGE) ||
1139 5258 : (rAnch.GetAnchorId() == FLY_AS_CHAR))
1140 : {
1141 : //Page bounded are already anchored, character bounded
1142 : //I don't want here.
1143 1684 : bRemove = true;
1144 : }
1145 4866 : else if ( false == (bRemove = ::lcl_ObjConnected( pFmt, pSib )) ||
1146 1218 : ::lcl_InHeaderOrFooter( *pFmt ) )
1147 : {
1148 : // OD 23.06.2003 #108784# - correction: for objects in header
1149 : // or footer create frames, in spite of the fact that an connected
1150 : // objects already exists.
1151 : //Call for Flys and DrawObjs only a MakeFrms if nor
1152 : //no dependent exists, otherwise, or if the MakeDrms creates no
1153 : //dependents, remove.
1154 2846 : pFmt->MakeFrms();
1155 2846 : bRemove = ::lcl_ObjConnected( pFmt, pSib );
1156 : }
1157 5332 : if ( bRemove )
1158 : {
1159 5152 : aCpy.erase( aCpy.begin() + i );
1160 5152 : --i;
1161 : }
1162 : }
1163 : }
1164 5284 : aCpy.clear();
1165 5284 : }
1166 :
1167 : /** local method to set 'working' position for newly inserted frames
1168 :
1169 : OD 12.08.2003 #i17969#
1170 : */
1171 62252 : static void lcl_SetPos( SwFrm& _rNewFrm,
1172 : const SwLayoutFrm& _rLayFrm )
1173 : {
1174 62252 : SWRECTFN( (&_rLayFrm) )
1175 62252 : (_rNewFrm.Frm().*fnRect->fnSetPos)( (_rLayFrm.Frm().*fnRect->fnGetPos)() );
1176 : // move position by one SwTwip in text flow direction in order to get
1177 : // notifications for a new calculated position after its formatting.
1178 62252 : if ( bVert )
1179 4 : _rNewFrm.Frm().Pos().X() -= 1;
1180 : else
1181 62248 : _rNewFrm.Frm().Pos().Y() += 1;
1182 62252 : }
1183 :
1184 30892 : void _InsertCnt( SwLayoutFrm *pLay, SwDoc *pDoc,
1185 : sal_uLong nIndex, bool bPages, sal_uLong nEndIndex,
1186 : SwFrm *pPrv )
1187 : {
1188 30892 : pDoc->getIDocumentTimerAccess().BlockIdling();
1189 30892 : SwRootFrm* pLayout = pLay->getRootFrm();
1190 30892 : const bool bOldCallbackActionEnabled = pLayout ? pLayout->IsCallbackActionEnabled() : sal_False;
1191 30892 : if( bOldCallbackActionEnabled )
1192 3610 : pLayout->SetCallbackActionEnabled( false );
1193 :
1194 : //In the generation of the Layout will be bPage with sal_True handed over.
1195 : //Then will be new pages generated all x paragraphs already times in advance.
1196 : //On breaks and/or pagedescriptorchanges the correspondig will be generated
1197 : //immediately.
1198 : //The advantage is, that on one hand already a nearly realistic number of
1199 : //pages are created, but above all there are no almost endless long chain
1200 : //of paragraphs, which must be moved expensively until it reaches a tolarable
1201 : //reduced level.
1202 : //We'd like to think that 20 Paragraphs fit on one page.
1203 : //So that it does not become in extremly situations so violent we calculate depending
1204 : //on the node something to it.
1205 : //If in the DocStatistik a usable given pagenumber
1206 : //(Will be cared for while writing), so it will be presumed that this will be
1207 : //number of pages.
1208 30892 : const bool bStartPercent = bPages && !nEndIndex;
1209 :
1210 30892 : SwPageFrm *pPage = pLay->FindPageFrm();
1211 30892 : const SwFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
1212 30892 : SwFrm *pFrm = 0;
1213 30892 : bool bBreakAfter = false;
1214 :
1215 30892 : SwActualSection *pActualSection = 0;
1216 : SwLayHelper *pPageMaker;
1217 :
1218 : //If the layout will be created (bPages == sal_True) we do head on the progress
1219 : //Flys and DrawObjekte are not connected immediately, this
1220 : //happens only at the end of the function.
1221 30892 : if ( bPages )
1222 : {
1223 : // Attention: the SwLayHelper class uses references to the content-,
1224 : // page-, layout-frame etc. and may change them!
1225 : pPageMaker = new SwLayHelper( pDoc, pFrm, pPrv, pPage, pLay,
1226 5266 : pActualSection, bBreakAfter, nIndex, 0 == nEndIndex );
1227 5266 : if( bStartPercent )
1228 : {
1229 5266 : const sal_uLong nPageCount = pPageMaker->CalcPageCount();
1230 5266 : if( nPageCount )
1231 1848 : bObjsDirect = false;
1232 : }
1233 : }
1234 : else
1235 25626 : pPageMaker = NULL;
1236 :
1237 30904 : if( pLay->IsInSct() &&
1238 6 : ( pLay->IsSctFrm() || pLay->GetUpper() ) ) // Hereby will newbies
1239 : // be intercepted, of which flags could not determined yet,
1240 : // for e.g. while inserting a table
1241 : {
1242 6 : SwSectionFrm* pSct = pLay->FindSctFrm();
1243 : // If content will be inserted in a footnote, which in an column area,
1244 : // the column area it is not allowed to be broken up.
1245 : // Only if in the inner of the footnote lies an area, is this a candidate
1246 : // for pActualSection.
1247 : // The same applies for areas in tables, if inside the table will be
1248 : // something inserted, it's only allowed to break up areas, which
1249 : // lies in the inside also.
1250 18 : if( ( !pLay->IsInFtn() || pSct->IsInFtn() ) &&
1251 6 : ( !pLay->IsInTab() || pSct->IsInTab() ) )
1252 : {
1253 6 : pActualSection = new SwActualSection( 0, pSct, 0 );
1254 : OSL_ENSURE( !pLay->Lower() || !pLay->Lower()->IsColumnFrm(),
1255 : "_InsertCnt: Wrong Call" );
1256 : }
1257 : }
1258 :
1259 : //If a section is "open", the pActualSection points to an SwActualSection.
1260 : //If the page breaks, for "open" sections a follow will created.
1261 : //For nested sections (which have, however, not a nested layout),
1262 : //the SwActualSection class has a member, which points to an upper(section).
1263 : //When the "inner" section finishs, the upper will used instead.
1264 :
1265 : while( true )
1266 : {
1267 97360 : SwNode *pNd = pDoc->GetNodes()[nIndex];
1268 97360 : if ( pNd->IsCntntNode() )
1269 : {
1270 60416 : SwCntntNode* pNode = (SwCntntNode*)pNd;
1271 60416 : pFrm = pNode->MakeFrm(pLay);
1272 60416 : if( pPageMaker )
1273 29288 : pPageMaker->CheckInsert( nIndex );
1274 :
1275 60416 : pFrm->InsertBehind( pLay, pPrv );
1276 : // #i27138#
1277 : // notify accessibility paragraphs objects about changed
1278 : // CONTENT_FLOWS_FROM/_TO relation.
1279 : // Relation CONTENT_FLOWS_FROM for next paragraph will change
1280 : // and relation CONTENT_FLOWS_TO for previous paragraph will change.
1281 60416 : if ( pFrm->IsTxtFrm() )
1282 : {
1283 58550 : SwViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
1284 : // no notification, if <SwViewShell> is in construction
1285 120226 : if ( pViewShell && !pViewShell->IsInConstructor() &&
1286 64818 : pViewShell->GetLayout() &&
1287 3134 : pViewShell->GetLayout()->IsAnyShellAccessible() )
1288 : {
1289 : pViewShell->InvalidateAccessibleParaFlowRelation(
1290 0 : dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
1291 0 : dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
1292 : // #i68958#
1293 : // The information flags of the text frame are validated
1294 : // in methods <FindNextCnt(..)> and <FindPrevCnt(..)>.
1295 : // The information flags have to be invalidated, because
1296 : // it is possible, that the one of its upper frames
1297 : // isn't inserted into the layout.
1298 0 : pFrm->InvalidateInfFlags();
1299 : }
1300 : }
1301 : // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
1302 : // for setting position at newly inserted frame
1303 60416 : lcl_SetPos( *pFrm, *pLay );
1304 60416 : pPrv = pFrm;
1305 :
1306 60416 : if ( !pTbl->empty() && bObjsDirect && !bDontCreateObjects )
1307 22644 : AppendObjs( pTbl, nIndex, pFrm, pPage );
1308 : }
1309 36944 : else if ( pNd->IsTableNode() )
1310 : { //Should we have encountered a table?
1311 1170 : SwTableNode *pTblNode = (SwTableNode*)pNd;
1312 :
1313 : // #108116# loading may produce table structures that GCLines
1314 : // needs to clean up. To keep table formulas correct, change
1315 : // all table formulas to internal (BOXPTR) representation.
1316 1170 : SwTableFmlUpdate aMsgHnt( &pTblNode->GetTable() );
1317 1170 : aMsgHnt.eFlags = TBL_BOXPTR;
1318 1170 : pDoc->getIDocumentFieldsAccess().UpdateTblFlds( &aMsgHnt );
1319 1170 : pTblNode->GetTable().GCLines();
1320 :
1321 1170 : pFrm = pTblNode->MakeFrm( pLay );
1322 :
1323 1170 : if( pPageMaker )
1324 784 : pPageMaker->CheckInsert( nIndex );
1325 :
1326 1170 : pFrm->InsertBehind( pLay, pPrv );
1327 : // #i27138#
1328 : // notify accessibility paragraphs objects about changed
1329 : // CONTENT_FLOWS_FROM/_TO relation.
1330 : // Relation CONTENT_FLOWS_FROM for next paragraph will change
1331 : // and relation CONTENT_FLOWS_TO for previous paragraph will change.
1332 : {
1333 1170 : SwViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
1334 : // no notification, if <SwViewShell> is in construction
1335 2354 : if ( pViewShell && !pViewShell->IsInConstructor() &&
1336 1198 : pViewShell->GetLayout() &&
1337 14 : pViewShell->GetLayout()->IsAnyShellAccessible() )
1338 : {
1339 : pViewShell->InvalidateAccessibleParaFlowRelation(
1340 0 : dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
1341 0 : dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
1342 : }
1343 : }
1344 1170 : if ( bObjsDirect && !pTbl->empty() )
1345 272 : ((SwTabFrm*)pFrm)->RegistFlys();
1346 : // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
1347 : // for setting position at newly inserted frame
1348 1170 : lcl_SetPos( *pFrm, *pLay );
1349 :
1350 1170 : pPrv = pFrm;
1351 : //Set the index to the endnode of the table section.
1352 1170 : nIndex = pTblNode->EndOfSectionIndex();
1353 :
1354 1170 : SwTabFrm* pTmpFrm = (SwTabFrm*)pFrm;
1355 3630 : while ( pTmpFrm )
1356 : {
1357 1290 : pTmpFrm->CheckDirChange();
1358 1290 : pTmpFrm = pTmpFrm->IsFollow() ? pTmpFrm->FindMaster() : NULL;
1359 1170 : }
1360 :
1361 : }
1362 35774 : else if ( pNd->IsSectionNode() )
1363 : {
1364 586 : SwSectionNode *pNode = (SwSectionNode*)pNd;
1365 586 : if( pNode->GetSection().CalcHiddenFlag() )
1366 : // is hidden, skip the area
1367 0 : nIndex = pNode->EndOfSectionIndex();
1368 : else
1369 : {
1370 586 : pFrm = pNode->MakeFrm( pLay );
1371 : pActualSection = new SwActualSection( pActualSection,
1372 586 : (SwSectionFrm*)pFrm, pNode );
1373 586 : if ( pActualSection->GetUpper() )
1374 : {
1375 : //Insert behind the Upper, the "Follow" of the Upper will be
1376 : //generated at the EndNode.
1377 80 : SwSectionFrm *pTmp = pActualSection->GetUpper()->GetSectionFrm();
1378 80 : pFrm->InsertBehind( pTmp->GetUpper(), pTmp );
1379 : // OD 25.03.2003 #108339# - direct initialization of section
1380 : // after insertion in the layout
1381 80 : static_cast<SwSectionFrm*>(pFrm)->Init();
1382 : }
1383 : else
1384 : {
1385 506 : pFrm->InsertBehind( pLay, pPrv );
1386 : // OD 25.03.2003 #108339# - direct initialization of section
1387 : // after insertion in the layout
1388 506 : static_cast<SwSectionFrm*>(pFrm)->Init();
1389 :
1390 : // #i33963#
1391 : // Do not trust the IsInFtn flag. If we are currently
1392 : // building up a table, the upper of pPrv may be a cell
1393 : // frame, but the cell frame does not have an upper yet.
1394 506 : if( pPrv && 0 != pPrv->ImplFindFtnFrm() )
1395 : {
1396 0 : if( pPrv->IsSctFrm() )
1397 0 : pPrv = ((SwSectionFrm*)pPrv)->ContainsCntnt();
1398 0 : if( pPrv && pPrv->IsTxtFrm() )
1399 0 : ((SwTxtFrm*)pPrv)->Prepare( PREP_QUOVADIS, 0, false );
1400 : }
1401 : }
1402 : // #i27138#
1403 : // notify accessibility paragraphs objects about changed
1404 : // CONTENT_FLOWS_FROM/_TO relation.
1405 : // Relation CONTENT_FLOWS_FROM for next paragraph will change
1406 : // and relation CONTENT_FLOWS_TO for previous paragraph will change.
1407 : {
1408 586 : SwViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
1409 : // no notification, if <SwViewShell> is in construction
1410 1274 : if ( pViewShell && !pViewShell->IsInConstructor() &&
1411 790 : pViewShell->GetLayout() &&
1412 102 : pViewShell->GetLayout()->IsAnyShellAccessible() )
1413 : {
1414 : pViewShell->InvalidateAccessibleParaFlowRelation(
1415 0 : dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
1416 0 : dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
1417 : }
1418 : }
1419 586 : pFrm->CheckDirChange();
1420 :
1421 : // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
1422 : // for setting position at newly inserted frame
1423 586 : lcl_SetPos( *pFrm, *pLay );
1424 :
1425 : // OD 20.11.2002 #105405# - no page, no invalidate.
1426 586 : if ( pPage )
1427 : {
1428 : // OD 18.09.2002 #100522#
1429 : // invalidate page in order to force format and paint of
1430 : // inserted section frame
1431 554 : pFrm->InvalidatePage( pPage );
1432 :
1433 : // FME 10.11.2003 #112243#
1434 : // Invalidate fly content flag:
1435 554 : if ( pFrm->IsInFly() )
1436 4 : pPage->InvalidateFlyCntnt();
1437 :
1438 : // OD 14.11.2002 #104684# - invalidate page content in order to
1439 : // force format and paint of section content.
1440 554 : pPage->InvalidateCntnt();
1441 : }
1442 :
1443 586 : pLay = (SwLayoutFrm*)pFrm;
1444 586 : if ( pLay->Lower() && pLay->Lower()->IsLayoutFrm() )
1445 130 : pLay = pLay->GetNextLayoutLeaf();
1446 586 : pPrv = 0;
1447 : }
1448 : }
1449 35188 : else if ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() )
1450 : {
1451 : OSL_ENSURE( pActualSection, "Sectionende ohne Anfang?" );
1452 : OSL_ENSURE( pActualSection->GetSectionNode() == pNd->StartOfSectionNode(),
1453 : "Sectionende mit falschen Start Node?" );
1454 :
1455 : //Close the section, where appropriate activate the surrounding
1456 : //section again.
1457 586 : SwActualSection *pTmp = pActualSection ? pActualSection->GetUpper() : NULL;
1458 586 : delete pActualSection;
1459 586 : pLay = pLay->FindSctFrm();
1460 586 : if ( 0 != (pActualSection = pTmp) )
1461 : {
1462 : //Could be, that the last SectionFrm remains empty.
1463 : //Then now is the time to remove them.
1464 80 : if ( !pLay->ContainsCntnt() )
1465 : {
1466 0 : SwFrm *pTmpFrm = pLay;
1467 0 : pLay = pTmpFrm->GetUpper();
1468 0 : pPrv = pTmpFrm->GetPrev();
1469 0 : pTmpFrm->Remove();
1470 0 : delete pTmpFrm;
1471 : }
1472 : else
1473 : {
1474 80 : pPrv = pLay;
1475 80 : pLay = pLay->GetUpper();
1476 : }
1477 :
1478 : // new section frame
1479 80 : pFrm = pActualSection->GetSectionNode()->MakeFrm( pLay );
1480 80 : pFrm->InsertBehind( pLay, pPrv );
1481 80 : static_cast<SwSectionFrm*>(pFrm)->Init();
1482 :
1483 : // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
1484 : // for setting position at newly inserted frame
1485 80 : lcl_SetPos( *pFrm, *pLay );
1486 :
1487 80 : SwSectionFrm* pOuterSectionFrm = pActualSection->GetSectionFrm();
1488 :
1489 : // a follow has to be appended to the new section frame
1490 80 : SwSectionFrm* pFollow = pOuterSectionFrm->GetFollow();
1491 80 : if ( pFollow )
1492 : {
1493 0 : pOuterSectionFrm->SetFollow( NULL );
1494 0 : pOuterSectionFrm->InvalidateSize();
1495 0 : ((SwSectionFrm*)pFrm)->SetFollow( pFollow );
1496 : }
1497 :
1498 : // We don't want to leave empty parts back.
1499 154 : if( ! pOuterSectionFrm->IsColLocked() &&
1500 74 : ! pOuterSectionFrm->ContainsCntnt() )
1501 : {
1502 44 : pOuterSectionFrm->DelEmpty( true );
1503 44 : delete pOuterSectionFrm;
1504 : }
1505 80 : pActualSection->SetSectionFrm( (SwSectionFrm*)pFrm );
1506 :
1507 80 : pLay = (SwLayoutFrm*)pFrm;
1508 80 : if ( pLay->Lower() && pLay->Lower()->IsLayoutFrm() )
1509 0 : pLay = pLay->GetNextLayoutLeaf();
1510 80 : pPrv = 0;
1511 : }
1512 : else
1513 : {
1514 : //Nothing more with sections, it goes on right behind
1515 : //the SectionFrame.
1516 506 : pPrv = pLay;
1517 506 : pLay = pLay->GetUpper();
1518 : }
1519 : }
1520 38398 : else if( pNd->IsStartNode() &&
1521 3796 : SwFlyStartNode == ((SwStartNode*)pNd)->GetStartNodeType() )
1522 : {
1523 3796 : if ( !pTbl->empty() && bObjsDirect && !bDontCreateObjects )
1524 : {
1525 2718 : SwFlyFrm* pFly = pLay->FindFlyFrm();
1526 2718 : if( pFly )
1527 2718 : AppendObjs( pTbl, nIndex, pFly, pPage );
1528 : }
1529 : }
1530 : else
1531 : // Neither Cntnt nor table nor section,
1532 : // so we have to be ready.
1533 30806 : break;
1534 :
1535 66554 : ++nIndex;
1536 : // Do not consider the end node. The caller (section/MakeFrms()) has to ensure that the end
1537 : // of this area is positioned before EndIndex!
1538 66554 : if ( nEndIndex && nIndex >= nEndIndex )
1539 86 : break;
1540 : }
1541 :
1542 30892 : if ( pActualSection )
1543 : {
1544 : // Might happen that an empty (Follow-)Section is left over.
1545 6 : if ( !(pLay = pActualSection->GetSectionFrm())->ContainsCntnt() )
1546 : {
1547 6 : pLay->Remove();
1548 6 : delete pLay;
1549 : }
1550 6 : delete pActualSection;
1551 : }
1552 :
1553 30892 : if ( bPages ) // let the Flys connect to each other
1554 : {
1555 5266 : if ( !bDontCreateObjects )
1556 5266 : AppendAllObjs( pTbl, pLayout );
1557 5266 : bObjsDirect = true;
1558 : }
1559 :
1560 30892 : if( pPageMaker )
1561 : {
1562 5266 : pPageMaker->CheckFlyCache( pPage );
1563 5266 : delete pPageMaker;
1564 5266 : if( pDoc->GetLayoutCache() )
1565 : {
1566 : #ifdef DBG_UTIL
1567 : pDoc->GetLayoutCache()->CompareLayout( *pDoc );
1568 : #endif
1569 28 : pDoc->GetLayoutCache()->ClearImpl();
1570 : }
1571 : }
1572 :
1573 30892 : pDoc->getIDocumentTimerAccess().UnblockIdling();
1574 30892 : if( bOldCallbackActionEnabled )
1575 70078 : pLayout->SetCallbackActionEnabled( bOldCallbackActionEnabled );
1576 30892 : }
1577 :
1578 84 : void MakeFrms( SwDoc *pDoc, const SwNodeIndex &rSttIdx,
1579 : const SwNodeIndex &rEndIdx )
1580 : {
1581 84 : bObjsDirect = false;
1582 :
1583 84 : SwNodeIndex aTmp( rSttIdx );
1584 84 : sal_uLong nEndIdx = rEndIdx.GetIndex();
1585 84 : SwNode* pNd = pDoc->GetNodes().FindPrvNxtFrmNode( aTmp,
1586 168 : pDoc->GetNodes()[ nEndIdx-1 ]);
1587 84 : if ( pNd )
1588 : {
1589 76 : bool bApres = aTmp < rSttIdx;
1590 76 : SwNode2Layout aNode2Layout( *pNd, rSttIdx.GetIndex() );
1591 : SwFrm* pFrm;
1592 228 : while( 0 != (pFrm = aNode2Layout.NextFrm()) )
1593 : {
1594 76 : SwLayoutFrm *pUpper = pFrm->GetUpper();
1595 76 : SwFtnFrm* pFtnFrm = pUpper->FindFtnFrm();
1596 : bool bOldLock, bOldFtn;
1597 76 : if( pFtnFrm )
1598 : {
1599 4 : bOldFtn = pFtnFrm->IsColLocked();
1600 4 : pFtnFrm->ColLock();
1601 : }
1602 : else
1603 72 : bOldFtn = true;
1604 76 : SwSectionFrm* pSct = pUpper->FindSctFrm();
1605 : // Inside of footnotes only those areas are interesting that are inside of them. But
1606 : // not the ones (e.g. column areas) in which are the footnote containers positioned.
1607 : // #109767# Table frame is in section, insert section in cell frame.
1608 76 : if( pSct && ((pFtnFrm && !pSct->IsInFtn()) || pUpper->IsCellFrm()) )
1609 0 : pSct = NULL;
1610 76 : if( pSct )
1611 : { // to prevent pTmp->MoveFwd from destroying the SectionFrm
1612 6 : bOldLock = pSct->IsColLocked();
1613 6 : pSct->ColLock();
1614 : }
1615 : else
1616 70 : bOldLock = true;
1617 :
1618 : // If pFrm cannot be moved, it is not possible to move it to the next page. This applies
1619 : // also for frames (in the first column of a frame pFrm is moveable) and column
1620 : // sections of tables (also here pFrm is moveable).
1621 76 : bool bMoveNext = nEndIdx - rSttIdx.GetIndex() > 120;
1622 212 : bool bAllowMove = !pFrm->IsInFly() && pFrm->IsMoveable() &&
1623 144 : (!pFrm->IsInTab() || pFrm->IsTabFrm() );
1624 76 : if ( bMoveNext && bAllowMove )
1625 : {
1626 0 : SwFrm *pMove = pFrm;
1627 0 : SwFrm *pPrev = pFrm->GetPrev();
1628 0 : SwFlowFrm *pTmp = SwFlowFrm::CastFlowFrm( pMove );
1629 : OSL_ENSURE( pTmp, "Missing FlowFrm" );
1630 :
1631 0 : if ( bApres )
1632 : {
1633 : // The rest of this page should be empty. Thus, the following one has to move to
1634 : // the next page (it might also be located in the following column).
1635 : OSL_ENSURE( !pTmp->HasFollow(), "Follows forbidden" );
1636 0 : pPrev = pFrm;
1637 : // If the surrounding SectionFrm has a "next" one,
1638 : // so this one needs to be moved as well.
1639 0 : pMove = pFrm->GetIndNext();
1640 0 : SwColumnFrm* pCol = (SwColumnFrm*)pFrm->FindColFrm();
1641 0 : if( pCol )
1642 0 : pCol = (SwColumnFrm*)pCol->GetNext();
1643 0 : do
1644 : {
1645 0 : if( pCol && !pMove )
1646 : { // No successor so far, look into the next column
1647 0 : pMove = pCol->ContainsAny();
1648 0 : if( pCol->GetNext() )
1649 0 : pCol = (SwColumnFrm*)pCol->GetNext();
1650 0 : else if( pCol->IsInSct() )
1651 : { // If there is no following column but we are in a column frame,
1652 : // there might be (page) columns outside of it.
1653 0 : pCol = (SwColumnFrm*)pCol->FindSctFrm()->FindColFrm();
1654 0 : if( pCol )
1655 0 : pCol = (SwColumnFrm*)pCol->GetNext();
1656 : }
1657 : else
1658 0 : pCol = NULL;
1659 : }
1660 : // skip invalid SectionFrms
1661 0 : while( pMove && pMove->IsSctFrm() &&
1662 0 : !((SwSectionFrm*)pMove)->GetSection() )
1663 0 : pMove = pMove->GetNext();
1664 0 : } while( !pMove && pCol );
1665 :
1666 0 : if( pMove )
1667 : {
1668 0 : if ( pMove->IsCntntFrm() )
1669 0 : pTmp = (SwCntntFrm*)pMove;
1670 0 : else if ( pMove->IsTabFrm() )
1671 0 : pTmp = (SwTabFrm*)pMove;
1672 0 : else if ( pMove->IsSctFrm() )
1673 : {
1674 0 : pMove = ((SwSectionFrm*)pMove)->ContainsAny();
1675 0 : if( pMove )
1676 0 : pTmp = SwFlowFrm::CastFlowFrm( pMove );
1677 : else
1678 0 : pTmp = NULL;
1679 : }
1680 : }
1681 : else
1682 0 : pTmp = 0;
1683 : }
1684 : else
1685 : {
1686 : OSL_ENSURE( !pTmp->IsFollow(), "Follows really forbidden" );
1687 : // move the _content_ of a section frame
1688 0 : if( pMove->IsSctFrm() )
1689 : {
1690 0 : while( pMove && pMove->IsSctFrm() &&
1691 0 : !((SwSectionFrm*)pMove)->GetSection() )
1692 0 : pMove = pMove->GetNext();
1693 0 : if( pMove && pMove->IsSctFrm() )
1694 0 : pMove = ((SwSectionFrm*)pMove)->ContainsAny();
1695 0 : if( pMove )
1696 0 : pTmp = SwFlowFrm::CastFlowFrm( pMove );
1697 : else
1698 0 : pTmp = NULL;
1699 : }
1700 : }
1701 :
1702 0 : if( pTmp )
1703 : {
1704 0 : SwFrm* pOldUp = pTmp->GetFrm().GetUpper();
1705 : // MoveFwd==sal_True means that we are still on the same page.
1706 : // But since we want to move if possible!
1707 0 : bool bTmpOldLock = pTmp->IsJoinLocked();
1708 0 : pTmp->LockJoin();
1709 0 : while( pTmp->MoveFwd( true, false, true ) )
1710 : {
1711 0 : if( pOldUp == pTmp->GetFrm().GetUpper() )
1712 0 : break;
1713 0 : pOldUp = pTmp->GetFrm().GetUpper();
1714 : }
1715 0 : if( !bTmpOldLock )
1716 0 : pTmp->UnlockJoin();
1717 : }
1718 : ::_InsertCnt( pUpper, pDoc, rSttIdx.GetIndex(),
1719 0 : pFrm->IsInDocBody(), nEndIdx, pPrev );
1720 : }
1721 : else
1722 : {
1723 : bool bSplit;
1724 76 : SwFrm* pPrv = bApres ? pFrm : pFrm->GetPrev();
1725 : // If the section frame is inserted into another one, it must be split.
1726 76 : if( pSct && rSttIdx.GetNode().IsSectionNode() )
1727 : {
1728 6 : bSplit = pSct->SplitSect( pFrm, bApres );
1729 6 : if( !bSplit && !bApres )
1730 : {
1731 0 : pUpper = pSct->GetUpper();
1732 0 : pPrv = pSct->GetPrev();
1733 : }
1734 : }
1735 : else
1736 70 : bSplit = false;
1737 :
1738 : ::_InsertCnt( pUpper, pDoc, rSttIdx.GetIndex(), false,
1739 76 : nEndIdx, pPrv );
1740 : // OD 23.06.2003 #108784# - correction: append objects doesn't
1741 : // depend on value of <bAllowMove>
1742 76 : if( !bDontCreateObjects )
1743 : {
1744 76 : const SwFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
1745 76 : if( !pTbl->empty() )
1746 18 : AppendAllObjs( pTbl, pUpper );
1747 : }
1748 :
1749 : // If nothing was added (e.g. a hidden section), the split must be reversed.
1750 82 : if( bSplit && pSct && pSct->GetNext()
1751 82 : && pSct->GetNext()->IsSctFrm() )
1752 6 : pSct->MergeNext( (SwSectionFrm*)pSct->GetNext() );
1753 76 : if( pFrm->IsInFly() )
1754 4 : pFrm->FindFlyFrm()->_Invalidate();
1755 76 : if( pFrm->IsInTab() )
1756 4 : pFrm->InvalidateSize();
1757 : }
1758 :
1759 76 : SwPageFrm *pPage = pUpper->FindPageFrm();
1760 76 : SwFrm::CheckPageDescs( pPage, false );
1761 76 : if( !bOldFtn )
1762 4 : pFtnFrm->ColUnlock();
1763 76 : if( !bOldLock )
1764 : {
1765 6 : pSct->ColUnlock();
1766 : // pSct might be empty (e.g. when inserting linked section containing further
1767 : // sections) and can be destroyed in such cases.
1768 6 : if( !pSct->ContainsCntnt() )
1769 : {
1770 0 : pSct->DelEmpty( true );
1771 0 : pUpper->getRootFrm()->RemoveFromList( pSct );
1772 0 : delete pSct;
1773 : }
1774 : }
1775 76 : }
1776 : }
1777 :
1778 84 : bObjsDirect = true;
1779 84 : }
1780 :
1781 159507 : SwBorderAttrs::SwBorderAttrs( const SwModify *pMod, const SwFrm *pConstructor ) :
1782 : SwCacheObj( pMod ),
1783 159507 : rAttrSet( pConstructor->IsCntntFrm()
1784 73651 : ? ((SwCntntFrm*)pConstructor)->GetNode()->GetSwAttrSet()
1785 85856 : : ((SwLayoutFrm*)pConstructor)->GetFmt()->GetAttrSet() ),
1786 159507 : rUL ( rAttrSet.GetULSpace() ),
1787 : // #i96772#
1788 : // LRSpaceItem is copied due to the possibility that it is adjusted - see below
1789 159507 : rLR ( rAttrSet.GetLRSpace() ),
1790 159507 : rBox ( rAttrSet.GetBox() ),
1791 159507 : rShadow ( rAttrSet.GetShadow() ),
1792 1116549 : aFrmSize( rAttrSet.GetFrmSize().GetSize() )
1793 : {
1794 : // #i96772#
1795 159507 : const SwTxtFrm* pTxtFrm = dynamic_cast<const SwTxtFrm*>(pConstructor);
1796 159507 : if ( pTxtFrm )
1797 : {
1798 72205 : pTxtFrm->GetTxtNode()->ClearLRSpaceItemDueToListLevelIndents( rLR );
1799 : }
1800 87302 : else if ( pConstructor->IsNoTxtFrm() )
1801 : {
1802 1446 : rLR = SvxLRSpaceItem ( RES_LR_SPACE );
1803 : }
1804 :
1805 : // Caution: The USHORTs for the cached values are not initialized by intention!
1806 :
1807 : // everything needs to be calculated at least once:
1808 : bTopLine = bBottomLine = bLeftLine = bRightLine =
1809 159507 : bTop = bBottom = bLine = true;
1810 :
1811 159507 : bCacheGetLine = bCachedGetTopLine = bCachedGetBottomLine = false;
1812 : // OD 21.05.2003 #108789# - init cache status for values <bJoinedWithPrev>
1813 : // and <bJoinedWithNext>, which aren't initialized by default.
1814 159507 : bCachedJoinedWithPrev = false;
1815 159507 : bCachedJoinedWithNext = false;
1816 :
1817 159507 : bBorderDist = 0 != (pConstructor->GetType() & (FRM_CELL));
1818 159507 : }
1819 :
1820 478521 : SwBorderAttrs::~SwBorderAttrs()
1821 : {
1822 159507 : ((SwModify*)pOwner)->SetInCache( false );
1823 319014 : }
1824 :
1825 : /* All calc methods calculate a safety distance in addition to the values given by the attributes.
1826 : * This safety distance is only added when working with borders and/or shadows to prevent that
1827 : * e.g. borders are painted over.
1828 : */
1829 :
1830 9466 : void SwBorderAttrs::_CalcTop()
1831 : {
1832 9466 : nTop = CalcTopLine() + rUL.GetUpper();
1833 9466 : bTop = false;
1834 9466 : }
1835 :
1836 9466 : void SwBorderAttrs::_CalcBottom()
1837 : {
1838 9466 : nBottom = CalcBottomLine() + rUL.GetLower();
1839 9466 : bBottom = false;
1840 9466 : }
1841 :
1842 442561 : long SwBorderAttrs::CalcRight( const SwFrm* pCaller ) const
1843 : {
1844 442561 : long nRight=0;
1845 :
1846 442561 : if (!pCaller->IsTxtFrm() || !((SwTxtFrm*)pCaller)->GetTxtNode()->GetDoc()->GetDocumentSettingManager().get(IDocumentSettingAccess::INVERT_BORDER_SPACING)) {
1847 : // OD 23.01.2003 #106895# - for cell frame in R2L text direction the left
1848 : // and right border are painted on the right respectively left.
1849 112121 : if ( pCaller->IsCellFrm() && pCaller->IsRightToLeft() )
1850 0 : nRight = CalcLeftLine();
1851 : else
1852 112121 : nRight = CalcRightLine();
1853 :
1854 : }
1855 : // for paragraphs, "left" is "before text" and "right" is "after text"
1856 442561 : if ( pCaller->IsTxtFrm() && pCaller->IsRightToLeft() )
1857 460 : nRight += rLR.GetLeft();
1858 : else
1859 442101 : nRight += rLR.GetRight();
1860 :
1861 : // correction: retrieve left margin for numbering in R2L-layout
1862 442561 : if ( pCaller->IsTxtFrm() && pCaller->IsRightToLeft() )
1863 : {
1864 460 : nRight += ((SwTxtFrm*)pCaller)->GetTxtNode()->GetLeftMarginWithNum();
1865 : }
1866 :
1867 442561 : return nRight;
1868 : }
1869 :
1870 : /// Tries to detect if this paragraph has a floating table attached.
1871 631570 : static bool lcl_hasTabFrm(const SwTxtFrm* pTxtFrm)
1872 : {
1873 631570 : if (pTxtFrm->GetDrawObjs())
1874 : {
1875 43142 : const SwSortedObjs* pSortedObjs = pTxtFrm->GetDrawObjs();
1876 43142 : if (pSortedObjs->size() > 0)
1877 : {
1878 43142 : SwAnchoredObject* pObject = (*pSortedObjs)[0];
1879 43142 : if (pObject->IsA(TYPE(SwFlyFrm)))
1880 : {
1881 28972 : SwFlyFrm* pFly = (SwFlyFrm*)pObject;
1882 28972 : if (pFly->Lower() && pFly->Lower()->IsTabFrm())
1883 842 : return true;
1884 : }
1885 : }
1886 : }
1887 630728 : return false;
1888 : }
1889 :
1890 494827 : long SwBorderAttrs::CalcLeft( const SwFrm *pCaller ) const
1891 : {
1892 494827 : long nLeft=0;
1893 :
1894 494827 : if (!pCaller->IsTxtFrm() || !((SwTxtFrm*)pCaller)->GetTxtNode()->GetDoc()->GetDocumentSettingManager().get(IDocumentSettingAccess::INVERT_BORDER_SPACING)) {
1895 : // OD 23.01.2003 #106895# - for cell frame in R2L text direction the left
1896 : // and right border are painted on the right respectively left.
1897 125113 : if ( pCaller->IsCellFrm() && pCaller->IsRightToLeft() )
1898 0 : nLeft = CalcRightLine();
1899 : else
1900 125113 : nLeft = CalcLeftLine();
1901 : }
1902 :
1903 : // for paragraphs, "left" is "before text" and "right" is "after text"
1904 494827 : if ( pCaller->IsTxtFrm() && pCaller->IsRightToLeft() )
1905 520 : nLeft += rLR.GetRight();
1906 : else
1907 : {
1908 494307 : bool bIgnoreMargin = false;
1909 494307 : if (pCaller->IsTxtFrm())
1910 : {
1911 459476 : const SwTxtFrm* pTxtFrm = (const SwTxtFrm*)pCaller;
1912 459476 : if (pTxtFrm->GetTxtNode()->GetDoc()->GetDocumentSettingManager().get(IDocumentSettingAccess::FLOATTABLE_NOMARGINS))
1913 : {
1914 : // If this is explicitly requested, ignore the margins next to the floating table.
1915 350504 : if (lcl_hasTabFrm(pTxtFrm))
1916 526 : bIgnoreMargin = true;
1917 : // TODO here we only handle the first two paragraphs, would be nice to generalize this.
1918 349978 : else if (pTxtFrm->FindPrev() && pTxtFrm->FindPrev()->IsTxtFrm() && lcl_hasTabFrm((const SwTxtFrm*)pTxtFrm->FindPrev()))
1919 316 : bIgnoreMargin = true;
1920 : }
1921 : }
1922 494307 : if (!bIgnoreMargin)
1923 493465 : nLeft += rLR.GetLeft();
1924 : }
1925 :
1926 : // correction: do not retrieve left margin for numbering in R2L-layout
1927 494827 : if ( pCaller->IsTxtFrm() && !pCaller->IsRightToLeft() )
1928 : {
1929 459476 : nLeft += ((SwTxtFrm*)pCaller)->GetTxtNode()->GetLeftMarginWithNum();
1930 : }
1931 :
1932 494827 : return nLeft;
1933 : }
1934 :
1935 : /* Calculated values for borders and shadows.
1936 : * It might be that a distance is wanted even without lines. This will be
1937 : * considered here and not by the attribute (e.g. bBorderDist for cells).
1938 : */
1939 :
1940 74132 : void SwBorderAttrs::_CalcTopLine()
1941 : {
1942 130 : nTopLine = (bBorderDist && !rBox.GetTop())
1943 38 : ? rBox.GetDistance (BOX_LINE_TOP)
1944 74170 : : rBox.CalcLineSpace(BOX_LINE_TOP);
1945 74132 : nTopLine = nTopLine + rShadow.CalcShadowSpace(SHADOW_TOP);
1946 74132 : bTopLine = false;
1947 74132 : }
1948 :
1949 74114 : void SwBorderAttrs::_CalcBottomLine()
1950 : {
1951 130 : nBottomLine = (bBorderDist && !rBox.GetBottom())
1952 40 : ? rBox.GetDistance (BOX_LINE_BOTTOM)
1953 74154 : : rBox.CalcLineSpace(BOX_LINE_BOTTOM);
1954 74114 : nBottomLine = nBottomLine + rShadow.CalcShadowSpace(SHADOW_BOTTOM);
1955 74114 : bBottomLine = false;
1956 74114 : }
1957 :
1958 28563 : void SwBorderAttrs::_CalcLeftLine()
1959 : {
1960 90 : nLeftLine = (bBorderDist && !rBox.GetLeft())
1961 36 : ? rBox.GetDistance (BOX_LINE_LEFT)
1962 28599 : : rBox.CalcLineSpace(BOX_LINE_LEFT);
1963 28563 : nLeftLine = nLeftLine + rShadow.CalcShadowSpace(SHADOW_LEFT);
1964 28563 : bLeftLine = false;
1965 28563 : }
1966 :
1967 28563 : void SwBorderAttrs::_CalcRightLine()
1968 : {
1969 90 : nRightLine = (bBorderDist && !rBox.GetRight())
1970 34 : ? rBox.GetDistance (BOX_LINE_RIGHT)
1971 28597 : : rBox.CalcLineSpace(BOX_LINE_RIGHT);
1972 28563 : nRightLine = nRightLine + rShadow.CalcShadowSpace(SHADOW_RIGHT);
1973 28563 : bRightLine = false;
1974 28563 : }
1975 :
1976 15280 : void SwBorderAttrs::_IsLine()
1977 : {
1978 45428 : bIsLine = rBox.GetTop() || rBox.GetBottom() ||
1979 45400 : rBox.GetLeft()|| rBox.GetRight();
1980 15280 : bLine = false;
1981 15280 : }
1982 :
1983 : /* The borders of neighboring paragraphs are condensed by following algorithm:
1984 : *
1985 : * 1. No top border if the predecessor has the same top border and (3) applies.
1986 : * In addition, the paragraph needs to have a border at at least one side (left/right/bottom).
1987 : * 2. No bottom border if the successor has the same bottom border and (3) applies.
1988 : * In addition, the paragraph needs to have a border at at least one side (left/right/top).
1989 : * 3. The borders on the left and right side are identical between the current and the
1990 : * pre-/succeeding paragraph.
1991 : */
1992 :
1993 631126 : inline bool CmpLines( const editeng::SvxBorderLine *pL1, const editeng::SvxBorderLine *pL2 )
1994 : {
1995 631126 : return ( ((pL1 && pL2) && (*pL1 == *pL2)) || (!pL1 && !pL2) );
1996 : }
1997 :
1998 : // OD 21.05.2003 #108789# - change name of 1st parameter - "rAttrs" -> "rCmpAttrs"
1999 : // OD 21.05.2003 #108789# - compare <CalcRight()> and <rCmpAttrs.CalcRight()>
2000 : // instead of only the right LR-spacing, because R2L-layout has to be
2001 : // considered.
2002 157318 : bool SwBorderAttrs::CmpLeftRight( const SwBorderAttrs &rCmpAttrs,
2003 : const SwFrm *pCaller,
2004 : const SwFrm *pCmp ) const
2005 : {
2006 314636 : return ( CmpLines( rCmpAttrs.GetBox().GetLeft(), GetBox().GetLeft() ) &&
2007 314636 : CmpLines( rCmpAttrs.GetBox().GetRight(),GetBox().GetRight() ) &&
2008 450758 : CalcLeft( pCaller ) == rCmpAttrs.CalcLeft( pCmp ) &&
2009 : // OD 21.05.2003 #108789# - compare <CalcRight> with <rCmpAttrs.CalcRight>.
2010 293440 : CalcRight( pCaller ) == rCmpAttrs.CalcRight( pCmp ) );
2011 : }
2012 :
2013 158746 : bool SwBorderAttrs::_JoinWithCmp( const SwFrm& _rCallerFrm,
2014 : const SwFrm& _rCmpFrm ) const
2015 : {
2016 158746 : bool bReturnVal = false;
2017 :
2018 158746 : SwBorderAttrAccess aCmpAccess( SwFrm::GetCache(), &_rCmpFrm );
2019 158746 : const SwBorderAttrs &rCmpAttrs = *aCmpAccess.Get();
2020 476086 : if ( rShadow == rCmpAttrs.GetShadow() &&
2021 316490 : CmpLines( rBox.GetTop(), rCmpAttrs.GetBox().GetTop() ) &&
2022 473960 : CmpLines( rBox.GetBottom(), rCmpAttrs.GetBox().GetBottom() ) &&
2023 157318 : CmpLeftRight( rCmpAttrs, &_rCallerFrm, &_rCmpFrm )
2024 : )
2025 : {
2026 135412 : bReturnVal = true;
2027 : }
2028 :
2029 158746 : return bReturnVal;
2030 : }
2031 :
2032 : // OD 21.05.2003 #108789# - method to determine, if borders are joined with
2033 : // previous frame. Calculated value saved in cached value <bJoinedWithPrev>
2034 : // OD 2004-02-26 #i25029# - add 2nd parameter <_pPrevFrm>
2035 292455 : void SwBorderAttrs::_CalcJoinedWithPrev( const SwFrm& _rFrm,
2036 : const SwFrm* _pPrevFrm )
2037 : {
2038 : // set default
2039 292455 : bJoinedWithPrev = false;
2040 :
2041 292455 : if ( _rFrm.IsTxtFrm() )
2042 : {
2043 : // text frame can potentially join with previous text frame, if
2044 : // corresponding attribute set is set at previous text frame.
2045 : // OD 2004-02-26 #i25029# - If parameter <_pPrevFrm> is set, take this
2046 : // one as previous frame.
2047 280688 : const SwFrm* pPrevFrm = _pPrevFrm ? _pPrevFrm : _rFrm.GetPrev();
2048 : // OD 2004-02-13 #i25029# - skip hidden text frames.
2049 663759 : while ( pPrevFrm && pPrevFrm->IsTxtFrm() &&
2050 102365 : static_cast<const SwTxtFrm*>(pPrevFrm)->IsHiddenNow() )
2051 : {
2052 18 : pPrevFrm = pPrevFrm->GetPrev();
2053 : }
2054 383035 : if ( pPrevFrm && pPrevFrm->IsTxtFrm() &&
2055 102347 : pPrevFrm->GetAttrSet()->GetParaConnectBorder().GetValue()
2056 : )
2057 : {
2058 102347 : bJoinedWithPrev = _JoinWithCmp( _rFrm, *(pPrevFrm) );
2059 : }
2060 : }
2061 :
2062 : // valid cache status, if demanded
2063 : // OD 2004-02-26 #i25029# - Do not validate cache, if parameter <_pPrevFrm>
2064 : // is set.
2065 292455 : bCachedJoinedWithPrev = bCacheGetLine && !_pPrevFrm;
2066 292455 : }
2067 :
2068 : // OD 21.05.2003 #108789# - method to determine, if borders are joined with
2069 : // next frame. Calculated value saved in cached value <bJoinedWithNext>
2070 140491 : void SwBorderAttrs::_CalcJoinedWithNext( const SwFrm& _rFrm )
2071 : {
2072 : // set default
2073 140491 : bJoinedWithNext = false;
2074 :
2075 140491 : if ( _rFrm.IsTxtFrm() )
2076 : {
2077 : // text frame can potentially join with next text frame, if
2078 : // corresponding attribute set is set at current text frame.
2079 : // OD 2004-02-13 #i25029# - get next frame, but skip hidden text frames.
2080 138720 : const SwFrm* pNextFrm = _rFrm.GetNext();
2081 333839 : while ( pNextFrm && pNextFrm->IsTxtFrm() &&
2082 56399 : static_cast<const SwTxtFrm*>(pNextFrm)->IsHiddenNow() )
2083 : {
2084 0 : pNextFrm = pNextFrm->GetNext();
2085 : }
2086 195119 : if ( pNextFrm && pNextFrm->IsTxtFrm() &&
2087 56399 : _rFrm.GetAttrSet()->GetParaConnectBorder().GetValue()
2088 : )
2089 : {
2090 56399 : bJoinedWithNext = _JoinWithCmp( _rFrm, *(pNextFrm) );
2091 : }
2092 : }
2093 :
2094 : // valid cache status, if demanded
2095 140491 : bCachedJoinedWithNext = bCacheGetLine;
2096 140491 : }
2097 :
2098 : // OD 21.05.2003 #108789# - accessor for cached values <bJoinedWithPrev>
2099 : // OD 2004-02-26 #i25029# - add 2nd parameter <_pPrevFrm>, which is passed to
2100 : // method <_CalcJoindWithPrev(..)>.
2101 292591 : bool SwBorderAttrs::JoinedWithPrev( const SwFrm& _rFrm,
2102 : const SwFrm* _pPrevFrm ) const
2103 : {
2104 292591 : if ( !bCachedJoinedWithPrev || _pPrevFrm )
2105 : {
2106 : // OD 2004-02-26 #i25029# - pass <_pPrevFrm> as 2nd parameter
2107 292455 : const_cast<SwBorderAttrs*>(this)->_CalcJoinedWithPrev( _rFrm, _pPrevFrm );
2108 : }
2109 :
2110 292591 : return bJoinedWithPrev;
2111 : }
2112 :
2113 140627 : bool SwBorderAttrs::JoinedWithNext( const SwFrm& _rFrm ) const
2114 : {
2115 140627 : if ( !bCachedJoinedWithNext )
2116 : {
2117 140491 : const_cast<SwBorderAttrs*>(this)->_CalcJoinedWithNext( _rFrm );
2118 : }
2119 :
2120 140627 : return bJoinedWithNext;
2121 : }
2122 :
2123 : // OD 2004-02-26 #i25029# - added 2nd parameter <_pPrevFrm>, which is passed to
2124 : // method <JoinedWithPrev>
2125 165411 : void SwBorderAttrs::_GetTopLine( const SwFrm& _rFrm,
2126 : const SwFrm* _pPrevFrm )
2127 : {
2128 165411 : sal_uInt16 nRet = CalcTopLine();
2129 :
2130 : // OD 21.05.2003 #108789# - use new method <JoinWithPrev()>
2131 : // OD 2004-02-26 #i25029# - add 2nd parameter
2132 165411 : if ( JoinedWithPrev( _rFrm, _pPrevFrm ) )
2133 : {
2134 52531 : nRet = 0;
2135 : }
2136 :
2137 165411 : bCachedGetTopLine = bCacheGetLine;
2138 :
2139 165411 : nGetTopLine = nRet;
2140 165411 : }
2141 :
2142 140469 : void SwBorderAttrs::_GetBottomLine( const SwFrm& _rFrm )
2143 : {
2144 140469 : sal_uInt16 nRet = CalcBottomLine();
2145 :
2146 : // OD 21.05.2003 #108789# - use new method <JoinWithPrev()>
2147 140469 : if ( JoinedWithNext( _rFrm ) )
2148 : {
2149 49927 : nRet = 0;
2150 : }
2151 :
2152 140469 : bCachedGetBottomLine = bCacheGetLine;
2153 :
2154 140469 : nGetBottomLine = nRet;
2155 140469 : }
2156 :
2157 695209 : SwBorderAttrAccess::SwBorderAttrAccess( SwCache &rCach, const SwFrm *pFrm ) :
2158 : SwCacheAccess( rCach,
2159 695209 : (pFrm->IsCntntFrm() ?
2160 : (void*)((SwCntntFrm*)pFrm)->GetNode() :
2161 309975 : (void*)((SwLayoutFrm*)pFrm)->GetFmt()),
2162 695209 : (pFrm->IsCntntFrm() ?
2163 385234 : ((SwModify*)((SwCntntFrm*)pFrm)->GetNode())->IsInCache() :
2164 309975 : ((SwModify*)((SwLayoutFrm*)pFrm)->GetFmt())->IsInCache()) ),
2165 2395602 : pConstructor( pFrm )
2166 : {
2167 695209 : }
2168 :
2169 159507 : SwCacheObj *SwBorderAttrAccess::NewObj()
2170 : {
2171 159507 : ((SwModify*)pOwner)->SetInCache( true );
2172 159507 : return new SwBorderAttrs( (SwModify*)pOwner, pConstructor );
2173 : }
2174 :
2175 695209 : SwBorderAttrs *SwBorderAttrAccess::Get()
2176 : {
2177 695209 : return (SwBorderAttrs*)SwCacheAccess::Get();
2178 : }
2179 :
2180 3060 : SwOrderIter::SwOrderIter( const SwPageFrm *pPg, bool bFlys ) :
2181 : pPage( pPg ),
2182 : pCurrent( 0 ),
2183 3060 : bFlysOnly( bFlys )
2184 : {
2185 3060 : }
2186 :
2187 20 : const SdrObject *SwOrderIter::Top()
2188 : {
2189 20 : pCurrent = 0;
2190 20 : if ( pPage->GetSortedObjs() )
2191 : {
2192 20 : const SwSortedObjs *pObjs = pPage->GetSortedObjs();
2193 20 : if ( pObjs->size() )
2194 : {
2195 20 : sal_uInt32 nTopOrd = 0;
2196 20 : (*pObjs)[0]->GetDrawObj()->GetOrdNum(); // force updating
2197 60 : for ( size_t i = 0; i < pObjs->size(); ++i )
2198 : {
2199 40 : const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
2200 40 : if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
2201 12 : continue;
2202 28 : sal_uInt32 nTmp = pObj->GetOrdNumDirect();
2203 28 : if ( nTmp >= nTopOrd )
2204 : {
2205 20 : nTopOrd = nTmp;
2206 20 : pCurrent = pObj;
2207 : }
2208 : }
2209 : }
2210 : }
2211 20 : return pCurrent;
2212 : }
2213 :
2214 336 : const SdrObject *SwOrderIter::Bottom()
2215 : {
2216 336 : pCurrent = 0;
2217 336 : if ( pPage->GetSortedObjs() )
2218 : {
2219 336 : sal_uInt32 nBotOrd = USHRT_MAX;
2220 336 : const SwSortedObjs *pObjs = pPage->GetSortedObjs();
2221 336 : if ( pObjs->size() )
2222 : {
2223 336 : (*pObjs)[0]->GetDrawObj()->GetOrdNum(); // force updating
2224 1284 : for ( size_t i = 0; i < pObjs->size(); ++i )
2225 : {
2226 948 : const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
2227 948 : if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
2228 216 : continue;
2229 732 : sal_uInt32 nTmp = pObj->GetOrdNumDirect();
2230 732 : if ( nTmp < nBotOrd )
2231 : {
2232 488 : nBotOrd = nTmp;
2233 488 : pCurrent = pObj;
2234 : }
2235 : }
2236 : }
2237 : }
2238 336 : return pCurrent;
2239 : }
2240 :
2241 16930 : const SdrObject *SwOrderIter::Next()
2242 : {
2243 16930 : const sal_uInt32 nCurOrd = pCurrent ? pCurrent->GetOrdNumDirect() : 0;
2244 16930 : pCurrent = 0;
2245 16930 : if ( pPage->GetSortedObjs() )
2246 : {
2247 16930 : sal_uInt32 nOrd = USHRT_MAX;
2248 16930 : const SwSortedObjs *pObjs = pPage->GetSortedObjs();
2249 16930 : if ( pObjs->size() )
2250 : {
2251 16930 : (*pObjs)[0]->GetDrawObj()->GetOrdNum(); // force updating
2252 1864248 : for ( size_t i = 0; i < pObjs->size(); ++i )
2253 : {
2254 1847318 : const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
2255 1847318 : if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
2256 1264738 : continue;
2257 582580 : sal_uInt32 nTmp = pObj->GetOrdNumDirect();
2258 582580 : if ( nTmp > nCurOrd && nTmp < nOrd )
2259 : {
2260 15492 : nOrd = nTmp;
2261 15492 : pCurrent = pObj;
2262 : }
2263 : }
2264 : }
2265 : }
2266 16930 : return pCurrent;
2267 : }
2268 :
2269 28 : const SdrObject *SwOrderIter::Prev()
2270 : {
2271 28 : const sal_uInt32 nCurOrd = pCurrent ? pCurrent->GetOrdNumDirect() : 0;
2272 28 : pCurrent = 0;
2273 28 : if ( pPage->GetSortedObjs() )
2274 : {
2275 28 : const SwSortedObjs *pObjs = pPage->GetSortedObjs();
2276 28 : if ( pObjs->size() )
2277 : {
2278 28 : sal_uInt32 nOrd = 0;
2279 28 : (*pObjs)[0]->GetDrawObj()->GetOrdNum(); // force updating
2280 84 : for ( size_t i = 0; i < pObjs->size(); ++i )
2281 : {
2282 56 : const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
2283 56 : if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
2284 12 : continue;
2285 44 : sal_uInt32 nTmp = pObj->GetOrdNumDirect();
2286 44 : if ( nTmp < nCurOrd && nTmp >= nOrd )
2287 : {
2288 8 : nOrd = nTmp;
2289 8 : pCurrent = pObj;
2290 : }
2291 : }
2292 : }
2293 : }
2294 28 : return pCurrent;
2295 : }
2296 :
2297 : /// Keep and restore the substructure of a layout frame for an action.
2298 : // New algorithm:
2299 : // Do not look at each neighbor one by one to set all pointers correctly.
2300 : // It is sufficient to detach a part of a chain and check if another chain needs to be added
2301 : // when attaching it again. Only the pointers necessary for the chain connection need to be
2302 : // adjusted. The correction happens in RestoreCntnt(). In between all access is restricted.
2303 : // During this action, the Flys are detached from the page.
2304 :
2305 : // #115759# - 'remove' also drawing object from page and
2306 : // at-fly anchored objects from page
2307 12 : static void lcl_RemoveObjsFromPage( SwFrm* _pFrm )
2308 : {
2309 : OSL_ENSURE( _pFrm->GetDrawObjs(), "no DrawObjs in lcl_RemoveObjsFromPage." );
2310 12 : SwSortedObjs &rObjs = *_pFrm->GetDrawObjs();
2311 32 : for ( size_t i = 0; i < rObjs.size(); ++i )
2312 : {
2313 20 : SwAnchoredObject* pObj = rObjs[i];
2314 : // #115759# - reset member, at which the anchored
2315 : // object orients its vertical position
2316 20 : pObj->ClearVertPosOrientFrm();
2317 : // #i43913#
2318 20 : pObj->ResetLayoutProcessBools();
2319 : // #115759# - remove also lower objects of as-character
2320 : // anchored Writer fly frames from page
2321 20 : if ( pObj->ISA(SwFlyFrm) )
2322 : {
2323 0 : SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
2324 :
2325 : // #115759# - remove also direct lowers of Writer
2326 : // fly frame from page
2327 0 : if ( pFlyFrm->GetDrawObjs() )
2328 : {
2329 0 : ::lcl_RemoveObjsFromPage( pFlyFrm );
2330 : }
2331 :
2332 0 : SwCntntFrm* pCnt = pFlyFrm->ContainsCntnt();
2333 0 : while ( pCnt )
2334 : {
2335 0 : if ( pCnt->GetDrawObjs() )
2336 0 : ::lcl_RemoveObjsFromPage( pCnt );
2337 0 : pCnt = pCnt->GetNextCntntFrm();
2338 : }
2339 0 : if ( pFlyFrm->IsFlyFreeFrm() )
2340 : {
2341 : // #i28701# - use new method <GetPageFrm()>
2342 0 : pFlyFrm->GetPageFrm()->RemoveFlyFromPage( pFlyFrm );
2343 : }
2344 : }
2345 : // #115759# - remove also drawing objects from page
2346 20 : else if ( pObj->ISA(SwAnchoredDrawObject) )
2347 : {
2348 20 : if (pObj->GetFrmFmt().GetAnchor().GetAnchorId() != FLY_AS_CHAR)
2349 : {
2350 : pObj->GetPageFrm()->RemoveDrawObjFromPage(
2351 0 : *(static_cast<SwAnchoredDrawObject*>(pObj)) );
2352 : }
2353 : }
2354 : }
2355 12 : }
2356 :
2357 1160 : SwFrm *SaveCntnt( SwLayoutFrm *pLay, SwFrm *pStart )
2358 : {
2359 1160 : if( pLay->IsSctFrm() && pLay->Lower() && pLay->Lower()->IsColumnFrm() )
2360 22 : sw_RemoveFtns( (SwColumnFrm*)pLay->Lower(), true, true );
2361 :
2362 : SwFrm *pSav;
2363 1160 : if ( 0 == (pSav = pLay->ContainsAny()) )
2364 828 : return 0;
2365 :
2366 332 : if( pSav->IsInFtn() && !pLay->IsInFtn() )
2367 : {
2368 0 : do
2369 0 : pSav = pSav->FindNext();
2370 0 : while( pSav && pSav->IsInFtn() );
2371 0 : if( !pSav || !pLay->IsAnLower( pSav ) )
2372 0 : return NULL;
2373 : }
2374 :
2375 : // Tables should be saved as a whole, expection:
2376 : // The contents of a section or a cell inside a table should be saved
2377 332 : if ( pSav->IsInTab() && !( ( pLay->IsSctFrm() || pLay->IsCellFrm() ) && pLay->IsInTab() ) )
2378 0 : while ( !pSav->IsTabFrm() )
2379 0 : pSav = pSav->GetUpper();
2380 :
2381 332 : if( pSav->IsInSct() )
2382 : { // search the upmost section inside of pLay
2383 48 : SwFrm* pSect = pLay->FindSctFrm();
2384 48 : SwFrm *pTmp = pSav;
2385 48 : do
2386 : {
2387 48 : pSav = pTmp;
2388 48 : pTmp = (pSav && pSav->GetUpper()) ? pSav->GetUpper()->FindSctFrm() : NULL;
2389 : } while ( pTmp != pSect );
2390 : }
2391 :
2392 332 : SwFrm *pFloat = pSav;
2393 332 : if( !pStart )
2394 326 : pStart = pSav;
2395 332 : bool bGo = pStart == pSav;
2396 334 : do
2397 : {
2398 334 : if( bGo )
2399 328 : pFloat->GetUpper()->pLower = 0; // detach the chain part
2400 :
2401 : // search the end of the chain part, remove Flys on the way
2402 86 : do
2403 : {
2404 420 : if( bGo )
2405 : {
2406 414 : if ( pFloat->IsCntntFrm() )
2407 : {
2408 412 : if ( pFloat->GetDrawObjs() )
2409 10 : ::lcl_RemoveObjsFromPage( (SwCntntFrm*)pFloat );
2410 : }
2411 2 : else if ( pFloat->IsTabFrm() || pFloat->IsSctFrm() )
2412 : {
2413 2 : SwCntntFrm *pCnt = ((SwLayoutFrm*)pFloat)->ContainsCntnt();
2414 2 : if( pCnt )
2415 : {
2416 2 : do
2417 2 : { if ( pCnt->GetDrawObjs() )
2418 2 : ::lcl_RemoveObjsFromPage( pCnt );
2419 2 : pCnt = pCnt->GetNextCntntFrm();
2420 2 : } while ( pCnt && ((SwLayoutFrm*)pFloat)->IsAnLower( pCnt ) );
2421 : }
2422 : }
2423 : else {
2424 : OSL_ENSURE( !pFloat, "new FloatFrame?" );
2425 : }
2426 : }
2427 420 : if ( pFloat->GetNext() )
2428 : {
2429 86 : if( bGo )
2430 80 : pFloat->mpUpper = NULL;
2431 86 : pFloat = pFloat->GetNext();
2432 86 : if( !bGo && pFloat == pStart )
2433 : {
2434 6 : bGo = true;
2435 6 : pFloat->mpPrev->mpNext = NULL;
2436 6 : pFloat->mpPrev = NULL;
2437 : }
2438 : }
2439 : else
2440 334 : break;
2441 :
2442 : } while ( pFloat );
2443 :
2444 : // search next chain part and connect both chains
2445 334 : SwFrm *pTmp = pFloat->FindNext();
2446 334 : if( bGo )
2447 334 : pFloat->mpUpper = NULL;
2448 :
2449 334 : if( !pLay->IsInFtn() )
2450 664 : while( pTmp && pTmp->IsInFtn() )
2451 0 : pTmp = pTmp->FindNext();
2452 :
2453 334 : if ( !pLay->IsAnLower( pTmp ) )
2454 332 : pTmp = 0;
2455 :
2456 334 : if ( pTmp && bGo )
2457 : {
2458 2 : pFloat->mpNext = pTmp; // connect both chains
2459 2 : pFloat->mpNext->mpPrev = pFloat;
2460 : }
2461 334 : pFloat = pTmp;
2462 334 : bGo = bGo || ( pStart == pFloat );
2463 : } while ( pFloat );
2464 :
2465 332 : return bGo ? pStart : NULL;
2466 : }
2467 :
2468 : // #115759# - add also drawing objects to page and at-fly
2469 : // anchored objects to page
2470 12 : static void lcl_AddObjsToPage( SwFrm* _pFrm, SwPageFrm* _pPage )
2471 : {
2472 : OSL_ENSURE( _pFrm->GetDrawObjs(), "no DrawObjs in lcl_AddObjsToPage." );
2473 12 : SwSortedObjs &rObjs = *_pFrm->GetDrawObjs();
2474 32 : for ( size_t i = 0; i < rObjs.size(); ++i )
2475 : {
2476 20 : SwAnchoredObject* pObj = rObjs[i];
2477 :
2478 : // #115759# - unlock position of anchored object
2479 : // in order to get the object's position calculated.
2480 20 : pObj->UnlockPosition();
2481 : // #115759# - add also lower objects of as-character
2482 : // anchored Writer fly frames from page
2483 20 : if ( pObj->ISA(SwFlyFrm) )
2484 : {
2485 0 : SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
2486 0 : if ( pObj->ISA(SwFlyFreeFrm) )
2487 : {
2488 0 : _pPage->AppendFlyToPage( pFlyFrm );
2489 : }
2490 0 : pFlyFrm->_InvalidatePos();
2491 0 : pFlyFrm->_InvalidateSize();
2492 0 : pFlyFrm->InvalidatePage( _pPage );
2493 :
2494 : // #115759# - add also at-fly anchored objects
2495 : // to page
2496 0 : if ( pFlyFrm->GetDrawObjs() )
2497 : {
2498 0 : ::lcl_AddObjsToPage( pFlyFrm, _pPage );
2499 : }
2500 :
2501 0 : SwCntntFrm *pCnt = pFlyFrm->ContainsCntnt();
2502 0 : while ( pCnt )
2503 : {
2504 0 : if ( pCnt->GetDrawObjs() )
2505 0 : ::lcl_AddObjsToPage( pCnt, _pPage );
2506 0 : pCnt = pCnt->GetNextCntntFrm();
2507 : }
2508 : }
2509 : // #115759# - remove also drawing objects from page
2510 20 : else if ( pObj->ISA(SwAnchoredDrawObject) )
2511 : {
2512 20 : if (pObj->GetFrmFmt().GetAnchor().GetAnchorId() != FLY_AS_CHAR)
2513 : {
2514 0 : pObj->InvalidateObjPos();
2515 : _pPage->AppendDrawObjToPage(
2516 0 : *(static_cast<SwAnchoredDrawObject*>(pObj)) );
2517 : }
2518 : }
2519 : }
2520 12 : }
2521 :
2522 332 : void RestoreCntnt( SwFrm *pSav, SwLayoutFrm *pParent, SwFrm *pSibling, bool bGrow )
2523 : {
2524 : OSL_ENSURE( pSav && pParent, "no Save or Parent provided for RestoreCntnt." );
2525 332 : SWRECTFN( pParent )
2526 :
2527 : // If there are already FlowFrms below the new parent, so add the chain (starting with pSav)
2528 : // after the last one. The parts are inserted and invalidated if needed.
2529 : // On the way, the Flys of the CntntFrms are registered at the page.
2530 :
2531 332 : SwPageFrm *pPage = pParent->FindPageFrm();
2532 :
2533 332 : if ( pPage )
2534 326 : pPage->InvalidatePage( pPage );
2535 :
2536 : // determine predecessor and establish connection or initialize
2537 332 : pSav->mpPrev = pSibling;
2538 : SwFrm* pNxt;
2539 332 : if ( pSibling )
2540 : {
2541 214 : pNxt = pSibling->mpNext;
2542 214 : pSibling->mpNext = pSav;
2543 214 : pSibling->_InvalidatePrt();
2544 214 : pSibling->InvalidatePage( pPage );
2545 214 : SwFlowFrm *pFlowFrm = dynamic_cast<SwFlowFrm*>(pSibling);
2546 214 : if (pFlowFrm && pFlowFrm->GetFollow())
2547 196 : pSibling->Prepare( PREP_CLEAR, 0, false );
2548 : }
2549 : else
2550 118 : { pNxt = pParent->pLower;
2551 118 : pParent->pLower = pSav;
2552 118 : pSav->mpUpper = pParent; // set here already, so that it is explicit when invalidating
2553 :
2554 118 : if ( pSav->IsCntntFrm() )
2555 118 : ((SwCntntFrm*)pSav)->InvalidatePage( pPage );
2556 : else
2557 : { // pSav might be an empty SectFrm
2558 0 : SwCntntFrm* pCnt = pParent->ContainsCntnt();
2559 0 : if( pCnt )
2560 0 : pCnt->InvalidatePage( pPage );
2561 : }
2562 : }
2563 :
2564 : // the parent needs to grow appropiately
2565 332 : SwTwips nGrowVal = 0;
2566 : SwFrm* pLast;
2567 414 : do
2568 414 : { pSav->mpUpper = pParent;
2569 414 : nGrowVal += (pSav->Frm().*fnRect->fnGetHeight)();
2570 414 : pSav->_InvalidateAll();
2571 :
2572 : // register Flys, if TxtFrms than also invalidate appropriately
2573 414 : if ( pSav->IsCntntFrm() )
2574 : {
2575 824 : if ( pSav->IsTxtFrm() &&
2576 412 : ((SwTxtFrm*)pSav)->GetCacheIdx() != USHRT_MAX )
2577 340 : ((SwTxtFrm*)pSav)->Init(); // I am its friend
2578 :
2579 412 : if ( pPage && pSav->GetDrawObjs() )
2580 10 : ::lcl_AddObjsToPage( (SwCntntFrm*)pSav, pPage );
2581 : }
2582 : else
2583 2 : { SwCntntFrm *pBlub = ((SwLayoutFrm*)pSav)->ContainsCntnt();
2584 2 : if( pBlub )
2585 : {
2586 2 : do
2587 2 : { if ( pPage && pBlub->GetDrawObjs() )
2588 2 : ::lcl_AddObjsToPage( pBlub, pPage );
2589 2 : if( pBlub->IsTxtFrm() && ((SwTxtFrm*)pBlub)->HasFtn() &&
2590 0 : ((SwTxtFrm*)pBlub)->GetCacheIdx() != USHRT_MAX )
2591 0 : ((SwTxtFrm*)pBlub)->Init(); // I am its friend
2592 2 : pBlub = pBlub->GetNextCntntFrm();
2593 2 : } while ( pBlub && ((SwLayoutFrm*)pSav)->IsAnLower( pBlub ));
2594 : }
2595 : }
2596 414 : pLast = pSav;
2597 414 : pSav = pSav->GetNext();
2598 :
2599 : } while ( pSav );
2600 :
2601 332 : if( pNxt )
2602 : {
2603 8 : pLast->mpNext = pNxt;
2604 8 : pNxt->mpPrev = pLast;
2605 : }
2606 :
2607 332 : if ( bGrow )
2608 332 : pParent->Grow( nGrowVal );
2609 332 : }
2610 :
2611 6952 : SwPageFrm * InsertNewPage( SwPageDesc &rDesc, SwFrm *pUpper,
2612 : bool bOdd, bool bFirst, bool bInsertEmpty, bool bFtn,
2613 : SwFrm *pSibling )
2614 : {
2615 : SwPageFrm *pRet;
2616 6952 : SwDoc *pDoc = ((SwLayoutFrm*)pUpper)->GetFmt()->GetDoc();
2617 6952 : if (bFirst)
2618 : {
2619 5470 : if (rDesc.IsFirstShared())
2620 : {
2621 : // We need to fallback to left or right page format, decide it now.
2622 : // FIXME: is this still needed?
2623 5432 : if (bOdd)
2624 : {
2625 5198 : rDesc.GetFirstMaster().SetFmtAttr( rDesc.GetMaster().GetHeader() );
2626 5198 : rDesc.GetFirstMaster().SetFmtAttr( rDesc.GetMaster().GetFooter() );
2627 : // fdo#60250 copy margins for mirrored pages
2628 5198 : rDesc.GetFirstMaster().SetFmtAttr( rDesc.GetMaster().GetLRSpace() );
2629 : }
2630 : else
2631 : {
2632 234 : rDesc.GetFirstLeft().SetFmtAttr( rDesc.GetLeft().GetHeader() );
2633 234 : rDesc.GetFirstLeft().SetFmtAttr( rDesc.GetLeft().GetFooter() );
2634 234 : rDesc.GetFirstLeft().SetFmtAttr( rDesc.GetLeft().GetLRSpace() );
2635 : }
2636 : }
2637 : }
2638 6952 : SwFrmFmt *pFmt(bOdd ? rDesc.GetRightFmt(bFirst) : rDesc.GetLeftFmt(bFirst));
2639 : // If there is no FrmFmt for this page, add an empty page
2640 6952 : if ( !pFmt )
2641 : {
2642 4 : pFmt = bOdd ? rDesc.GetLeftFmt() : rDesc.GetRightFmt();
2643 : OSL_ENSURE( pFmt, "Descriptor without any format?!" );
2644 4 : bInsertEmpty = !bInsertEmpty;
2645 : }
2646 6952 : if( bInsertEmpty )
2647 : {
2648 0 : SwPageDesc *pTmpDesc = pSibling && pSibling->GetPrev() ?
2649 22 : ((SwPageFrm*)pSibling->GetPrev())->GetPageDesc() : &rDesc;
2650 22 : pRet = new SwPageFrm( pDoc->GetEmptyPageFmt(), pUpper, pTmpDesc );
2651 22 : pRet->Paste( pUpper, pSibling );
2652 22 : pRet->PreparePage( bFtn );
2653 : }
2654 6952 : pRet = new SwPageFrm( pFmt, pUpper, &rDesc );
2655 6952 : pRet->Paste( pUpper, pSibling );
2656 6952 : pRet->PreparePage( bFtn );
2657 6952 : if ( pRet->GetNext() )
2658 0 : ((SwRootFrm*)pRet->GetUpper())->AssertPageFlys( pRet );
2659 6952 : return pRet;
2660 : }
2661 :
2662 : /* The following two methods search the layout structure recursively and
2663 : * register all Flys at the page that have a Frm in this structure as an anchor.
2664 : */
2665 :
2666 910 : static void lcl_Regist( SwPageFrm *pPage, const SwFrm *pAnch )
2667 : {
2668 910 : SwSortedObjs *pObjs = (SwSortedObjs*)pAnch->GetDrawObjs();
2669 2386 : for ( size_t i = 0; i < pObjs->size(); ++i )
2670 : {
2671 1476 : SwAnchoredObject* pObj = (*pObjs)[i];
2672 1476 : if ( pObj->ISA(SwFlyFrm) )
2673 : {
2674 776 : SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pObj);
2675 : // register (not if already known)
2676 : // #i28701# - use new method <GetPageFrm()>
2677 776 : SwPageFrm *pPg = pFly->IsFlyFreeFrm()
2678 776 : ? pFly->GetPageFrm() : pFly->FindPageFrm();
2679 776 : if ( pPg != pPage )
2680 : {
2681 776 : if ( pPg )
2682 0 : pPg->RemoveFlyFromPage( pFly );
2683 776 : pPage->AppendFlyToPage( pFly );
2684 : }
2685 776 : ::RegistFlys( pPage, pFly );
2686 : }
2687 : else
2688 : {
2689 : // #i87493#
2690 700 : if ( pPage != pObj->GetPageFrm() )
2691 : {
2692 : // #i28701#
2693 684 : if ( pObj->GetPageFrm() )
2694 0 : pObj->GetPageFrm()->RemoveDrawObjFromPage( *pObj );
2695 684 : pPage->AppendDrawObjToPage( *pObj );
2696 : }
2697 : }
2698 :
2699 1476 : const SwFlyFrm* pFly = pAnch->FindFlyFrm();
2700 1500 : if ( pFly &&
2701 1476 : pObj->GetDrawObj()->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() &&
2702 0 : pObj->GetDrawObj()->GetPage() )
2703 : {
2704 : //#i119945# set pFly's OrdNum to pObj's. So when pFly is removed by Undo, the original OrdNum will not be changed.
2705 0 : pObj->DrawObj()->GetPage()->SetObjectOrdNum( pFly->GetVirtDrawObj()->GetOrdNumDirect(),
2706 0 : pObj->GetDrawObj()->GetOrdNumDirect() );
2707 : }
2708 : }
2709 910 : }
2710 :
2711 59784 : void RegistFlys( SwPageFrm *pPage, const SwLayoutFrm *pLay )
2712 : {
2713 59784 : if ( pLay->GetDrawObjs() )
2714 2 : ::lcl_Regist( pPage, pLay );
2715 59784 : const SwFrm *pFrm = pLay->Lower();
2716 204512 : while ( pFrm )
2717 : {
2718 84944 : if ( pFrm->IsLayoutFrm() )
2719 46652 : ::RegistFlys( pPage, (const SwLayoutFrm*)pFrm );
2720 38292 : else if ( pFrm->GetDrawObjs() )
2721 908 : ::lcl_Regist( pPage, pFrm );
2722 84944 : pFrm = pFrm->GetNext();
2723 : }
2724 59784 : }
2725 :
2726 : /// Notify the background based on the difference between old and new rectangle
2727 10057 : void Notify( SwFlyFrm *pFly, SwPageFrm *pOld, const SwRect &rOld,
2728 : const SwRect* pOldPrt )
2729 : {
2730 10057 : const SwRect aFrm( pFly->GetObjRectWithSpaces() );
2731 10057 : if ( rOld.Pos() != aFrm.Pos() )
2732 : { // changed position, invalidate old and new area
2733 8060 : if ( rOld.HasArea() &&
2734 4030 : rOld.Left()+pFly->GetFmt()->GetLRSpace().GetLeft() < FAR_AWAY )
2735 : {
2736 518 : pFly->NotifyBackground( pOld, rOld, PREP_FLY_LEAVE );
2737 : }
2738 4030 : pFly->NotifyBackground( pFly->FindPageFrm(), aFrm, PREP_FLY_ARRIVE );
2739 : }
2740 6027 : else if ( rOld.SSize() != aFrm.SSize() )
2741 : { // changed size, invalidate the area that was left or is now overlapped
2742 : // For simplicity, we purposely invalidate a Twip even if not needed.
2743 :
2744 1800 : SwViewShell *pSh = pFly->getRootFrm()->GetCurrShell();
2745 1800 : if( pSh && rOld.HasArea() )
2746 1800 : pSh->InvalidateWindows( rOld );
2747 :
2748 : // #i51941# - consider case that fly frame isn't
2749 : // registered at the old page <pOld>
2750 1800 : SwPageFrm* pPageFrm = pFly->FindPageFrm();
2751 1800 : if ( pOld != pPageFrm )
2752 : {
2753 116 : pFly->NotifyBackground( pPageFrm, aFrm, PREP_FLY_ARRIVE );
2754 : }
2755 :
2756 1800 : if ( rOld.Left() != aFrm.Left() )
2757 : {
2758 0 : SwRect aTmp( rOld );
2759 0 : aTmp.Union( aFrm );
2760 0 : aTmp.Left( std::min(aFrm.Left(), rOld.Left()) );
2761 0 : aTmp.Right( std::max(aFrm.Left(), rOld.Left()) );
2762 0 : pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
2763 : }
2764 1800 : SwTwips nOld = rOld.Right();
2765 1800 : SwTwips nNew = aFrm.Right();
2766 1800 : if ( nOld != nNew )
2767 : {
2768 8 : SwRect aTmp( rOld );
2769 8 : aTmp.Union( aFrm );
2770 8 : aTmp.Left( std::min(nNew, nOld) );
2771 8 : aTmp.Right( std::max(nNew, nOld) );
2772 8 : pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
2773 : }
2774 1800 : if ( rOld.Top() != aFrm.Top() )
2775 : {
2776 0 : SwRect aTmp( rOld );
2777 0 : aTmp.Union( aFrm );
2778 0 : aTmp.Top( std::min(aFrm.Top(), rOld.Top()) );
2779 0 : aTmp.Bottom( std::max(aFrm.Top(), rOld.Top()) );
2780 0 : pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
2781 : }
2782 1800 : nOld = rOld.Bottom();
2783 1800 : nNew = aFrm.Bottom();
2784 1800 : if ( nOld != nNew )
2785 : {
2786 1792 : SwRect aTmp( rOld );
2787 1792 : aTmp.Union( aFrm );
2788 1792 : aTmp.Top( std::min(nNew, nOld) );
2789 1792 : aTmp.Bottom( std::max(nNew, nOld) );
2790 1792 : pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
2791 : }
2792 : }
2793 4233 : else if ( pOldPrt && *pOldPrt != pFly->Prt() &&
2794 6 : pFly->GetFmt()->GetSurround().IsContour() )
2795 : {
2796 : // #i24097#
2797 0 : pFly->NotifyBackground( pFly->FindPageFrm(), aFrm, PREP_FLY_ARRIVE );
2798 : }
2799 10057 : }
2800 :
2801 18583 : static void lcl_CheckFlowBack( SwFrm* pFrm, const SwRect &rRect )
2802 : {
2803 18583 : SwTwips nBottom = rRect.Bottom();
2804 90369 : while( pFrm )
2805 : {
2806 53203 : if( pFrm->IsLayoutFrm() )
2807 : {
2808 28920 : if( rRect.IsOver( pFrm->Frm() ) )
2809 12221 : lcl_CheckFlowBack( ((SwLayoutFrm*)pFrm)->Lower(), rRect );
2810 : }
2811 24283 : else if( !pFrm->GetNext() && nBottom > pFrm->Frm().Bottom() )
2812 : {
2813 3615 : if( pFrm->IsCntntFrm() && ((SwCntntFrm*)pFrm)->HasFollow() )
2814 6 : pFrm->InvalidateSize();
2815 : else
2816 3609 : pFrm->InvalidateNextPos();
2817 : }
2818 53203 : pFrm = pFrm->GetNext();
2819 : }
2820 18583 : }
2821 :
2822 240836 : static void lcl_NotifyCntnt( const SdrObject *pThis, SwCntntFrm *pCnt,
2823 : const SwRect &rRect, const PrepareHint eHint )
2824 : {
2825 240836 : if ( pCnt->IsTxtFrm() )
2826 : {
2827 237010 : SwRect aCntPrt( pCnt->Prt() );
2828 237010 : aCntPrt.Pos() += pCnt->Frm().Pos();
2829 237010 : if ( eHint == PREP_FLY_ATTR_CHG )
2830 : {
2831 : // #i35640# - use given rectangle <rRect> instead
2832 : // of current bound rectangle
2833 116 : if ( aCntPrt.IsOver( rRect ) )
2834 37 : pCnt->Prepare( PREP_FLY_ATTR_CHG );
2835 : }
2836 : // #i23129# - only invalidate, if the text frame
2837 : // printing area overlaps with the given rectangle.
2838 236894 : else if ( aCntPrt.IsOver( rRect ) )
2839 22356 : pCnt->Prepare( eHint, (void*)&aCntPrt._Intersection( rRect ) );
2840 237010 : if ( pCnt->GetDrawObjs() )
2841 : {
2842 33480 : const SwSortedObjs &rObjs = *pCnt->GetDrawObjs();
2843 503592 : for ( size_t i = 0; i < rObjs.size(); ++i )
2844 : {
2845 470112 : SwAnchoredObject* pObj = rObjs[i];
2846 470112 : if ( pObj->ISA(SwFlyFrm) )
2847 : {
2848 155064 : SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pObj);
2849 155064 : if ( pFly->IsFlyInCntFrm() )
2850 : {
2851 2704 : SwCntntFrm *pCntnt = pFly->ContainsCntnt();
2852 8716 : while ( pCntnt )
2853 : {
2854 3308 : ::lcl_NotifyCntnt( pThis, pCntnt, rRect, eHint );
2855 3308 : pCntnt = pCntnt->GetNextCntntFrm();
2856 : }
2857 : }
2858 : }
2859 : }
2860 : }
2861 : }
2862 240836 : }
2863 :
2864 18114 : void Notify_Background( const SdrObject* pObj,
2865 : SwPageFrm* pPage,
2866 : const SwRect& rRect,
2867 : const PrepareHint eHint,
2868 : const bool bInva )
2869 : {
2870 : // If the frame was positioned correctly for the first time, do not inform the old area
2871 18114 : if ( eHint == PREP_FLY_LEAVE && rRect.Top() == FAR_AWAY )
2872 18152 : return;
2873 :
2874 : SwLayoutFrm* pArea;
2875 18076 : SwFlyFrm *pFlyFrm = 0;
2876 : SwFrm* pAnchor;
2877 18076 : if( pObj->ISA(SwVirtFlyDrawObj) )
2878 : {
2879 6470 : pFlyFrm = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
2880 6470 : pAnchor = pFlyFrm->AnchorFrm();
2881 : }
2882 : else
2883 : {
2884 11606 : pFlyFrm = NULL;
2885 : pAnchor = const_cast<SwFrm*>(
2886 11606 : GetUserCall(pObj)->GetAnchoredObj( pObj )->GetAnchorFrm() );
2887 : }
2888 18076 : if( PREP_FLY_LEAVE != eHint && pAnchor->IsInFly() )
2889 126 : pArea = pAnchor->FindFlyFrm();
2890 : else
2891 17950 : pArea = pPage;
2892 18076 : SwCntntFrm *pCnt = 0;
2893 18076 : if ( pArea )
2894 : {
2895 18076 : if( PREP_FLY_ARRIVE != eHint )
2896 6362 : lcl_CheckFlowBack( pArea, rRect );
2897 :
2898 : // Only the Flys following this anchor are reacting. Thus, those do not
2899 : // need to be processed.
2900 : // An exception is LEAVE, since the Fly might come "from above".
2901 : // If the anchor is positioned on the previous page, the whole page
2902 : // needs to be processed (47722).
2903 : // OD 2004-05-13 #i28701# - If the wrapping style has to be considered
2904 : // on the object positioning, the complete area has to be processed,
2905 : // because content frames before the anchor frame also have to consider
2906 : // the object for the text wrapping.
2907 : // #i3317# - The complete area has always been
2908 : // processed.
2909 : {
2910 18076 : pCnt = pArea->ContainsCntnt();
2911 : }
2912 : }
2913 18076 : SwFrm *pLastTab = 0;
2914 :
2915 195864 : while ( pCnt && pArea && pArea->IsAnLower( pCnt ) )
2916 : {
2917 159712 : ::lcl_NotifyCntnt( pObj, pCnt, rRect, eHint );
2918 159712 : if ( pCnt->IsInTab() )
2919 : {
2920 35014 : SwLayoutFrm* pCell = pCnt->GetUpper();
2921 : // #i40606# - use <GetLastBoundRect()>
2922 : // instead of <GetCurrentBoundRect()>, because a recalculation
2923 : // of the bounding rectangle isn't intended here.
2924 142342 : if ( pCell->IsCellFrm() &&
2925 172934 : ( pCell->Frm().IsOver( pObj->GetLastBoundRect() ) ||
2926 32878 : pCell->Frm().IsOver( rRect ) ) )
2927 : {
2928 2286 : const SwFmtVertOrient &rOri = pCell->GetFmt()->GetVertOrient();
2929 2286 : if ( text::VertOrientation::NONE != rOri.GetVertOrient() )
2930 1104 : pCell->InvalidatePrt();
2931 : }
2932 35014 : SwTabFrm *pTab = pCnt->FindTabFrm();
2933 35014 : if ( pTab != pLastTab )
2934 : {
2935 1542 : pLastTab = pTab;
2936 : // #i40606# - use <GetLastBoundRect()>
2937 : // instead of <GetCurrentBoundRect()>, because a recalculation
2938 : // of the bounding rectangle isn't intended here.
2939 2654 : if ( pTab->Frm().IsOver( pObj->GetLastBoundRect() ) ||
2940 1112 : pTab->Frm().IsOver( rRect ) )
2941 : {
2942 444 : if ( !pFlyFrm || !pFlyFrm->IsLowerOf( pTab ) )
2943 384 : pTab->InvalidatePrt();
2944 : }
2945 : }
2946 : }
2947 159712 : pCnt = pCnt->GetNextCntntFrm();
2948 : }
2949 : // #128702# - make code robust
2950 18076 : if ( pPage && pPage->GetSortedObjs() )
2951 : {
2952 17980 : pObj->GetOrdNum();
2953 17980 : const SwSortedObjs &rObjs = *pPage->GetSortedObjs();
2954 489260 : for ( size_t i = 0; i < rObjs.size(); ++i )
2955 : {
2956 471280 : SwAnchoredObject* pAnchoredObj = rObjs[i];
2957 471280 : if ( pAnchoredObj->ISA(SwFlyFrm) )
2958 : {
2959 154582 : if( pAnchoredObj->GetDrawObj() == pObj )
2960 6470 : continue;
2961 148112 : SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
2962 148112 : if ( pFly->Frm().Top() == FAR_AWAY )
2963 82126 : continue;
2964 :
2965 141812 : if ( !pFlyFrm ||
2966 24056 : (!pFly->IsLowerOf( pFlyFrm ) &&
2967 12028 : pFly->GetVirtDrawObj()->GetOrdNumDirect() < pObj->GetOrdNumDirect()))
2968 : {
2969 63798 : pCnt = pFly->ContainsCntnt();
2970 205412 : while ( pCnt )
2971 : {
2972 77816 : ::lcl_NotifyCntnt( pObj, pCnt, rRect, eHint );
2973 77816 : pCnt = pCnt->GetNextCntntFrm();
2974 : }
2975 : }
2976 65986 : if( pFly->IsFlyLayFrm() )
2977 : {
2978 4806 : if( pFly->Lower() && pFly->Lower()->IsColumnFrm() &&
2979 0 : pFly->Frm().Bottom() >= rRect.Top() &&
2980 0 : pFly->Frm().Top() <= rRect.Bottom() &&
2981 1602 : pFly->Frm().Right() >= rRect.Left() &&
2982 0 : pFly->Frm().Left() <= rRect.Right() )
2983 : {
2984 0 : pFly->InvalidateSize();
2985 : }
2986 : }
2987 : // Flys above myself might sidestep if they have an automatic
2988 : // alignment. This happens independently of my attributes since
2989 : // this might have been changed as well.
2990 193152 : else if ( pFly->IsFlyAtCntFrm() &&
2991 64384 : pObj->GetOrdNumDirect() <
2992 117812 : pFly->GetVirtDrawObj()->GetOrdNumDirect() &&
2993 65472 : pFlyFrm && !pFly->IsLowerOf( pFlyFrm ) )
2994 : {
2995 1088 : const SwFmtHoriOrient &rH = pFly->GetFmt()->GetHoriOrient();
2996 2208 : if ( text::HoriOrientation::NONE != rH.GetHoriOrient() &&
2997 32 : text::HoriOrientation::CENTER != rH.GetHoriOrient() &&
2998 1088 : ( !pFly->IsAutoPos() || text::RelOrientation::CHAR != rH.GetRelationOrient() ) &&
2999 0 : (pFly->Frm().Bottom() >= rRect.Top() &&
3000 0 : pFly->Frm().Top() <= rRect.Bottom()) )
3001 0 : pFly->InvalidatePos();
3002 : }
3003 : }
3004 : }
3005 : }
3006 18076 : if ( pFlyFrm && pAnchor->GetUpper() && pAnchor->IsInTab() )//MA_FLY_HEIGHT
3007 54 : pAnchor->GetUpper()->InvalidateSize();
3008 :
3009 : // #i82258# - make code robust
3010 18076 : SwViewShell* pSh = 0;
3011 36152 : if ( bInva && pPage &&
3012 18076 : 0 != (pSh = pPage->getRootFrm()->GetCurrShell()) )
3013 : {
3014 17730 : pSh->InvalidateWindows( rRect );
3015 : }
3016 : }
3017 :
3018 : /// Provides the Upper of an anchor in paragraph-bound objects. If the latter
3019 : /// is a chained border or a footnote, the "virtual" Upper might be returne.
3020 41151 : const SwFrm* GetVirtualUpper( const SwFrm* pFrm, const Point& rPos )
3021 : {
3022 41151 : if( pFrm->IsTxtFrm() )
3023 : {
3024 40451 : pFrm = pFrm->GetUpper();
3025 40451 : if( !pFrm->Frm().IsInside( rPos ) )
3026 : {
3027 6494 : if( pFrm->IsFtnFrm() )
3028 : {
3029 0 : const SwFtnFrm* pTmp = ((SwFtnFrm*)pFrm)->GetFollow();
3030 0 : while( pTmp )
3031 : {
3032 0 : if( pTmp->Frm().IsInside( rPos ) )
3033 0 : return pTmp;
3034 0 : pTmp = pTmp->GetFollow();
3035 : }
3036 : }
3037 : else
3038 : {
3039 6494 : SwFlyFrm* pTmp = (SwFlyFrm*)pFrm->FindFlyFrm();
3040 13008 : while( pTmp )
3041 : {
3042 20 : if( pTmp->Frm().IsInside( rPos ) )
3043 0 : return pTmp;
3044 20 : pTmp = pTmp->GetNextLink();
3045 : }
3046 : }
3047 : }
3048 : }
3049 41151 : return pFrm;
3050 : }
3051 :
3052 40961 : bool Is_Lower_Of( const SwFrm *pCurrFrm, const SdrObject* pObj )
3053 : {
3054 40961 : Point aPos;
3055 : const SwFrm* pFrm;
3056 40961 : if( pObj->ISA(SwVirtFlyDrawObj) )
3057 : {
3058 11915 : const SwFlyFrm* pFly = ( (SwVirtFlyDrawObj*)pObj )->GetFlyFrm();
3059 11915 : pFrm = pFly->GetAnchorFrm();
3060 11915 : aPos = pFly->Frm().Pos();
3061 : }
3062 : else
3063 : {
3064 29046 : pFrm = ( (SwDrawContact*)GetUserCall(pObj) )->GetAnchorFrm(pObj);
3065 29046 : aPos = pObj->GetCurrentBoundRect().TopLeft();
3066 : }
3067 : OSL_ENSURE( pFrm, "8-( Fly is lost in Space." );
3068 40961 : pFrm = GetVirtualUpper( pFrm, aPos );
3069 122099 : do
3070 122447 : { if ( pFrm == pCurrFrm )
3071 348 : return true;
3072 122099 : if( pFrm->IsFlyFrm() )
3073 : {
3074 2 : aPos = pFrm->Frm().Pos();
3075 2 : pFrm = GetVirtualUpper( ((const SwFlyFrm*)pFrm)->GetAnchorFrm(), aPos );
3076 : }
3077 : else
3078 122097 : pFrm = pFrm->GetUpper();
3079 : } while ( pFrm );
3080 40613 : return false;
3081 : }
3082 :
3083 : /// provides the area of a frame in that no Fly from another area can overlap
3084 211994 : const SwFrm *FindKontext( const SwFrm *pFrm, sal_uInt16 nAdditionalContextType )
3085 : {
3086 : const sal_uInt16 nTyp = FRM_ROOT | FRM_HEADER | FRM_FOOTER | FRM_FTNCONT |
3087 : FRM_FTN | FRM_FLY |
3088 : FRM_TAB | FRM_ROW | FRM_CELL |
3089 211994 : nAdditionalContextType;
3090 543524 : do
3091 755518 : { if ( pFrm->GetType() & nTyp )
3092 211994 : break;
3093 543524 : pFrm = pFrm->GetUpper();
3094 : } while( pFrm );
3095 211994 : return pFrm;
3096 : }
3097 :
3098 26638 : bool IsFrmInSameKontext( const SwFrm *pInnerFrm, const SwFrm *pFrm )
3099 : {
3100 26638 : const SwFrm *pKontext = FindKontext( pInnerFrm, 0 );
3101 :
3102 : const sal_uInt16 nTyp = FRM_ROOT | FRM_HEADER | FRM_FOOTER | FRM_FTNCONT |
3103 : FRM_FTN | FRM_FLY |
3104 26638 : FRM_TAB | FRM_ROW | FRM_CELL;
3105 112194 : do
3106 113728 : { if ( pFrm->GetType() & nTyp )
3107 : {
3108 26722 : if( pFrm == pKontext )
3109 138 : return true;
3110 26584 : if( pFrm->IsCellFrm() )
3111 1396 : return false;
3112 : }
3113 112194 : if( pFrm->IsFlyFrm() )
3114 : {
3115 84 : Point aPos( pFrm->Frm().Pos() );
3116 84 : pFrm = GetVirtualUpper( ((const SwFlyFrm*)pFrm)->GetAnchorFrm(), aPos );
3117 : }
3118 : else
3119 112110 : pFrm = pFrm->GetUpper();
3120 : } while( pFrm );
3121 :
3122 25104 : return false;
3123 : }
3124 :
3125 0 : static SwTwips lcl_CalcCellRstHeight( SwLayoutFrm *pCell )
3126 : {
3127 0 : if ( pCell->Lower()->IsCntntFrm() || pCell->Lower()->IsSctFrm() )
3128 : {
3129 0 : SwFrm *pLow = pCell->Lower();
3130 0 : long nHeight = 0, nFlyAdd = 0;
3131 0 : do
3132 : {
3133 0 : long nLow = pLow->Frm().Height();
3134 0 : if( pLow->IsTxtFrm() && ((SwTxtFrm*)pLow)->IsUndersized() )
3135 0 : nLow += ((SwTxtFrm*)pLow)->GetParHeight()-pLow->Prt().Height();
3136 0 : else if( pLow->IsSctFrm() && ((SwSectionFrm*)pLow)->IsUndersized() )
3137 0 : nLow += ((SwSectionFrm*)pLow)->Undersize();
3138 0 : nFlyAdd = std::max( 0L, nFlyAdd - nLow );
3139 0 : nFlyAdd = std::max( nFlyAdd, ::CalcHeightWithFlys( pLow ) );
3140 0 : nHeight += nLow;
3141 0 : pLow = pLow->GetNext();
3142 : } while ( pLow );
3143 0 : if ( nFlyAdd )
3144 0 : nHeight += nFlyAdd;
3145 :
3146 : // The border cannot be calculated based on PrtArea and Frm, since both can be invalid.
3147 0 : SwBorderAttrAccess aAccess( SwFrm::GetCache(), pCell );
3148 0 : const SwBorderAttrs &rAttrs = *aAccess.Get();
3149 0 : nHeight += rAttrs.CalcTop() + rAttrs.CalcBottom();
3150 :
3151 0 : return pCell->Frm().Height() - nHeight;
3152 : }
3153 : else
3154 : {
3155 0 : long nRstHeight = 0;
3156 0 : SwFrm *pLow = pCell->Lower();
3157 0 : do
3158 0 : { nRstHeight += ::CalcRowRstHeight( (SwLayoutFrm*)pLow );
3159 0 : pLow = pLow->GetNext();
3160 :
3161 : } while ( pLow );
3162 :
3163 0 : return nRstHeight;
3164 : }
3165 : }
3166 :
3167 0 : SwTwips CalcRowRstHeight( SwLayoutFrm *pRow )
3168 : {
3169 0 : SwTwips nRstHeight = LONG_MAX;
3170 0 : SwLayoutFrm *pLow = (SwLayoutFrm*)pRow->Lower();
3171 0 : while ( pLow )
3172 : {
3173 0 : nRstHeight = std::min( nRstHeight, ::lcl_CalcCellRstHeight( pLow ) );
3174 0 : pLow = (SwLayoutFrm*)pLow->GetNext();
3175 : }
3176 0 : return nRstHeight;
3177 : }
3178 :
3179 5492 : const SwFrm* FindPage( const SwRect &rRect, const SwFrm *pPage )
3180 : {
3181 5492 : if ( !rRect.IsOver( pPage->Frm() ) )
3182 : {
3183 364 : const SwRootFrm* pRootFrm = static_cast<const SwRootFrm*>(pPage->GetUpper());
3184 364 : const SwFrm* pTmpPage = pRootFrm ? pRootFrm->GetPageAtPos( rRect.TopLeft(), &rRect.SSize(), true ) : 0;
3185 364 : if ( pTmpPage )
3186 348 : pPage = pTmpPage;
3187 : }
3188 :
3189 5492 : return pPage;
3190 : }
3191 :
3192 1170070 : class SwFrmHolder : private SfxListener
3193 : {
3194 : SwFrm* pFrm;
3195 : bool bSet;
3196 : virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) SAL_OVERRIDE;
3197 : public:
3198 1170070 : SwFrmHolder() : pFrm(0), bSet(false) {}
3199 : void SetFrm( SwFrm* pHold );
3200 6696 : SwFrm* GetFrm() { return pFrm; }
3201 : void Reset();
3202 372997 : bool IsSet() { return bSet; }
3203 : };
3204 :
3205 6696 : void SwFrmHolder::SetFrm( SwFrm* pHold )
3206 : {
3207 6696 : bSet = true;
3208 6696 : pFrm = pHold;
3209 6696 : StartListening(*pHold);
3210 6696 : }
3211 :
3212 1536371 : void SwFrmHolder::Reset()
3213 : {
3214 1536371 : if (pFrm)
3215 0 : EndListening(*pFrm);
3216 1536371 : bSet = false;
3217 1536371 : pFrm = 0;
3218 1536371 : }
3219 :
3220 0 : void SwFrmHolder::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
3221 : {
3222 0 : const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
3223 0 : if ( pSimpleHint && pSimpleHint->GetId() == SFX_HINT_DYING && &rBC == pFrm )
3224 : {
3225 0 : pFrm = 0;
3226 : }
3227 0 : }
3228 :
3229 1170070 : SwFrm* GetFrmOfModify( const SwRootFrm* pLayout, SwModify const& rMod, sal_uInt16 const nFrmType,
3230 : const Point* pPoint, const SwPosition *pPos, const bool bCalcFrm )
3231 : {
3232 1170070 : SwFrm *pMinFrm = 0, *pTmpFrm;
3233 1170070 : SwFrmHolder aHolder;
3234 1170070 : SwRect aCalcRect;
3235 1170070 : bool bClientIterChanged = false;
3236 :
3237 2340140 : SwIterator<SwFrm,SwModify> aIter( rMod );
3238 1170070 : do {
3239 1170070 : pMinFrm = 0;
3240 1170070 : aHolder.Reset();
3241 1170070 : sal_uInt64 nMinDist = 0;
3242 1170070 : bClientIterChanged = false;
3243 :
3244 1374716 : for( pTmpFrm = aIter.First(); pTmpFrm; pTmpFrm = aIter.Next() )
3245 : {
3246 3397380 : if( pTmpFrm->GetType() & nFrmType &&
3247 4462932 : ( !pLayout || pLayout == pTmpFrm->getRootFrm() ) &&
3248 2260230 : (!pTmpFrm->IsFlowFrm() ||
3249 1127770 : !SwFlowFrm::CastFlowFrm( pTmpFrm )->IsFollow() ))
3250 : {
3251 1073548 : if( pPoint )
3252 : {
3253 : // watch for Frm being deleted
3254 372997 : if ( pMinFrm )
3255 6696 : aHolder.SetFrm( pMinFrm );
3256 : else
3257 366301 : aHolder.Reset();
3258 :
3259 372997 : if( bCalcFrm )
3260 : {
3261 : // - format parent Writer
3262 : // fly frame, if it isn't been formatted yet.
3263 : // Note: The Writer fly frame could be the frame itself.
3264 17002 : SwFlyFrm* pFlyFrm( pTmpFrm->FindFlyFrm() );
3265 17002 : if ( pFlyFrm &&
3266 17002 : pFlyFrm->Frm().Pos().X() == FAR_AWAY &&
3267 0 : pFlyFrm->Frm().Pos().Y() == FAR_AWAY )
3268 : {
3269 0 : SwObjectFormatter::FormatObj( *pFlyFrm );
3270 : }
3271 17002 : pTmpFrm->Calc();
3272 : }
3273 :
3274 : // #127369#
3275 : // aIter.IsChanged checks if the current pTmpFrm has been deleted while
3276 : // it is the current iterator
3277 : // FrmHolder watches for deletion of the current pMinFrm
3278 372997 : if( aIter.IsChanged() || ( aHolder.IsSet() && !aHolder.GetFrm() ) )
3279 : {
3280 : // restart iteration
3281 0 : bClientIterChanged = true;
3282 227263 : break;
3283 : }
3284 :
3285 : // for Flys go via the parent if the Fly is not yet "formatted"
3286 1105517 : if( !bCalcFrm && pTmpFrm->GetType() & FRM_FLY &&
3287 7056 : ((SwFlyFrm*)pTmpFrm)->GetAnchorFrm() &&
3288 376525 : FAR_AWAY == pTmpFrm->Frm().Pos().getX() &&
3289 0 : FAR_AWAY == pTmpFrm->Frm().Pos().getY() )
3290 0 : aCalcRect = ((SwFlyFrm*)pTmpFrm)->GetAnchorFrm()->Frm();
3291 : else
3292 372997 : aCalcRect = pTmpFrm->Frm();
3293 :
3294 372997 : if ( aCalcRect.IsInside( *pPoint ) )
3295 : {
3296 227263 : pMinFrm = pTmpFrm;
3297 227263 : break;
3298 : }
3299 :
3300 : // Point not in rectangle. Compare distances:
3301 145734 : const Point aCalcRectCenter = aCalcRect.Center();
3302 145734 : const Point aDiff = aCalcRectCenter - *pPoint;
3303 145734 : const sal_uInt64 nCurrentDist = sal_Int64(aDiff.getX()) * sal_Int64(aDiff.getX()) + sal_Int64(aDiff.getY()) * sal_Int64(aDiff.getY()); // opt: no sqrt
3304 145734 : if ( !pMinFrm || nCurrentDist < nMinDist )
3305 : {
3306 140322 : pMinFrm = pTmpFrm;
3307 140322 : nMinDist = nCurrentDist;
3308 : }
3309 : }
3310 : else
3311 : {
3312 : // if no pPoint is provided, take the first one
3313 700551 : pMinFrm = pTmpFrm;
3314 700551 : break;
3315 : }
3316 : }
3317 : }
3318 : } while( bClientIterChanged );
3319 :
3320 1170070 : if( pPos && pMinFrm && pMinFrm->IsTxtFrm() )
3321 361963 : return ((SwTxtFrm*)pMinFrm)->GetFrmAtPos( *pPos );
3322 :
3323 1978177 : return pMinFrm;
3324 : }
3325 :
3326 160830 : bool IsExtraData( const SwDoc *pDoc )
3327 : {
3328 160830 : const SwLineNumberInfo &rInf = pDoc->GetLineNumberInfo();
3329 321308 : return rInf.IsPaintLineNumbers() ||
3330 324373 : rInf.IsCountInFlys() ||
3331 320956 : ((sal_Int16)SW_MOD()->GetRedlineMarkPos() != text::HoriOrientation::NONE &&
3332 321308 : !pDoc->getIDocumentRedlineAccess().GetRedlineTbl().empty());
3333 : }
3334 :
3335 : // OD 22.09.2003 #110978#
3336 314 : const SwRect SwPageFrm::PrtWithoutHeaderAndFooter() const
3337 : {
3338 314 : SwRect aPrtWithoutHeaderFooter( Prt() );
3339 314 : aPrtWithoutHeaderFooter.Pos() += Frm().Pos();
3340 :
3341 314 : const SwFrm* pLowerFrm = Lower();
3342 1174 : while ( pLowerFrm )
3343 : {
3344 : // Note: independent on text direction page header and page footer are
3345 : // always at top respectively at bottom of the page frame.
3346 546 : if ( pLowerFrm->IsHeaderFrm() )
3347 : {
3348 232 : aPrtWithoutHeaderFooter.Top( aPrtWithoutHeaderFooter.Top() +
3349 232 : pLowerFrm->Frm().Height() );
3350 : }
3351 546 : if ( pLowerFrm->IsFooterFrm() )
3352 : {
3353 0 : aPrtWithoutHeaderFooter.Bottom( aPrtWithoutHeaderFooter.Bottom() -
3354 0 : pLowerFrm->Frm().Height() );
3355 : }
3356 :
3357 546 : pLowerFrm = pLowerFrm->GetNext();
3358 : }
3359 :
3360 314 : return aPrtWithoutHeaderFooter;
3361 : }
3362 :
3363 : /** method to determine the spacing values of a frame
3364 :
3365 : OD 2004-03-10 #i28701#
3366 : OD 2009-08-28 #i102458#
3367 : Add output parameter <obIsLineSpacingProportional>
3368 : */
3369 83275 : void GetSpacingValuesOfFrm( const SwFrm& rFrm,
3370 : SwTwips& onLowerSpacing,
3371 : SwTwips& onLineSpacing,
3372 : bool& obIsLineSpacingProportional )
3373 : {
3374 83275 : if ( !rFrm.IsFlowFrm() )
3375 : {
3376 0 : onLowerSpacing = 0;
3377 0 : onLineSpacing = 0;
3378 : }
3379 : else
3380 : {
3381 83275 : const SvxULSpaceItem& rULSpace = rFrm.GetAttrSet()->GetULSpace();
3382 83275 : onLowerSpacing = rULSpace.GetLower();
3383 :
3384 83275 : onLineSpacing = 0;
3385 83275 : obIsLineSpacingProportional = false;
3386 83275 : if ( rFrm.IsTxtFrm() )
3387 : {
3388 80443 : onLineSpacing = static_cast<const SwTxtFrm&>(rFrm).GetLineSpace();
3389 : obIsLineSpacingProportional =
3390 100259 : onLineSpacing != 0 &&
3391 100259 : static_cast<const SwTxtFrm&>(rFrm).GetLineSpace( true ) == 0;
3392 : }
3393 :
3394 : OSL_ENSURE( onLowerSpacing >= 0 && onLineSpacing >= 0,
3395 : "<GetSpacingValuesOfFrm(..)> - spacing values aren't positive!" );
3396 : }
3397 83275 : }
3398 :
3399 : /// get the content of the table cell, skipping content from nested tables
3400 2 : const SwCntntFrm* GetCellCntnt( const SwLayoutFrm& rCell )
3401 : {
3402 2 : const SwCntntFrm* pCntnt = rCell.ContainsCntnt();
3403 2 : const SwTabFrm* pTab = rCell.FindTabFrm();
3404 :
3405 4 : while ( pCntnt && rCell.IsAnLower( pCntnt ) )
3406 : {
3407 2 : const SwTabFrm* pTmpTab = pCntnt->FindTabFrm();
3408 2 : if ( pTmpTab != pTab )
3409 : {
3410 0 : pCntnt = pTmpTab->FindLastCntnt();
3411 0 : if ( pCntnt )
3412 :
3413 0 : pCntnt = pCntnt->FindNextCnt();
3414 :
3415 : }
3416 : else
3417 2 : break;
3418 : }
3419 2 : return pCntnt;
3420 : }
3421 :
3422 : /// Can be used to check if a frame has been deleted
3423 2 : bool SwDeletionChecker::HasBeenDeleted()
3424 : {
3425 2 : if ( !mpFrm || !mpRegIn )
3426 0 : return false;
3427 :
3428 2 : SwIterator<SwFrm,SwModify> aIter(*mpRegIn);
3429 2 : SwFrm* pLast = aIter.First();
3430 4 : while ( pLast )
3431 : {
3432 2 : if ( pLast == mpFrm )
3433 2 : return false;
3434 0 : pLast = aIter.Next();
3435 : }
3436 :
3437 0 : return true;
3438 270 : }
3439 :
3440 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|