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