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