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 <ndole.hxx>
21 : #include <svl/itemiter.hxx>
22 : #include <fmtfsize.hxx>
23 : #include <fmthdft.hxx>
24 : #include <fmtclds.hxx>
25 : #include <fmtpdsc.hxx>
26 : #include <fmtornt.hxx>
27 : #include <fmtsrnd.hxx>
28 : #include <ftninfo.hxx>
29 : #include <tgrditem.hxx>
30 : #include <viewopt.hxx>
31 : #include <docsh.hxx>
32 : #include <wrtsh.hxx>
33 : #include <view.hxx>
34 : #include <edtwin.hxx>
35 :
36 : #include "viewimp.hxx"
37 : #include "pagefrm.hxx"
38 : #include "rootfrm.hxx"
39 : #include <IDocumentSettingAccess.hxx>
40 : #include <IDocumentFieldsAccess.hxx>
41 : #include "dcontact.hxx"
42 : #include "hints.hxx"
43 :
44 : #include "ftnidx.hxx"
45 : #include "bodyfrm.hxx"
46 : #include "ftnfrm.hxx"
47 : #include "tabfrm.hxx"
48 : #include "txtfrm.hxx"
49 : #include "layact.hxx"
50 : #include "flyfrms.hxx"
51 : #include "htmltbl.hxx"
52 : #include "pagedesc.hxx"
53 : #include <editeng/frmdiritem.hxx>
54 : #include <sortedobjs.hxx>
55 : #include <switerator.hxx>
56 : #include <txtfly.hxx>
57 :
58 : using namespace ::com::sun::star;
59 :
60 8954 : SwBodyFrm::SwBodyFrm( SwFrmFmt *pFmt, SwFrm* pSib ):
61 8954 : SwLayoutFrm( pFmt, pSib )
62 : {
63 8954 : mnType = FRMC_BODY;
64 8954 : }
65 :
66 16928 : void SwBodyFrm::Format( const SwBorderAttrs * )
67 : {
68 : // Formatting of the body is too simple, thus, it gets an own format method.
69 : // Borders etc. are not taken into account here.
70 : // With is taken from the PrtArea of the Upper, height is the height of the
71 : // PrtArea of the Upper minus any neighbors (for robustness).
72 : // The PrtArea has always the size of the frame.
73 :
74 16928 : if ( !mbValidSize )
75 : {
76 12650 : SwTwips nHeight = GetUpper()->Prt().Height();
77 12650 : SwTwips nWidth = GetUpper()->Prt().Width();
78 12650 : const SwFrm *pFrm = GetUpper()->Lower();
79 12704 : do
80 : {
81 12704 : if ( pFrm != this )
82 : {
83 54 : if( pFrm->IsVertical() )
84 0 : nWidth -= pFrm->Frm().Width();
85 : else
86 54 : nHeight -= pFrm->Frm().Height();
87 : }
88 12704 : pFrm = pFrm->GetNext();
89 : } while ( pFrm );
90 12650 : if ( nHeight < 0 )
91 0 : nHeight = 0;
92 12650 : Frm().Height( nHeight );
93 :
94 12650 : if( IsVertical() && !IsVertLR() && !IsReverse() && nWidth != Frm().Width() )
95 0 : Frm().Pos().setX(Frm().Pos().getX() + Frm().Width() - nWidth);
96 12650 : Frm().Width( nWidth );
97 : }
98 :
99 16928 : bool bNoGrid = true;
100 16928 : if( GetUpper()->IsPageFrm() && ((SwPageFrm*)GetUpper())->HasGrid() )
101 : {
102 : SwTextGridItem const*const pGrid(
103 30 : GetGridItem(static_cast<SwPageFrm*>(GetUpper())));
104 30 : if( pGrid )
105 : {
106 30 : bNoGrid = false;
107 30 : long nSum = pGrid->GetBaseHeight() + pGrid->GetRubyHeight();
108 30 : SWRECTFN( this )
109 30 : long nSize = (Frm().*fnRect->fnGetWidth)();
110 30 : long nBorder = 0;
111 30 : if( GRID_LINES_CHARS == pGrid->GetGridType() )
112 : {
113 : //for textgrid refactor
114 0 : SwDoc *pDoc = GetFmt()->GetDoc();
115 0 : nBorder = nSize % (GetGridWidth(*pGrid, *pDoc));
116 0 : nSize -= nBorder;
117 0 : nBorder /= 2;
118 : }
119 30 : (Prt().*fnRect->fnSetPosX)( nBorder );
120 30 : (Prt().*fnRect->fnSetWidth)( nSize );
121 :
122 : // Height of body frame:
123 30 : nBorder = (Frm().*fnRect->fnGetHeight)();
124 :
125 : // Number of possible lines in area of body frame:
126 30 : long nNumberOfLines = nBorder / nSum;
127 30 : if( nNumberOfLines > pGrid->GetLines() )
128 12 : nNumberOfLines = pGrid->GetLines();
129 :
130 : // Space required for nNumberOfLines lines:
131 30 : nSize = nNumberOfLines * nSum;
132 30 : nBorder -= nSize;
133 30 : nBorder /= 2;
134 :
135 : // #i21774# Footnotes and centering the grid does not work together:
136 30 : const bool bAdjust = ((SwPageFrm*)GetUpper())->GetFmt()->GetDoc()->
137 30 : GetFtnIdxs().empty();
138 :
139 30 : (Prt().*fnRect->fnSetPosY)( bAdjust ? nBorder : 0 );
140 30 : (Prt().*fnRect->fnSetHeight)( nSize );
141 : }
142 : }
143 16928 : if( bNoGrid )
144 : {
145 16898 : Prt().Pos().setX(0);
146 16898 : Prt().Pos().setY(0);
147 16898 : Prt().Height( Frm().Height() );
148 16898 : Prt().Width( Frm().Width() );
149 : }
150 16928 : mbValidSize = mbValidPrtArea = true;
151 16928 : }
152 :
153 7532 : SwPageFrm::SwPageFrm( SwFrmFmt *pFmt, SwFrm* pSib, SwPageDesc *pPgDsc ) :
154 : SwFtnBossFrm( pFmt, pSib ),
155 : pSortedObjs( 0 ),
156 : pDesc( pPgDsc ),
157 7532 : nPhyPageNum( 0 )
158 : {
159 7532 : SetDerivedVert( false );
160 7532 : SetDerivedR2L( false );
161 7532 : if( pDesc )
162 : {
163 7532 : bHasGrid = true;
164 7532 : SwTextGridItem const*const pGrid(GetGridItem(this));
165 7532 : if( !pGrid )
166 7516 : bHasGrid = false;
167 : }
168 : else
169 0 : bHasGrid = false;
170 7532 : SetMaxFtnHeight( pPgDsc->GetFtnInfo().GetHeight() ?
171 7532 : pPgDsc->GetFtnInfo().GetHeight() : LONG_MAX ),
172 7532 : mnType = FRMC_PAGE;
173 7532 : bInvalidLayout = bInvalidCntnt = bInvalidSpelling = bInvalidSmartTags = bInvalidAutoCmplWrds = bInvalidWordCount = true;
174 7532 : bInvalidFlyLayout = bInvalidFlyCntnt = bInvalidFlyInCnt = bFtnPage = bEndNotePage = false;
175 :
176 7532 : SwViewShell *pSh = getRootFrm()->GetCurrShell();
177 7532 : const bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
178 7532 : if ( bBrowseMode )
179 : {
180 6 : Frm().Height( 0 );
181 6 : long nWidth = pSh->VisArea().Width();
182 6 : if ( !nWidth )
183 6 : nWidth = 5000L; //aendert sich sowieso
184 6 : Frm().Width ( nWidth );
185 : }
186 : else
187 7526 : Frm().SSize( pFmt->GetFrmSize().GetSize() );
188 :
189 : // create and insert body area if it is not a blank page
190 7532 : SwDoc *pDoc = pFmt->GetDoc();
191 7532 : if ( false == (bEmptyPage = (pFmt == pDoc->GetEmptyPageFmt())) )
192 : {
193 7476 : bEmptyPage = false;
194 7476 : Calc(); // so that the PrtArea is correct
195 7476 : SwBodyFrm *pBodyFrm = new SwBodyFrm( pDoc->GetDfltFrmFmt(), this );
196 7476 : pBodyFrm->ChgSize( Prt().SSize() );
197 7476 : pBodyFrm->Paste( this );
198 7476 : pBodyFrm->Calc(); // so that the columns can be inserted correctly
199 7476 : pBodyFrm->InvalidatePos();
200 :
201 7476 : if ( bBrowseMode )
202 6 : _InvalidateSize();
203 :
204 : // insert header/footer,, but only if active.
205 7476 : if ( pFmt->GetHeader().IsActive() )
206 1690 : PrepareHeader();
207 7476 : if ( pFmt->GetFooter().IsActive() )
208 1924 : PrepareFooter();
209 :
210 7476 : const SwFmtCol &rCol = pFmt->GetCol();
211 7476 : if ( rCol.GetNumCols() > 1 )
212 : {
213 28 : const SwFmtCol aOld; //ChgColumns() needs an old value
214 28 : pBodyFrm->ChgColumns( aOld, rCol );
215 : }
216 : }
217 7532 : }
218 :
219 22584 : SwPageFrm::~SwPageFrm()
220 : {
221 : // Cleanup the header-footer controls in the SwEditWin
222 7528 : SwViewShell* pSh = getRootFrm()->GetCurrShell();
223 7528 : SwWrtShell* pWrtSh = dynamic_cast< SwWrtShell* >( pSh );
224 7528 : if ( pWrtSh )
225 : {
226 366 : SwEditWin& rEditWin = pWrtSh->GetView().GetEditWin();
227 366 : rEditWin.GetFrameControlsManager( ).RemoveControls( this );
228 : }
229 :
230 : // empty FlyContainer, deletion of the Flys is done by the anchor (in base class SwFrm)
231 7528 : if ( pSortedObjs )
232 : {
233 : // Objects can be anchored at pages that are before their anchors (why ever...).
234 : // In such cases, we would access already freed memory.
235 6122 : for ( size_t i = 0; i < pSortedObjs->size(); ++i )
236 : {
237 4516 : SwAnchoredObject* pAnchoredObj = (*pSortedObjs)[i];
238 4516 : pAnchoredObj->SetPageFrm( 0L );
239 : }
240 1606 : delete pSortedObjs;
241 1606 : pSortedObjs = 0; // reset to zero to prevent problems when detaching the Flys
242 : }
243 :
244 7528 : if ( !IsEmptyPage() ) //#59184# unnessesary for empty pages
245 : {
246 : // prevent access to destroyed pages
247 7472 : SwDoc *pDoc = GetFmt() ? GetFmt()->GetDoc() : NULL;
248 7472 : if( pDoc && !pDoc->IsInDtor() )
249 : {
250 7472 : if ( pSh )
251 : {
252 340 : SwViewImp *pImp = pSh->Imp();
253 340 : pImp->SetFirstVisPageInvalid();
254 340 : if ( pImp->IsAction() )
255 322 : pImp->GetLayAction().SetAgain();
256 : // OD 12.02.2003 #i9719#, #105645# - retouche area of page
257 : // including border and shadow area.
258 340 : const bool bRightSidebar = (SidebarPosition() == sw::sidebarwindows::SIDEBAR_RIGHT);
259 340 : SwRect aRetoucheRect;
260 340 : SwPageFrm::GetBorderAndShadowBoundRect( Frm(), pSh, aRetoucheRect, IsLeftShadowNeeded(), IsRightShadowNeeded(), bRightSidebar );
261 340 : pSh->AddPaintRect( aRetoucheRect );
262 : }
263 : }
264 : }
265 15056 : }
266 :
267 10 : void SwPageFrm::CheckGrid( bool bInvalidate )
268 : {
269 10 : bool bOld = bHasGrid;
270 10 : bHasGrid = true;
271 10 : SwTextGridItem const*const pGrid(GetGridItem(this));
272 10 : bHasGrid = 0 != pGrid;
273 10 : if( bInvalidate || bOld != bHasGrid )
274 : {
275 10 : SwLayoutFrm* pBody = FindBodyCont();
276 10 : if( pBody )
277 : {
278 10 : pBody->InvalidatePrt();
279 10 : SwCntntFrm* pFrm = pBody->ContainsCntnt();
280 118 : while( pBody->IsAnLower( pFrm ) )
281 : {
282 98 : ((SwTxtFrm*)pFrm)->Prepare( PREP_CLEAR );
283 98 : pFrm = pFrm->GetNextCntntFrm();
284 : }
285 : }
286 10 : SetCompletePaint();
287 : }
288 10 : }
289 :
290 13686 : void SwPageFrm::CheckDirection( bool bVert )
291 : {
292 : sal_uInt16 nDir =
293 13686 : ((SvxFrameDirectionItem&)GetFmt()->GetFmtAttr( RES_FRAMEDIR )).GetValue();
294 13686 : if( bVert )
295 : {
296 7700 : if( FRMDIR_HORI_LEFT_TOP == nDir || FRMDIR_HORI_RIGHT_TOP == nDir )
297 : {
298 7654 : mbVertLR = false;
299 7654 : mbVertical = false;
300 : }
301 : else
302 : {
303 46 : const SwViewShell *pSh = getRootFrm()->GetCurrShell();
304 46 : if( pSh && pSh->GetViewOptions()->getBrowseMode() )
305 : {
306 0 : mbVertLR = false;
307 0 : mbVertical = false;
308 : }
309 : else
310 : {
311 46 : mbVertical = true;
312 :
313 46 : if(FRMDIR_VERT_TOP_RIGHT == nDir)
314 0 : mbVertLR = false;
315 46 : else if(FRMDIR_VERT_TOP_LEFT==nDir)
316 0 : mbVertLR = true;
317 : }
318 : }
319 :
320 7700 : mbReverse = false;
321 7700 : mbInvalidVert = false;
322 : }
323 : else
324 : {
325 5986 : if( FRMDIR_HORI_RIGHT_TOP == nDir )
326 32 : mbRightToLeft = true;
327 : else
328 5954 : mbRightToLeft = false;
329 5986 : mbInvalidR2L = false;
330 : }
331 13686 : }
332 :
333 : /// create specific Flys for this page and format generic content
334 18678 : static void lcl_FormatLay( SwLayoutFrm *pLay )
335 : {
336 : // format all LayoutFrms - no tables, Flys etc.
337 :
338 18678 : SwFrm *pTmp = pLay->Lower();
339 : // first the low-level ones
340 54698 : while ( pTmp )
341 : {
342 17342 : if ( pTmp->GetType() & 0x00FF )
343 11202 : ::lcl_FormatLay( (SwLayoutFrm*)pTmp );
344 17342 : pTmp = pTmp->GetNext();
345 : }
346 18678 : pLay->Calc();
347 18678 : }
348 :
349 : /// Create Flys or register draw objects
350 7484 : static void lcl_MakeObjs( const SwFrmFmts &rTbl, SwPageFrm *pPage )
351 : {
352 : // formats are in the special table of the document
353 :
354 25580 : for ( size_t i = 0; i < rTbl.size(); ++i )
355 : {
356 : SdrObject *pSdrObj;
357 18096 : SwFrmFmt *pFmt = rTbl[i];
358 18096 : const SwFmtAnchor &rAnch = pFmt->GetAnchor();
359 18096 : if ( rAnch.GetPageNum() == pPage->GetPhyPageNum() )
360 : {
361 322 : if( rAnch.GetCntntAnchor() )
362 : {
363 0 : if (FLY_AT_PAGE == rAnch.GetAnchorId())
364 : {
365 0 : SwFmtAnchor aAnch( rAnch );
366 0 : aAnch.SetAnchor( 0 );
367 0 : pFmt->SetFmtAttr( aAnch );
368 : }
369 : else
370 0 : continue;
371 : }
372 :
373 : // is it a border or a SdrObject?
374 322 : bool bSdrObj = RES_DRAWFRMFMT == pFmt->Which();
375 322 : pSdrObj = 0;
376 322 : if ( bSdrObj && 0 == (pSdrObj = pFmt->FindSdrObject()) )
377 : {
378 : OSL_FAIL( "DrawObject not found." );
379 0 : pFmt->GetDoc()->DelFrmFmt( pFmt );
380 0 : --i;
381 0 : continue;
382 : }
383 : // The object might be anchored to another page, e.g. when inserting
384 : // a new page due to a page descriptor change. In such cases, the
385 : // object needs to be moved.
386 : // In some cases the object is already anchored to the correct page.
387 : // This will be handled here and does not need to be coded extra.
388 322 : SwPageFrm *pPg = pPage->IsEmptyPage() ? (SwPageFrm*)pPage->GetNext() : pPage;
389 322 : if ( bSdrObj )
390 : {
391 : // OD 23.06.2003 #108784# - consider 'virtual' drawing objects
392 : SwDrawContact *pContact =
393 50 : static_cast<SwDrawContact*>(::GetUserCall(pSdrObj));
394 50 : if ( pSdrObj->ISA(SwDrawVirtObj) )
395 : {
396 0 : SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(pSdrObj);
397 0 : if ( pContact )
398 : {
399 0 : pDrawVirtObj->RemoveFromWriterLayout();
400 0 : pDrawVirtObj->RemoveFromDrawingPage();
401 0 : pPg->AppendDrawObj( *(pContact->GetAnchoredObj( pDrawVirtObj )) );
402 : }
403 : }
404 : else
405 : {
406 50 : if ( pContact->GetAnchorFrm() )
407 0 : pContact->DisconnectFromLayout( false );
408 50 : pPg->AppendDrawObj( *(pContact->GetAnchoredObj( pSdrObj )) );
409 : }
410 : }
411 : else
412 : {
413 272 : SwIterator<SwFlyFrm,SwFmt> aIter( *pFmt );
414 272 : SwFlyFrm *pFly = aIter.First();
415 272 : if ( pFly)
416 : {
417 124 : if( pFly->GetAnchorFrm() )
418 124 : pFly->AnchorFrm()->RemoveFly( pFly );
419 : }
420 : else
421 148 : pFly = new SwFlyLayFrm( (SwFlyFrmFmt*)pFmt, pPg, pPg );
422 272 : pPg->AppendFly( pFly );
423 272 : ::RegistFlys( pPg, pFly );
424 : }
425 : }
426 : }
427 7484 : }
428 :
429 7532 : void SwPageFrm::PreparePage( bool bFtn )
430 : {
431 7532 : SetFtnPage( bFtn );
432 :
433 : // #i82258#
434 : // Due to made change on OOo 2.0 code line, method <::lcl_FormatLay(..)> has
435 : // the side effect, that the content of page header and footer are formatted.
436 : // For this formatting it is needed that the anchored objects are registered
437 : // at the <SwPageFrm> instance.
438 : // Thus, first calling <::RegistFlys(..)>, then call <::lcl_FormatLay(..)>
439 7532 : ::RegistFlys( this, this );
440 :
441 7532 : if ( Lower() )
442 : {
443 7476 : ::lcl_FormatLay( this );
444 : }
445 :
446 : // Flys and draw objects that are still attached to the document.
447 : // Footnote pages do not have page-bound Flys!
448 : // There might be Flys or draw objects that want to be placed on
449 : // empty pages, however, the empty pages ignore that and the following
450 : // pages take care of them.
451 7532 : if ( !bFtn && !IsEmptyPage() )
452 : {
453 7452 : SwDoc *pDoc = GetFmt()->GetDoc();
454 :
455 7452 : if ( GetPrev() && ((SwPageFrm*)GetPrev())->IsEmptyPage() )
456 32 : lcl_MakeObjs( *pDoc->GetSpzFrmFmts(), (SwPageFrm*)GetPrev() );
457 7452 : lcl_MakeObjs( *pDoc->GetSpzFrmFmts(), this );
458 :
459 : // format footer/ header
460 7452 : SwLayoutFrm *pLow = (SwLayoutFrm*)Lower();
461 25970 : while ( pLow )
462 : {
463 11066 : if ( pLow->GetType() & (FRMTYPE_HEADER|FRMTYPE_FOOTER) )
464 : {
465 0 : SwCntntFrm *pCntnt = pLow->ContainsCntnt();
466 0 : while ( pCntnt && pLow->IsAnLower( pCntnt ) )
467 : {
468 0 : pCntnt->OptCalc(); // not the predecessors
469 0 : pCntnt = pCntnt->GetNextCntntFrm();
470 : }
471 : }
472 11066 : pLow = (SwLayoutFrm*)pLow->GetNext();
473 : }
474 : }
475 7532 : }
476 :
477 422 : void SwPageFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew )
478 : {
479 422 : SwViewShell *pSh = getRootFrm()->GetCurrShell();
480 422 : if ( pSh )
481 422 : pSh->SetFirstVisPageInvalid();
482 422 : sal_uInt8 nInvFlags = 0;
483 :
484 422 : if( pNew && RES_ATTRSET_CHG == pNew->Which() )
485 : {
486 248 : SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
487 496 : SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
488 496 : SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
489 496 : SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
490 : while( true )
491 : {
492 : _UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(),
493 : (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags,
494 282 : &aOldSet, &aNewSet );
495 282 : if( aNIter.IsAtEnd() )
496 248 : break;
497 34 : aNIter.NextItem();
498 34 : aOIter.NextItem();
499 : }
500 248 : if ( aOldSet.Count() || aNewSet.Count() )
501 466 : SwLayoutFrm::Modify( &aOldSet, &aNewSet );
502 : }
503 : else
504 174 : _UpdateAttr( pOld, pNew, nInvFlags );
505 :
506 422 : if ( nInvFlags != 0 )
507 : {
508 206 : InvalidatePage( this );
509 206 : if ( nInvFlags & 0x01 )
510 176 : _InvalidatePrt();
511 206 : if ( nInvFlags & 0x02 )
512 176 : SetCompletePaint();
513 206 : if ( nInvFlags & 0x04 && GetNext() )
514 8 : GetNext()->InvalidatePos();
515 206 : if ( nInvFlags & 0x08 )
516 28 : PrepareHeader();
517 206 : if ( nInvFlags & 0x10 )
518 40 : PrepareFooter();
519 206 : if ( nInvFlags & 0x20 )
520 10 : CheckGrid( nInvFlags & 0x40 );
521 : }
522 422 : }
523 :
524 456 : void SwPageFrm::_UpdateAttr( const SfxPoolItem *pOld, const SfxPoolItem *pNew,
525 : sal_uInt8 &rInvFlags,
526 : SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
527 : {
528 456 : bool bClear = true;
529 456 : const sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
530 456 : switch( nWhich )
531 : {
532 : case RES_FMT_CHG:
533 : {
534 : // If the frame format is changed, several things might also change:
535 : // 1. columns:
536 : assert(pOld && pNew); //FMT_CHG Missing Format
537 174 : const SwFmt* pOldFmt = pOld ? ((SwFmtChg*)pOld)->pChangedFmt : NULL;
538 174 : const SwFmt* pNewFmt = pNew ? ((SwFmtChg*)pNew)->pChangedFmt : NULL;
539 : assert(pOldFmt && pNewFmt); //FMT_CHG Missing Format
540 174 : if (pOldFmt && pNewFmt)
541 : {
542 174 : const SwFmtCol &rOldCol = pOldFmt->GetCol();
543 174 : const SwFmtCol &rNewCol = pNewFmt->GetCol();
544 174 : if( rOldCol != rNewCol )
545 : {
546 0 : SwLayoutFrm *pB = FindBodyCont();
547 : OSL_ENSURE( pB, "Seite ohne Body." );
548 0 : pB->ChgColumns( rOldCol, rNewCol );
549 0 : rInvFlags |= 0x20;
550 : }
551 :
552 : // 2. header and footer:
553 174 : const SwFmtHeader &rOldH = pOldFmt->GetHeader();
554 174 : const SwFmtHeader &rNewH = pNewFmt->GetHeader();
555 174 : if( rOldH != rNewH )
556 16 : rInvFlags |= 0x08;
557 :
558 174 : const SwFmtFooter &rOldF = pOldFmt->GetFooter();
559 174 : const SwFmtFooter &rNewF = pNewFmt->GetFooter();
560 174 : if( rOldF != rNewF )
561 28 : rInvFlags |= 0x10;
562 174 : CheckDirChange();
563 : }
564 : }
565 : // no break
566 : case RES_FRM_SIZE:
567 : {
568 176 : const SwRect aOldPageFrmRect( Frm() );
569 176 : SwViewShell *pSh = getRootFrm()->GetCurrShell();
570 176 : if( pSh && pSh->GetViewOptions()->getBrowseMode() )
571 : {
572 0 : mbValidSize = false;
573 : // OD 28.10.2002 #97265# - Don't call <SwPageFrm::MakeAll()>
574 : // Calculation of the page is not necessary, because its size is
575 : // is invalidated here and further invalidation is done in the
576 : // calling method <SwPageFrm::Modify(..)> and probably by calling
577 : // <SwLayoutFrm::Modify(..)> at the end.
578 : // It can also causes inconsistences, because the lowers are
579 : // adjusted, but not calculated, and a <SwPageFrm::MakeAll()> of
580 : // a next page is called. This is performed on the switch to the
581 : // online layout.
582 : //MakeAll();
583 : }
584 176 : else if (pNew)
585 : {
586 : const SwFmtFrmSize &rSz = nWhich == RES_FMT_CHG ?
587 174 : ((SwFmtChg*)pNew)->pChangedFmt->GetFrmSize() :
588 350 : (const SwFmtFrmSize&)*pNew;
589 :
590 176 : Frm().Height( std::max( rSz.GetHeight(), long(MINLAY) ) );
591 176 : Frm().Width ( std::max( rSz.GetWidth(), long(MINLAY) ) );
592 :
593 176 : if ( GetUpper() )
594 176 : static_cast<SwRootFrm*>(GetUpper())->CheckViewLayout( 0, 0 );
595 : }
596 : // cleanup Window
597 176 : if( pSh && pSh->GetWin() && aOldPageFrmRect.HasArea() )
598 : {
599 : // OD 12.02.2003 #i9719#, #105645# - consider border and shadow of
600 : // page frame for determine 'old' rectangle - it's used for invalidating.
601 176 : const bool bRightSidebar = (SidebarPosition() == sw::sidebarwindows::SIDEBAR_RIGHT);
602 176 : SwRect aOldRectWithBorderAndShadow;
603 : SwPageFrm::GetBorderAndShadowBoundRect( aOldPageFrmRect, pSh, aOldRectWithBorderAndShadow,
604 176 : IsLeftShadowNeeded(), IsRightShadowNeeded(), bRightSidebar );
605 176 : pSh->InvalidateWindows( aOldRectWithBorderAndShadow );
606 : }
607 176 : rInvFlags |= 0x03;
608 176 : if ( aOldPageFrmRect.Height() != Frm().Height() )
609 78 : rInvFlags |= 0x04;
610 : }
611 176 : break;
612 :
613 : case RES_COL:
614 : assert(pOld && pNew); //COL Missing Format
615 0 : if (pOld && pNew)
616 : {
617 0 : SwLayoutFrm *pB = FindBodyCont();
618 : assert(pB); //page without body
619 0 : pB->ChgColumns( *(const SwFmtCol*)pOld, *(const SwFmtCol*)pNew );
620 0 : rInvFlags |= 0x22;
621 : }
622 0 : break;
623 :
624 : case RES_HEADER:
625 12 : rInvFlags |= 0x08;
626 12 : break;
627 :
628 : case RES_FOOTER:
629 12 : rInvFlags |= 0x10;
630 12 : break;
631 : case RES_TEXTGRID:
632 10 : rInvFlags |= 0x60;
633 10 : break;
634 :
635 : case RES_PAGEDESC_FTNINFO:
636 : // currently the savest way:
637 0 : ((SwRootFrm*)GetUpper())->SetSuperfluous();
638 0 : SetMaxFtnHeight( pDesc->GetFtnInfo().GetHeight() );
639 0 : if ( !GetMaxFtnHeight() )
640 0 : SetMaxFtnHeight( LONG_MAX );
641 0 : SetColMaxFtnHeight();
642 : // here, the page might be destroyed:
643 0 : ((SwRootFrm*)GetUpper())->RemoveFtns( 0, false, true );
644 0 : break;
645 : case RES_FRAMEDIR :
646 0 : CheckDirChange();
647 0 : break;
648 :
649 : default:
650 246 : bClear = false;
651 : }
652 456 : if ( bClear )
653 : {
654 210 : if ( pOldSet || pNewSet )
655 : {
656 36 : if ( pOldSet )
657 36 : pOldSet->ClearItem( nWhich );
658 72 : if ( pNewSet )
659 36 : pNewSet->ClearItem( nWhich );
660 : }
661 : else
662 174 : SwLayoutFrm::Modify( pOld, pNew );
663 : }
664 456 : }
665 :
666 : /// get information from Modify
667 1798 : bool SwPageFrm::GetInfo( SfxPoolItem & rInfo ) const
668 : {
669 1798 : if( RES_AUTOFMT_DOCNODE == rInfo.Which() )
670 : {
671 : // a page frame exists, so use this one
672 1798 : return false;
673 : }
674 0 : return true; // continue searching
675 : }
676 :
677 130 : void SwPageFrm::SetPageDesc( SwPageDesc *pNew, SwFrmFmt *pFmt )
678 : {
679 130 : pDesc = pNew;
680 130 : if ( pFmt )
681 130 : SetFrmFmt( pFmt );
682 130 : }
683 :
684 : /* determine the right PageDesc:
685 : * 0. from the document for footnote and endnote pages
686 : * 1. from the first BodyCntnt below a page
687 : * 2. from PageDesc of the predecessor page
688 : * 3. from PageDesc of the previous page if blank page
689 : * 3.1 from PageDesc of the next page if no predecessor exists
690 : * 4. default PageDesc
691 : * 5. In BrowseMode use the first paragraph or default PageDesc.
692 : */
693 3750 : SwPageDesc *SwPageFrm::FindPageDesc()
694 : {
695 : // 0.
696 3750 : if ( IsFtnPage() )
697 : {
698 8 : SwDoc *pDoc = GetFmt()->GetDoc();
699 8 : if ( IsEndNotePage() )
700 8 : return pDoc->GetEndNoteInfo().GetPageDesc( *pDoc );
701 : else
702 0 : return pDoc->GetFtnInfo().GetPageDesc( *pDoc );
703 : }
704 :
705 3742 : SwPageDesc *pRet = 0;
706 :
707 : //5.
708 3742 : const SwViewShell *pSh = getRootFrm()->GetCurrShell();
709 3742 : if( pSh && pSh->GetViewOptions()->getBrowseMode() )
710 : {
711 30 : SwCntntFrm *pFrm = GetUpper()->ContainsCntnt();
712 60 : while (pFrm && !pFrm->IsInDocBody())
713 0 : pFrm = pFrm->GetNextCntntFrm();
714 30 : if (pFrm)
715 : {
716 30 : SwFrm *pFlow = pFrm;
717 30 : if ( pFlow->IsInTab() )
718 0 : pFlow = pFlow->FindTabFrm();
719 30 : pRet = (SwPageDesc*)pFlow->GetAttrSet()->GetPageDesc().GetPageDesc();
720 : }
721 30 : if ( !pRet )
722 18 : pRet = &GetFmt()->GetDoc()->GetPageDesc( 0 );
723 30 : return pRet;
724 : }
725 :
726 3712 : SwFrm *pFlow = FindFirstBodyCntnt();
727 3712 : if ( pFlow && pFlow->IsInTab() )
728 128 : pFlow = pFlow->FindTabFrm();
729 :
730 : //1.
731 3712 : if ( pFlow )
732 : {
733 2302 : SwFlowFrm *pTmp = SwFlowFrm::CastFlowFrm( pFlow );
734 2302 : if ( !pTmp->IsFollow() )
735 1940 : pRet = (SwPageDesc*)pFlow->GetAttrSet()->GetPageDesc().GetPageDesc();
736 : }
737 :
738 : //3. und 3.1
739 3712 : if ( !pRet && IsEmptyPage() )
740 : // FME 2008-03-03 #i81544# lijian/fme: an empty page should have
741 : // the same page description as its prev, just like after construction
742 : // of the empty page.
743 48 : pRet = GetPrev() ? ((SwPageFrm*)GetPrev())->GetPageDesc() :
744 48 : GetNext() ? ((SwPageFrm*)GetNext())->GetPageDesc() : 0;
745 :
746 : //2.
747 3712 : if ( !pRet )
748 3420 : pRet = GetPrev() ?
749 3420 : ((SwPageFrm*)GetPrev())->GetPageDesc()->GetFollow() : 0;
750 :
751 : //4.
752 3712 : if ( !pRet )
753 314 : pRet = &GetFmt()->GetDoc()->GetPageDesc( 0 );
754 :
755 : OSL_ENSURE( pRet, "could not find page descriptor." );
756 3712 : return pRet;
757 : }
758 :
759 : // Notify if the RootFrm changes its size
760 8294 : void AdjustSizeChgNotify( SwRootFrm *pRoot )
761 : {
762 8294 : const bool bOld = pRoot->IsSuperfluous();
763 8294 : pRoot->bCheckSuperfluous = false;
764 8294 : SwViewShell *pSh = pRoot->GetCurrShell();
765 8294 : if ( pSh )
766 : {
767 8274 : do
768 : {
769 8274 : if( pRoot == pSh->GetLayout() )
770 : {
771 8274 : pSh->SizeChgNotify();
772 8274 : if ( pSh->Imp() )
773 8274 : pSh->Imp()->NotifySizeChg( pRoot->Frm().SSize() );
774 : }
775 8274 : pSh = (SwViewShell*)pSh->GetNext();
776 8274 : } while ( pSh != pRoot->GetCurrShell() );
777 : }
778 8294 : pRoot->bCheckSuperfluous = bOld;
779 8294 : }
780 :
781 7774 : inline void SetLastPage( SwPageFrm *pPage )
782 : {
783 7774 : ((SwRootFrm*)pPage->GetUpper())->pLastPage = pPage;
784 7774 : }
785 :
786 392 : void SwPageFrm::Cut()
787 : {
788 392 : SwViewShell *pSh = getRootFrm()->GetCurrShell();
789 392 : if ( !IsEmptyPage() )
790 : {
791 364 : if ( GetNext() )
792 36 : GetNext()->InvalidatePos();
793 :
794 : // move Flys whose anchor is on a different page (draw objects are not relevant here)
795 364 : if ( GetSortedObjs() )
796 : {
797 80 : size_t i = 0;
798 340 : while ( GetSortedObjs() && i < GetSortedObjs()->size() )
799 : {
800 : // #i28701#
801 180 : SwAnchoredObject* pAnchoredObj = (*GetSortedObjs())[i];
802 :
803 180 : if ( pAnchoredObj->ISA(SwFlyAtCntFrm) )
804 : {
805 108 : SwFlyFrm* pFly = static_cast<SwFlyAtCntFrm*>(pAnchoredObj);
806 108 : SwPageFrm *pAnchPage = pFly->GetAnchorFrm() ?
807 108 : pFly->AnchorFrm()->FindPageFrm() : 0;
808 108 : if ( pAnchPage && (pAnchPage != this) )
809 : {
810 0 : MoveFly( pFly, pAnchPage );
811 0 : pFly->InvalidateSize();
812 0 : pFly->_InvalidatePos();
813 : // Do not increment index, in this case
814 0 : continue;
815 : }
816 : }
817 180 : ++i;
818 : }
819 : }
820 : // cleanup Window
821 364 : if ( pSh && pSh->GetWin() )
822 338 : pSh->InvalidateWindows( Frm() );
823 : }
824 :
825 : // decrease the root's page number
826 392 : ((SwRootFrm*)GetUpper())->DecrPhyPageNums();
827 392 : SwPageFrm *pPg = (SwPageFrm*)GetNext();
828 392 : if ( pPg )
829 : {
830 298 : while ( pPg )
831 : {
832 170 : pPg->DecrPhyPageNum(); //inline --nPhyPageNum
833 170 : pPg = (SwPageFrm*)pPg->GetNext();
834 : }
835 : }
836 : else
837 328 : ::SetLastPage( (SwPageFrm*)GetPrev() );
838 :
839 392 : SwFrm* pRootFrm = GetUpper();
840 :
841 : // cut all connections
842 392 : Remove();
843 :
844 392 : if ( pRootFrm )
845 392 : static_cast<SwRootFrm*>(pRootFrm)->CheckViewLayout( 0, 0 );
846 392 : }
847 :
848 7532 : void SwPageFrm::Paste( SwFrm* pParent, SwFrm* pSibling )
849 : {
850 : OSL_ENSURE( pParent->IsRootFrm(), "Parent is no Root." );
851 : OSL_ENSURE( pParent, "No parent for Paste()." );
852 : OSL_ENSURE( pParent != this, "I'm my own parent." );
853 : OSL_ENSURE( pSibling != this, "I'm my own neighbour." );
854 : OSL_ENSURE( !GetPrev() && !GetNext() && !GetUpper(),
855 : "I am still registered somewhere." );
856 :
857 : // insert into tree structure
858 7532 : InsertBefore( (SwLayoutFrm*)pParent, pSibling );
859 :
860 : // increase the root's page number
861 7532 : ((SwRootFrm*)GetUpper())->IncrPhyPageNums();
862 7532 : if( GetPrev() )
863 2262 : SetPhyPageNum( ((SwPageFrm*)GetPrev())->GetPhyPageNum() + 1 );
864 : else
865 5270 : SetPhyPageNum( 1 );
866 7532 : SwPageFrm *pPg = (SwPageFrm*)GetNext();
867 7532 : if ( pPg )
868 : {
869 416 : while ( pPg )
870 : {
871 244 : pPg->IncrPhyPageNum(); //inline ++nPhyPageNum
872 244 : pPg->_InvalidatePos();
873 244 : pPg->InvalidateLayout();
874 244 : pPg = (SwPageFrm*)pPg->GetNext();
875 : }
876 : }
877 : else
878 7446 : ::SetLastPage( this );
879 :
880 7532 : if( Frm().Width() != pParent->Prt().Width() )
881 5414 : _InvalidateSize();
882 :
883 7532 : InvalidatePos();
884 :
885 7532 : SwViewShell *pSh = getRootFrm()->GetCurrShell();
886 7532 : if ( pSh )
887 7532 : pSh->SetFirstVisPageInvalid();
888 :
889 7532 : getRootFrm()->CheckViewLayout( 0, 0 );
890 7532 : }
891 :
892 0 : static void lcl_PrepFlyInCntRegister( SwCntntFrm *pFrm )
893 : {
894 0 : pFrm->Prepare( PREP_REGISTER );
895 0 : if( pFrm->GetDrawObjs() )
896 : {
897 0 : for( size_t i = 0; i < pFrm->GetDrawObjs()->size(); ++i )
898 : {
899 : // #i28701#
900 0 : SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i];
901 0 : if ( pAnchoredObj->ISA(SwFlyInCntFrm) )
902 : {
903 0 : SwFlyFrm* pFly = static_cast<SwFlyInCntFrm*>(pAnchoredObj);
904 0 : SwCntntFrm *pCnt = pFly->ContainsCntnt();
905 0 : while ( pCnt )
906 : {
907 0 : lcl_PrepFlyInCntRegister( pCnt );
908 0 : pCnt = pCnt->GetNextCntntFrm();
909 : }
910 : }
911 : }
912 : }
913 0 : }
914 :
915 0 : void SwPageFrm::PrepareRegisterChg()
916 : {
917 0 : SwCntntFrm *pFrm = FindFirstBodyCntnt();
918 0 : while( pFrm )
919 : {
920 0 : lcl_PrepFlyInCntRegister( pFrm );
921 0 : pFrm = pFrm->GetNextCntntFrm();
922 0 : if( !IsAnLower( pFrm ) )
923 0 : break;
924 : }
925 0 : if( GetSortedObjs() )
926 : {
927 0 : for( size_t i = 0; i < GetSortedObjs()->size(); ++i )
928 : {
929 : // #i28701#
930 0 : SwAnchoredObject* pAnchoredObj = (*GetSortedObjs())[i];
931 0 : if ( pAnchoredObj->ISA(SwFlyFrm) )
932 : {
933 0 : SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
934 0 : pFrm = pFly->ContainsCntnt();
935 0 : while ( pFrm )
936 : {
937 0 : ::lcl_PrepFlyInCntRegister( pFrm );
938 0 : pFrm = pFrm->GetNextCntntFrm();
939 : }
940 : }
941 : }
942 : }
943 0 : }
944 :
945 : //FIXME: provide missing documentation
946 : /** Check all pages (starting from the given one) if they use the right frame format.
947 : *
948 : * If "wrong" pages are found, try to fix this as simple as possible.
949 : *
950 : * @param pStart the page from where to start searching
951 : * @param bNotifyFields
952 : * @param ppPrev
953 : */
954 1072 : void SwFrm::CheckPageDescs( SwPageFrm *pStart, bool bNotifyFields, SwPageFrm** ppPrev )
955 : {
956 : OSL_ENSURE( pStart, "no starting page." );
957 :
958 1072 : SwViewShell *pSh = pStart->getRootFrm()->GetCurrShell();
959 1072 : SwViewImp *pImp = pSh ? pSh->Imp() : 0;
960 :
961 1072 : if ( pImp && pImp->IsAction() && !pImp->GetLayAction().IsCheckPages() )
962 : {
963 320 : pImp->GetLayAction().SetCheckPageNum( pStart->GetPhyPageNum() );
964 1392 : return;
965 : }
966 :
967 : // For the update of page numbering fields, nDocPos provides
968 : // the page position from where invalidation should start.
969 752 : SwTwips nDocPos = LONG_MAX;
970 :
971 752 : SwRootFrm *pRoot = (SwRootFrm*)pStart->GetUpper();
972 752 : SwDoc* pDoc = pStart->GetFmt()->GetDoc();
973 752 : const bool bFtns = !pDoc->GetFtnIdxs().empty();
974 :
975 752 : SwPageFrm *pPage = pStart;
976 752 : if( pPage->GetPrev() && ((SwPageFrm*)pPage->GetPrev())->IsEmptyPage() )
977 16 : pPage = (SwPageFrm*)pPage->GetPrev();
978 3490 : while ( pPage )
979 : {
980 : // obtain PageDesc and FrmFmt
981 1986 : SwPageDesc *pDesc = pPage->FindPageDesc();
982 1986 : bool bCheckEmpty = pPage->IsEmptyPage();
983 1986 : bool bActOdd = pPage->OnRightPage();
984 1986 : bool bOdd = pPage->WannaRightPage();
985 1986 : bool bFirst = pPage->OnFirstPage();
986 : SwFrmFmt *pFmtWish = (bOdd)
987 1986 : ? pDesc->GetRightFmt(bFirst) : pDesc->GetLeftFmt(bFirst);
988 :
989 3948 : if ( bActOdd != bOdd ||
990 4034 : pDesc != pPage->GetPageDesc() || // wrong Desc
991 1896 : ( pFmtWish != pPage->GetFmt() && // wrong format and
992 90 : ( !pPage->IsEmptyPage() || pFmtWish ) // not blank /empty
993 : )
994 : )
995 : {
996 : // Updating a page might take a while, so check the WaitCrsr
997 218 : if( pImp )
998 218 : pImp->CheckWaitCrsr();
999 :
1000 : // invalidate the field, starting from here
1001 218 : if ( nDocPos == LONG_MAX )
1002 162 : nDocPos = pPage->GetPrev() ?
1003 162 : pPage->GetPrev()->Frm().Top() : pPage->Frm().Top();
1004 :
1005 : // Cases:
1006 : // 1. Empty page should be "normal" page -> remove empty page and take next one
1007 : // 2. Empty page should have different descriptor -> change
1008 : // 3. Normal page should be empty -> insert empty page if previous page
1009 : // is not empty, otherwise see (6).
1010 : // 4. Normal page should have different descriptor -> change
1011 : // 5. Normal page should have different format -> change
1012 : // 6. No "wish" format provided -> take the "other" format (left/right) of the PageDesc
1013 :
1014 240 : if ( pPage->IsEmptyPage() && ( pFmtWish || //1.
1015 0 : ( !bOdd && !pPage->GetPrev() ) ) )
1016 : {
1017 22 : SwPageFrm *pTmp = (SwPageFrm*)pPage->GetNext();
1018 22 : pPage->Cut();
1019 22 : bool bUpdatePrev = false;
1020 22 : if (ppPrev && *ppPrev == pPage)
1021 0 : bUpdatePrev = true;
1022 22 : delete pPage;
1023 22 : if ( pStart == pPage )
1024 2 : pStart = pTmp;
1025 22 : pPage = pTmp;
1026 22 : if (bUpdatePrev)
1027 0 : *ppPrev = pTmp;
1028 22 : continue;
1029 : }
1030 196 : else if ( pPage->IsEmptyPage() && !pFmtWish && //2.
1031 0 : pDesc != pPage->GetPageDesc() )
1032 : {
1033 0 : pPage->SetPageDesc( pDesc, 0 );
1034 : }
1035 588 : else if ( !pPage->IsEmptyPage() && //3.
1036 244 : bActOdd != bOdd &&
1037 48 : ( ( !pPage->GetPrev() && !bOdd ) ||
1038 40 : ( pPage->GetPrev() &&
1039 20 : !((SwPageFrm*)pPage->GetPrev())->IsEmptyPage() )
1040 : )
1041 : )
1042 : {
1043 24 : if ( pPage->GetPrev() )
1044 20 : pDesc = ((SwPageFrm*)pPage->GetPrev())->GetPageDesc();
1045 24 : SwPageFrm *pTmp = new SwPageFrm( pDoc->GetEmptyPageFmt(),pRoot,pDesc);
1046 24 : pTmp->Paste( pRoot, pPage );
1047 24 : pTmp->PreparePage( false );
1048 24 : pPage = pTmp;
1049 : }
1050 172 : else if ( pPage->GetPageDesc() != pDesc ) //4.
1051 : {
1052 130 : SwPageDesc *pOld = pPage->GetPageDesc();
1053 130 : pPage->SetPageDesc( pDesc, pFmtWish );
1054 130 : if ( bFtns )
1055 : {
1056 : // If specific values of the FtnInfo are changed, something has to happen.
1057 : // We try to limit the damage...
1058 : // If the page has no FtnCont it might be problematic.
1059 : // Let's hope that invalidation is enough.
1060 12 : SwFtnContFrm *pCont = pPage->FindFtnCont();
1061 12 : if ( pCont && !(pOld->GetFtnInfo() == pDesc->GetFtnInfo()) )
1062 2 : pCont->_InvalidateAll();
1063 : }
1064 : }
1065 42 : else if ( pFmtWish && pPage->GetFmt() != pFmtWish ) //5.
1066 : {
1067 42 : pPage->SetFrmFmt( pFmtWish );
1068 : }
1069 0 : else if ( !pFmtWish ) //6.
1070 : {
1071 : // get format with inverted logic
1072 0 : if (!pFmtWish)
1073 0 : pFmtWish = bOdd ? pDesc->GetLeftFmt() : pDesc->GetRightFmt();
1074 0 : if ( pPage->GetFmt() != pFmtWish )
1075 0 : pPage->SetFrmFmt( pFmtWish );
1076 : }
1077 : #if OSL_DEBUG_LEVEL > 0
1078 : else
1079 : {
1080 : OSL_FAIL( "CheckPageDescs, missing solution" );
1081 : }
1082 : #endif
1083 : }
1084 1964 : if ( bCheckEmpty )
1085 : {
1086 : // It also might be that an empty page is not needed at all.
1087 : // However, the algorithm above cannot determine that. It is not needed if the following
1088 : // page can live without it. Do obtain that information, we need to dig deeper...
1089 4 : SwPageFrm *pPg = (SwPageFrm*)pPage->GetNext();
1090 4 : if( !pPg || pPage->OnRightPage() == pPg->WannaRightPage() )
1091 : {
1092 : // The following page can find a FrmFmt or has no successor -> empty page not needed
1093 4 : SwPageFrm *pTmp = (SwPageFrm*)pPage->GetNext();
1094 4 : pPage->Cut();
1095 4 : bool bUpdatePrev = false;
1096 4 : if (ppPrev && *ppPrev == pPage)
1097 0 : bUpdatePrev = true;
1098 4 : delete pPage;
1099 4 : if ( pStart == pPage )
1100 0 : pStart = pTmp;
1101 4 : pPage = pTmp;
1102 4 : if (bUpdatePrev)
1103 0 : *ppPrev = pTmp;
1104 4 : continue;
1105 : }
1106 : }
1107 1960 : pPage = (SwPageFrm*)pPage->GetNext();
1108 : }
1109 :
1110 752 : pRoot->SetAssertFlyPages();
1111 752 : pRoot->AssertPageFlys( pStart );
1112 :
1113 752 : if ( bNotifyFields && (!pImp || !pImp->IsUpdateExpFlds()) )
1114 : {
1115 394 : SwDocPosUpdate aMsgHnt( nDocPos );
1116 394 : pDoc->getIDocumentFieldsAccess().UpdatePageFlds( &aMsgHnt );
1117 : }
1118 :
1119 : #if OSL_DEBUG_LEVEL > 0
1120 : //1. check if two empty pages are behind one another
1121 : bool bEmpty = false;
1122 : SwPageFrm *pPg = pStart;
1123 : while ( pPg )
1124 : {
1125 : if ( pPg->IsEmptyPage() )
1126 : {
1127 : if ( bEmpty )
1128 : {
1129 : OSL_FAIL( "double empty pages." );
1130 : break; // once is enough
1131 : }
1132 : bEmpty = true;
1133 : }
1134 : else
1135 : bEmpty = false;
1136 :
1137 : pPg = (SwPageFrm*)pPg->GetNext();
1138 : }
1139 : #endif
1140 : }
1141 :
1142 500 : SwPageFrm *SwFrm::InsertPage( SwPageFrm *pPrevPage, bool bFtn )
1143 : {
1144 500 : SwRootFrm *pRoot = (SwRootFrm*)pPrevPage->GetUpper();
1145 500 : SwPageFrm *pSibling = (SwPageFrm*)pPrevPage->GetNext();
1146 500 : SwPageDesc *pDesc = 0;
1147 :
1148 : // insert right (odd) or left (even) page?
1149 500 : bool bNextOdd = !pPrevPage->OnRightPage();
1150 500 : bool bWishedOdd = bNextOdd;
1151 :
1152 : // Which PageDesc is relevant?
1153 : // For CntntFrm take the one from format if provided,
1154 : // otherwise from the Follow of the PrevPage
1155 500 : if ( IsFlowFrm() && !SwFlowFrm::CastFlowFrm( this )->IsFollow() )
1156 226 : { SwFmtPageDesc &rDesc = (SwFmtPageDesc&)GetAttrSet()->GetPageDesc();
1157 226 : pDesc = rDesc.GetPageDesc();
1158 226 : if ( rDesc.GetNumOffset() )
1159 : {
1160 16 : ::boost::optional<sal_uInt16> oNumOffset = rDesc.GetNumOffset();
1161 16 : bWishedOdd = oNumOffset && (oNumOffset.get() % 2) != 0;
1162 : // use the opportunity to set the flag at root
1163 16 : pRoot->SetVirtPageNum( true );
1164 : }
1165 : }
1166 500 : if ( !pDesc )
1167 450 : pDesc = pPrevPage->GetPageDesc()->GetFollow();
1168 :
1169 : OSL_ENSURE( pDesc, "Missing PageDesc" );
1170 500 : if( !(bWishedOdd ? pDesc->GetRightFmt() : pDesc->GetLeftFmt()) )
1171 0 : bWishedOdd = !bWishedOdd;
1172 500 : bool const bWishedFirst = pDesc != pPrevPage->GetPageDesc();
1173 :
1174 500 : SwDoc *pDoc = pPrevPage->GetFmt()->GetDoc();
1175 500 : bool bCheckPages = false;
1176 : // If there is no FrmFmt for this page, create an empty page.
1177 500 : if( bWishedOdd != bNextOdd )
1178 : {
1179 10 : SwFrmFmt *const pEmptyFmt = pDoc->GetEmptyPageFmt();
1180 10 : SwPageDesc *pTmpDesc = pPrevPage->GetPageDesc();
1181 10 : SwPageFrm *pPage = new SwPageFrm(pEmptyFmt, pRoot, pTmpDesc);
1182 10 : pPage->Paste( pRoot, pSibling );
1183 10 : pPage->PreparePage( bFtn );
1184 : // If the sibling has no body text, destroy it as long as it is no footnote page.
1185 16 : if ( pSibling && !pSibling->IsFtnPage() &&
1186 6 : !pSibling->FindFirstBodyCntnt() )
1187 : {
1188 6 : SwPageFrm *pDel = pSibling;
1189 6 : pSibling = (SwPageFrm*)pSibling->GetNext();
1190 6 : if ( !pDoc->GetFtnIdxs().empty() )
1191 0 : pRoot->RemoveFtns( pDel, true );
1192 6 : pDel->Cut();
1193 6 : delete pDel;
1194 : }
1195 : else
1196 4 : bCheckPages = true;
1197 : }
1198 : SwFrmFmt *const pFmt( (bWishedOdd)
1199 204 : ? pDesc->GetRightFmt(bWishedFirst)
1200 704 : : pDesc->GetLeftFmt(bWishedFirst) );
1201 : assert(pFmt);
1202 500 : SwPageFrm *pPage = new SwPageFrm( pFmt, pRoot, pDesc );
1203 500 : pPage->Paste( pRoot, pSibling );
1204 500 : pPage->PreparePage( bFtn );
1205 : // If the sibling has no body text, destroy it as long as it is no footnote page.
1206 554 : if ( pSibling && !pSibling->IsFtnPage() &&
1207 54 : !pSibling->FindFirstBodyCntnt() )
1208 : {
1209 34 : SwPageFrm *pDel = pSibling;
1210 34 : pSibling = (SwPageFrm*)pSibling->GetNext();
1211 34 : if ( !pDoc->GetFtnIdxs().empty() )
1212 0 : pRoot->RemoveFtns( pDel, true );
1213 34 : pDel->Cut();
1214 34 : delete pDel;
1215 : }
1216 : else
1217 466 : bCheckPages = true;
1218 :
1219 500 : if ( pSibling )
1220 : {
1221 54 : if ( bCheckPages )
1222 : {
1223 22 : CheckPageDescs( pSibling, false );
1224 22 : SwViewShell *pSh = getRootFrm()->GetCurrShell();
1225 22 : SwViewImp *pImp = pSh ? pSh->Imp() : 0;
1226 22 : if ( pImp && pImp->IsAction() && !pImp->GetLayAction().IsCheckPages() )
1227 : {
1228 4 : const sal_uInt16 nNum = pImp->GetLayAction().GetCheckPageNum();
1229 4 : if ( nNum == pPrevPage->GetPhyPageNum() + 1 )
1230 0 : pImp->GetLayAction().SetCheckPageNumDirect(
1231 0 : pSibling->GetPhyPageNum() );
1232 4 : return pPage;
1233 : }
1234 : }
1235 : else
1236 32 : pRoot->AssertPageFlys( pSibling );
1237 : }
1238 :
1239 : // For the update of page numbering fields, nDocPos provides
1240 : // the page position from where invalidation should start.
1241 496 : SwViewShell *pSh = getRootFrm()->GetCurrShell();
1242 496 : if ( !pSh || !pSh->Imp()->IsUpdateExpFlds() )
1243 : {
1244 380 : SwDocPosUpdate aMsgHnt( pPrevPage->Frm().Top() );
1245 380 : pDoc->getIDocumentFieldsAccess().UpdatePageFlds( &aMsgHnt );
1246 : }
1247 496 : return pPage;
1248 : }
1249 :
1250 161754 : sw::sidebarwindows::SidebarPosition SwPageFrm::SidebarPosition() const
1251 : {
1252 161754 : SwViewShell *pSh = getRootFrm()->GetCurrShell();
1253 161754 : if( !pSh || pSh->GetViewOptions()->getBrowseMode() )
1254 : {
1255 928 : return sw::sidebarwindows::SIDEBAR_RIGHT;
1256 : }
1257 : else
1258 : {
1259 160826 : const bool bLTR = getRootFrm()->IsLeftToRightViewLayout();
1260 160826 : const bool bBookMode = pSh->GetViewOptions()->IsViewLayoutBookMode();
1261 160826 : const bool bRightSidebar = bLTR ? (!bBookMode || OnRightPage()) : (bBookMode && !OnRightPage());
1262 :
1263 : return bRightSidebar
1264 : ? sw::sidebarwindows::SIDEBAR_RIGHT
1265 160826 : : sw::sidebarwindows::SIDEBAR_LEFT;
1266 : }
1267 : }
1268 :
1269 0 : SwTwips SwRootFrm::GrowFrm( SwTwips nDist, bool bTst, bool )
1270 : {
1271 0 : if ( !bTst )
1272 0 : Frm().SSize().Height() += nDist;
1273 0 : return nDist;
1274 : }
1275 :
1276 0 : SwTwips SwRootFrm::ShrinkFrm( SwTwips nDist, bool bTst, bool )
1277 : {
1278 : OSL_ENSURE( nDist >= 0, "nDist < 0." );
1279 : OSL_ENSURE( nDist <= Frm().Height(), "nDist > als aktuelle Groesse." );
1280 :
1281 0 : if ( !bTst )
1282 0 : Frm().SSize().Height() -= nDist;
1283 0 : return nDist;
1284 : }
1285 :
1286 : /// remove pages that are not needed at all
1287 326 : void SwRootFrm::RemoveSuperfluous()
1288 : {
1289 : // A page is empty if the body text area has no CntntFrm, but not if there
1290 : // is at least one Fly or one footnote attached to the page. Two runs are
1291 : // needed: one for endnote pages and one for the pages of the body text.
1292 :
1293 326 : if ( !IsSuperfluous() )
1294 326 : return;
1295 326 : bCheckSuperfluous = false;
1296 :
1297 326 : SwPageFrm *pPage = GetLastPage();
1298 326 : long nDocPos = LONG_MAX;
1299 :
1300 : // Check the corresponding last page if it is empty and stop loop at the last non-empty page.
1301 628 : do
1302 : {
1303 628 : bool bExistEssentialObjs = ( 0 != pPage->GetSortedObjs() );
1304 628 : if ( bExistEssentialObjs )
1305 : {
1306 : // Only because the page has Flys does not mean that it is needed. If all Flys are
1307 : // attached to generic content it is also superfluous (checking DocBody should be enough)
1308 : // OD 19.06.2003 #108784# - consider that drawing objects in
1309 : // header/footer are supported now.
1310 222 : bool bOnlySuperfluosObjs = true;
1311 222 : SwSortedObjs &rObjs = *pPage->GetSortedObjs();
1312 764 : for ( size_t i = 0; bOnlySuperfluosObjs && i < rObjs.size(); ++i )
1313 : {
1314 : // #i28701#
1315 542 : SwAnchoredObject* pAnchoredObj = rObjs[i];
1316 : // OD 2004-01-19 #110582# - do not consider hidden objects
1317 1626 : if ( pPage->GetFmt()->GetDoc()->getIDocumentDrawModelAccess().IsVisibleLayerId(
1318 2694 : pAnchoredObj->GetDrawObj()->GetLayer() ) &&
1319 526 : !pAnchoredObj->GetAnchorFrm()->FindFooterOrHeader() )
1320 : {
1321 54 : bOnlySuperfluosObjs = false;
1322 : }
1323 : }
1324 222 : bExistEssentialObjs = !bOnlySuperfluosObjs;
1325 : }
1326 :
1327 : // OD 19.06.2003 #108784# - optimization: check first, if essential objects
1328 : // exists.
1329 628 : const SwLayoutFrm* pBody = 0;
1330 1202 : if ( bExistEssentialObjs ||
1331 1518 : pPage->FindFtnCont() ||
1332 1128 : ( 0 != ( pBody = pPage->FindBodyCont() ) &&
1333 866 : ( pBody->ContainsCntnt() ||
1334 : // #i47580#
1335 : // Do not delete page if there's an empty tabframe
1336 : // left. I think it might be correct to use ContainsAny()
1337 : // instead of ContainsCntnt() to cover the empty-table-case,
1338 : // but I'm not fully sure, since ContainsAny() also returns
1339 : // SectionFrames. Therefore I prefer to do it the safe way:
1340 304 : ( pBody->Lower() && pBody->Lower()->IsTabFrm() ) ) ) )
1341 : {
1342 326 : if ( pPage->IsFtnPage() )
1343 : {
1344 0 : while ( pPage->IsFtnPage() )
1345 : {
1346 0 : pPage = (SwPageFrm*)pPage->GetPrev();
1347 : OSL_ENSURE( pPage, "only endnote pages remain." );
1348 : }
1349 0 : continue;
1350 : }
1351 : else
1352 326 : pPage = 0;
1353 : }
1354 :
1355 628 : if ( pPage )
1356 : {
1357 302 : SwPageFrm *pEmpty = pPage;
1358 302 : pPage = (SwPageFrm*)pPage->GetPrev();
1359 302 : if ( !GetFmt()->GetDoc()->GetFtnIdxs().empty() )
1360 0 : RemoveFtns( pEmpty, true );
1361 302 : pEmpty->Cut();
1362 302 : delete pEmpty;
1363 302 : nDocPos = pPage ? pPage->Frm().Top() : 0;
1364 : }
1365 : } while ( pPage );
1366 :
1367 326 : SwViewShell *pSh = getRootFrm()->GetCurrShell();
1368 406 : if ( nDocPos != LONG_MAX &&
1369 136 : (!pSh || !pSh->Imp()->IsUpdateExpFlds()) )
1370 : {
1371 80 : SwDocPosUpdate aMsgHnt( nDocPos );
1372 80 : GetFmt()->GetDoc()->getIDocumentFieldsAccess().UpdatePageFlds( &aMsgHnt );
1373 : }
1374 : }
1375 :
1376 : /// Ensures that enough pages exist, so that all page bound frames and draw objects can be placed
1377 5552 : void SwRootFrm::AssertFlyPages()
1378 : {
1379 5552 : if ( !IsAssertFlyPages() )
1380 5552 : return;
1381 5552 : bAssertFlyPages = false;
1382 :
1383 5552 : SwDoc *pDoc = GetFmt()->GetDoc();
1384 5552 : const SwFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
1385 :
1386 : // what page targets the "last" Fly?
1387 5552 : sal_uInt16 nMaxPg = 0;
1388 :
1389 11232 : for ( size_t i = 0; i < pTbl->size(); ++i )
1390 : {
1391 5680 : const SwFmtAnchor &rAnch = (*pTbl)[i]->GetAnchor();
1392 5680 : if ( !rAnch.GetCntntAnchor() && nMaxPg < rAnch.GetPageNum() )
1393 128 : nMaxPg = rAnch.GetPageNum();
1394 : }
1395 : // How many pages exist at the moment?
1396 5552 : SwPageFrm *pPage = (SwPageFrm*)Lower();
1397 16024 : while ( pPage && pPage->GetNext() &&
1398 2470 : !((SwPageFrm*)pPage->GetNext())->IsFtnPage() )
1399 : {
1400 2450 : pPage = (SwPageFrm*)pPage->GetNext();
1401 : }
1402 :
1403 5552 : if ( nMaxPg > pPage->GetPhyPageNum() )
1404 : {
1405 : // Continue pages based on the rules of the PageDesc after the last page.
1406 8 : bool bOdd = (pPage->GetPhyPageNum() % 2) != 0;
1407 8 : SwPageDesc *pDesc = pPage->GetPageDesc();
1408 8 : SwFrm *pSibling = pPage->GetNext();
1409 32 : for ( sal_uInt16 i = pPage->GetPhyPageNum(); i < nMaxPg; ++i )
1410 : {
1411 24 : if ( !(bOdd ? pDesc->GetRightFmt() : pDesc->GetLeftFmt()) )
1412 : {
1413 : // Insert empty page (but Flys will be stored in the next page)
1414 0 : pPage = new SwPageFrm( pDoc->GetEmptyPageFmt(), this, pDesc );
1415 0 : pPage->Paste( this, pSibling );
1416 0 : pPage->PreparePage( false );
1417 0 : bOdd = !bOdd;
1418 0 : ++i;
1419 : }
1420 : pPage = new
1421 : SwPageFrm( (bOdd ? pDesc->GetRightFmt() :
1422 24 : pDesc->GetLeftFmt()), this, pDesc );
1423 24 : pPage->Paste( this, pSibling );
1424 24 : pPage->PreparePage( false );
1425 24 : bOdd = !bOdd;
1426 24 : pDesc = pDesc->GetFollow();
1427 : }
1428 : // If the endnote pages are now corrupt, destroy them.
1429 8 : if ( !pDoc->GetFtnIdxs().empty() )
1430 : {
1431 0 : pPage = (SwPageFrm*)Lower();
1432 0 : while ( pPage && !pPage->IsFtnPage() )
1433 0 : pPage = (SwPageFrm*)pPage->GetNext();
1434 :
1435 0 : if ( pPage )
1436 : {
1437 0 : SwPageDesc *pTmpDesc = pPage->FindPageDesc();
1438 0 : bOdd = pPage->OnRightPage();
1439 0 : if ( pPage->GetFmt() !=
1440 : (bOdd ? pTmpDesc->GetRightFmt() : pTmpDesc->GetLeftFmt()) )
1441 0 : RemoveFtns( pPage, false, true );
1442 : }
1443 : }
1444 : }
1445 : }
1446 :
1447 : /// Ensure that after the given page all page-bound objects are located on the correct page
1448 784 : void SwRootFrm::AssertPageFlys( SwPageFrm *pPage )
1449 : {
1450 3608 : while ( pPage )
1451 : {
1452 2040 : if ( pPage->GetSortedObjs() )
1453 : {
1454 378 : pPage->GetSortedObjs();
1455 378 : size_t i = 0;
1456 1898 : while ( pPage->GetSortedObjs() && i< pPage->GetSortedObjs()->size() )
1457 : {
1458 : // #i28701#
1459 1142 : SwFrmFmt& rFmt = (*pPage->GetSortedObjs())[i]->GetFrmFmt();
1460 1142 : const SwFmtAnchor &rAnch = rFmt.GetAnchor();
1461 1142 : const sal_uInt16 nPg = rAnch.GetPageNum();
1462 1688 : if ((rAnch.GetAnchorId() == FLY_AT_PAGE) &&
1463 546 : nPg != pPage->GetPhyPageNum() )
1464 : {
1465 : // If on the wrong page, check if previous page is empty
1466 0 : if( nPg && !(pPage->GetPhyPageNum()-1 == nPg &&
1467 0 : ((SwPageFrm*)pPage->GetPrev())->IsEmptyPage()) )
1468 : {
1469 : // It can move by itself. Just send a modify to its anchor attribute.
1470 : #if OSL_DEBUG_LEVEL > 1
1471 : const size_t nCnt = pPage->GetSortedObjs()->size();
1472 : rFmt.NotifyClients( 0, (SwFmtAnchor*)&rAnch );
1473 : OSL_ENSURE( !pPage->GetSortedObjs() ||
1474 : nCnt != pPage->GetSortedObjs()->size(),
1475 : "Object couldn't be reattached!" );
1476 : #else
1477 0 : rFmt.NotifyClients( 0, (SwFmtAnchor*)&rAnch );
1478 : #endif
1479 : // Do not increment index, in this case
1480 0 : continue;
1481 : }
1482 : }
1483 1142 : ++i;
1484 : }
1485 : }
1486 2040 : pPage = (SwPageFrm*)pPage->GetNext();
1487 : }
1488 784 : }
1489 :
1490 8294 : Size SwRootFrm::ChgSize( const Size& aNewSize )
1491 : {
1492 8294 : Frm().SSize() = aNewSize;
1493 8294 : _InvalidatePrt();
1494 8294 : mbFixSize = false;
1495 8294 : return Frm().SSize();
1496 : }
1497 :
1498 13562 : void SwRootFrm::MakeAll()
1499 : {
1500 13562 : if ( !mbValidPos )
1501 5268 : { mbValidPos = true;
1502 5268 : maFrm.Pos().setX(DOCUMENTBORDER);
1503 5268 : maFrm.Pos().setY(DOCUMENTBORDER);
1504 : }
1505 13562 : if ( !mbValidPrtArea )
1506 13562 : { mbValidPrtArea = true;
1507 13562 : maPrt.Pos().setX(0);
1508 13562 : maPrt.Pos().setY(0);
1509 13562 : maPrt.SSize( maFrm.SSize() );
1510 : }
1511 13562 : if ( !mbValidSize )
1512 : // SSize is set by the pages (Cut/Paste).
1513 5268 : mbValidSize = true;
1514 13562 : }
1515 :
1516 156 : void SwRootFrm::ImplInvalidateBrowseWidth()
1517 : {
1518 156 : bBrowseWidthValid = false;
1519 156 : SwFrm *pPg = Lower();
1520 468 : while ( pPg )
1521 : {
1522 156 : pPg->InvalidateSize();
1523 156 : pPg = pPg->GetNext();
1524 : }
1525 156 : }
1526 :
1527 168 : void SwRootFrm::ImplCalcBrowseWidth()
1528 : {
1529 : OSL_ENSURE( GetCurrShell() && GetCurrShell()->GetViewOptions()->getBrowseMode(),
1530 : "CalcBrowseWidth and not in BrowseView" );
1531 :
1532 : // The (minimal) with is determined from borders, tables and paint objects.
1533 : // It is calculated based on the attributes. Thus, it is not relevant how wide they are
1534 : // currently but only how wide they want to be.
1535 : // Frames and paint objects inside other objects (frames, tables) do not count.
1536 : // Borders and columns are not taken into account.
1537 :
1538 168 : SwFrm *pFrm = ContainsCntnt();
1539 336 : while ( pFrm && !pFrm->IsInDocBody() )
1540 0 : pFrm = ((SwCntntFrm*)pFrm)->GetNextCntntFrm();
1541 168 : if ( !pFrm )
1542 174 : return;
1543 :
1544 162 : bBrowseWidthValid = true;
1545 162 : SwViewShell *pSh = getRootFrm()->GetCurrShell();
1546 : nBrowseWidth = pSh
1547 162 : ? MINLAY + 2 * pSh->GetOut()->
1548 648 : PixelToLogic( pSh->GetBrowseBorder() ).Width()
1549 510 : : 5000;
1550 186 : do
1551 : {
1552 186 : if ( pFrm->IsInTab() )
1553 0 : pFrm = pFrm->FindTabFrm();
1554 :
1555 186 : if ( pFrm->IsTabFrm() &&
1556 0 : !((SwLayoutFrm*)pFrm)->GetFmt()->GetFrmSize().GetWidthPercent() )
1557 : {
1558 0 : SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm );
1559 0 : const SwBorderAttrs &rAttrs = *aAccess.Get();
1560 0 : const SwFmtHoriOrient &rHori = rAttrs.GetAttrSet().GetHoriOrient();
1561 0 : long nWidth = rAttrs.GetSize().Width();
1562 0 : if ( nWidth < USHRT_MAX-2000 && //-2k, because USHRT_MAX gets missing while trying to resize!
1563 0 : text::HoriOrientation::FULL != rHori.GetHoriOrient() )
1564 : {
1565 : const SwHTMLTableLayout *pLayoutInfo =
1566 : ((const SwTabFrm *)pFrm)->GetTable()
1567 0 : ->GetHTMLTableLayout();
1568 0 : if ( pLayoutInfo )
1569 0 : nWidth = std::min( nWidth, pLayoutInfo->GetBrowseWidthMin() );
1570 :
1571 0 : switch ( rHori.GetHoriOrient() )
1572 : {
1573 : case text::HoriOrientation::NONE:
1574 : // OD 23.01.2003 #106895# - add 1st param to <SwBorderAttrs::CalcRight(..)>
1575 0 : nWidth += rAttrs.CalcLeft( pFrm ) + rAttrs.CalcRight( pFrm );
1576 0 : break;
1577 : case text::HoriOrientation::LEFT_AND_WIDTH:
1578 0 : nWidth += rAttrs.CalcLeft( pFrm );
1579 0 : break;
1580 : default:
1581 0 : break;
1582 : }
1583 0 : nBrowseWidth = std::max( nBrowseWidth, nWidth );
1584 0 : }
1585 : }
1586 186 : else if ( pFrm->GetDrawObjs() )
1587 : {
1588 8 : for ( size_t i = 0; i < pFrm->GetDrawObjs()->size(); ++i )
1589 : {
1590 : // #i28701#
1591 4 : SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i];
1592 4 : const SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt();
1593 4 : const bool bFly = pAnchoredObj->ISA(SwFlyFrm);
1594 4 : if ((bFly && (FAR_AWAY == pAnchoredObj->GetObjRect().Width()))
1595 8 : || rFmt.GetFrmSize().GetWidthPercent())
1596 : {
1597 0 : continue;
1598 : }
1599 :
1600 4 : long nWidth = 0;
1601 4 : switch ( rFmt.GetAnchor().GetAnchorId() )
1602 : {
1603 : case FLY_AS_CHAR:
1604 0 : nWidth = bFly ? rFmt.GetFrmSize().GetWidth() :
1605 4 : pAnchoredObj->GetObjRect().Width();
1606 4 : break;
1607 : case FLY_AT_PARA:
1608 : {
1609 : // #i33170#
1610 : // Reactivated old code because
1611 : // nWidth = pAnchoredObj->GetObjRect().Right()
1612 : // gives wrong results for objects that are still
1613 : // at position FAR_AWAY.
1614 0 : if ( bFly )
1615 : {
1616 0 : nWidth = rFmt.GetFrmSize().GetWidth();
1617 0 : const SwFmtHoriOrient &rHori = rFmt.GetHoriOrient();
1618 0 : switch ( rHori.GetHoriOrient() )
1619 : {
1620 : case text::HoriOrientation::NONE:
1621 0 : nWidth += rHori.GetPos();
1622 0 : break;
1623 : case text::HoriOrientation::INSIDE:
1624 : case text::HoriOrientation::LEFT:
1625 0 : if ( text::RelOrientation::PRINT_AREA == rHori.GetRelationOrient() )
1626 0 : nWidth += pFrm->Prt().Left();
1627 0 : break;
1628 : default:
1629 0 : break;
1630 : }
1631 : }
1632 : else
1633 : // Paint objects to not have attributes and
1634 : // are defined by their current size
1635 0 : nWidth = pAnchoredObj->GetObjRect().Right() -
1636 0 : pAnchoredObj->GetDrawObj()->GetAnchorPos().X();
1637 : }
1638 0 : break;
1639 : default: /* do nothing */;
1640 : }
1641 4 : nBrowseWidth = std::max( nBrowseWidth, nWidth );
1642 : }
1643 : }
1644 186 : pFrm = pFrm->FindNextCnt();
1645 : } while ( pFrm );
1646 : }
1647 :
1648 42936 : void SwRootFrm::StartAllAction()
1649 : {
1650 42936 : SwViewShell *pSh = GetCurrShell();
1651 42936 : if ( pSh )
1652 42936 : do
1653 42936 : { if ( pSh->ISA( SwCrsrShell ) )
1654 42936 : ((SwCrsrShell*)pSh)->StartAction();
1655 : else
1656 0 : pSh->StartAction();
1657 42936 : pSh = (SwViewShell*)pSh->GetNext();
1658 :
1659 42936 : } while ( pSh != GetCurrShell() );
1660 42936 : }
1661 :
1662 42936 : void SwRootFrm::EndAllAction( bool bVirDev )
1663 : {
1664 42936 : SwViewShell *pSh = GetCurrShell();
1665 42936 : if ( pSh )
1666 42936 : do
1667 : {
1668 42936 : const bool bOldEndActionByVirDev = pSh->IsEndActionByVirDev();
1669 42936 : pSh->SetEndActionByVirDev( bVirDev );
1670 42936 : if ( pSh->ISA( SwCrsrShell ) )
1671 : {
1672 42936 : ((SwCrsrShell*)pSh)->EndAction();
1673 42936 : ((SwCrsrShell*)pSh)->CallChgLnk();
1674 42936 : if ( pSh->ISA( SwFEShell ) )
1675 42936 : ((SwFEShell*)pSh)->SetChainMarker();
1676 : }
1677 : else
1678 0 : pSh->EndAction();
1679 42936 : pSh->SetEndActionByVirDev( bOldEndActionByVirDev );
1680 42936 : pSh = (SwViewShell*)pSh->GetNext();
1681 :
1682 42936 : } while ( pSh != GetCurrShell() );
1683 42936 : }
1684 :
1685 344 : void SwRootFrm::UnoRemoveAllActions()
1686 : {
1687 344 : SwViewShell *pSh = GetCurrShell();
1688 344 : if ( pSh )
1689 344 : do
1690 : {
1691 : // #i84729#
1692 : // No end action, if <SwViewShell> instance is currently in its end action.
1693 : // Recursives calls to <::EndAction()> are not allowed.
1694 344 : if ( !pSh->IsInEndAction() )
1695 : {
1696 : OSL_ENSURE(!pSh->GetRestoreActions(), "Restore action count is already set!");
1697 344 : bool bCrsr = pSh->ISA( SwCrsrShell );
1698 344 : bool bFE = pSh->ISA( SwFEShell );
1699 344 : sal_uInt16 nRestore = 0;
1700 810 : while( pSh->ActionCount() )
1701 : {
1702 122 : if( bCrsr )
1703 : {
1704 122 : ((SwCrsrShell*)pSh)->EndAction();
1705 122 : ((SwCrsrShell*)pSh)->CallChgLnk();
1706 122 : if ( bFE )
1707 122 : ((SwFEShell*)pSh)->SetChainMarker();
1708 : }
1709 : else
1710 0 : pSh->EndAction();
1711 122 : nRestore++;
1712 : }
1713 344 : pSh->SetRestoreActions(nRestore);
1714 : }
1715 344 : pSh->LockView(true);
1716 344 : pSh = (SwViewShell*)pSh->GetNext();
1717 :
1718 344 : } while ( pSh != GetCurrShell() );
1719 344 : }
1720 :
1721 344 : void SwRootFrm::UnoRestoreAllActions()
1722 : {
1723 344 : SwViewShell *pSh = GetCurrShell();
1724 344 : if ( pSh )
1725 344 : do
1726 : {
1727 344 : sal_uInt16 nActions = pSh->GetRestoreActions();
1728 810 : while( nActions-- )
1729 : {
1730 122 : if ( pSh->ISA( SwCrsrShell ) )
1731 122 : ((SwCrsrShell*)pSh)->StartAction();
1732 : else
1733 0 : pSh->StartAction();
1734 : }
1735 344 : pSh->SetRestoreActions(0);
1736 344 : pSh->LockView(false);
1737 344 : pSh = (SwViewShell*)pSh->GetNext();
1738 :
1739 344 : } while ( pSh != GetCurrShell() );
1740 344 : }
1741 :
1742 : // Helper functions for SwRootFrm::CheckViewLayout
1743 : static void lcl_MoveAllLowers( SwFrm* pFrm, const Point& rOffset );
1744 :
1745 36012 : static void lcl_MoveAllLowerObjs( SwFrm* pFrm, const Point& rOffset )
1746 : {
1747 36012 : SwSortedObjs* pSortedObj = 0;
1748 36012 : const bool bPage = pFrm->IsPageFrm();
1749 :
1750 36012 : if ( bPage )
1751 8230 : pSortedObj = static_cast<SwPageFrm*>(pFrm)->GetSortedObjs();
1752 : else
1753 27782 : pSortedObj = pFrm->GetDrawObjs();
1754 :
1755 38590 : for ( size_t i = 0; pSortedObj && i < pSortedObj->size(); ++i)
1756 : {
1757 2578 : SwAnchoredObject* pAnchoredObj = (*pSortedObj)[i];
1758 :
1759 2578 : const SwFrmFmt& rObjFmt = pAnchoredObj->GetFrmFmt();
1760 2578 : const SwFmtAnchor& rAnchor = rObjFmt.GetAnchor();
1761 :
1762 : // all except from the as character anchored objects are moved
1763 : // when processing the page frame:
1764 2578 : const bool bAsChar = (rAnchor.GetAnchorId() == FLY_AS_CHAR);
1765 2578 : if ( !bPage && !bAsChar )
1766 2876 : continue;
1767 :
1768 1146 : SwObjPositioningInProgress aPosInProgress( *pAnchoredObj );
1769 :
1770 1146 : if ( pAnchoredObj->ISA(SwFlyFrm) )
1771 : {
1772 1112 : SwFlyFrm* pFlyFrm( static_cast<SwFlyFrm*>(pAnchoredObj) );
1773 1112 : lcl_MoveAllLowers( pFlyFrm, rOffset );
1774 1112 : pFlyFrm->NotifyDrawObj();
1775 : // --> let the active embedded object be moved
1776 1112 : if ( pFlyFrm->Lower() )
1777 : {
1778 1112 : if ( pFlyFrm->Lower()->IsNoTxtFrm() )
1779 : {
1780 1046 : SwCntntFrm* pCntntFrm = static_cast<SwCntntFrm*>(pFlyFrm->Lower());
1781 1046 : SwRootFrm* pRoot = pFlyFrm->Lower()->getRootFrm();
1782 1046 : SwViewShell *pSh = pRoot ? pRoot->GetCurrShell() : 0;
1783 1046 : if ( pSh )
1784 : {
1785 1046 : SwOLENode* pNode = pCntntFrm->GetNode()->GetOLENode();
1786 1046 : if ( pNode )
1787 : {
1788 2 : svt::EmbeddedObjectRef& xObj = pNode->GetOLEObj().GetObject();
1789 2 : if ( xObj.is() )
1790 : {
1791 2 : SwViewShell* pTmp = pSh;
1792 2 : do
1793 : {
1794 2 : SwFEShell* pFEShell = dynamic_cast< SwFEShell* >( pTmp );
1795 2 : if ( pFEShell )
1796 2 : pFEShell->MoveObjectIfActive( xObj, rOffset );
1797 2 : pTmp = static_cast<SwViewShell*>( pTmp->GetNext() );
1798 : } while( pTmp != pSh );
1799 : }
1800 : }
1801 : }
1802 : }
1803 : }
1804 : }
1805 34 : else if ( pAnchoredObj->ISA(SwAnchoredDrawObject) )
1806 : {
1807 34 : SwAnchoredDrawObject* pAnchoredDrawObj( static_cast<SwAnchoredDrawObject*>(pAnchoredObj) );
1808 :
1809 : // don't touch objects that are not yet positioned:
1810 34 : const bool bNotYetPositioned = pAnchoredDrawObj->NotYetPositioned();
1811 34 : if ( bNotYetPositioned )
1812 12 : continue;
1813 :
1814 22 : const Point aCurrAnchorPos = pAnchoredDrawObj->GetDrawObj()->GetAnchorPos();
1815 22 : const Point aNewAnchorPos( ( aCurrAnchorPos + rOffset ) );
1816 22 : pAnchoredDrawObj->DrawObj()->SetAnchorPos( aNewAnchorPos );
1817 22 : pAnchoredDrawObj->SetLastObjRect( pAnchoredDrawObj->GetObjRect().SVRect() );
1818 :
1819 : // clear contour cache
1820 22 : if ( pAnchoredDrawObj->GetFrmFmt().GetSurround().IsContour() )
1821 0 : ClrContourCache( pAnchoredDrawObj->GetDrawObj() );
1822 : }
1823 : // #i92511#
1824 : // cache for object rectangle inclusive spaces has to be invalidated.
1825 1134 : pAnchoredObj->InvalidateObjRectWithSpaces();
1826 1134 : }
1827 36012 : }
1828 :
1829 36012 : static void lcl_MoveAllLowers( SwFrm* pFrm, const Point& rOffset )
1830 : {
1831 36012 : const SwRect aFrm( pFrm->Frm() );
1832 :
1833 : // first move the current frame
1834 36012 : pFrm->Frm().Pos() += rOffset;
1835 :
1836 : // Don't forget accessibility:
1837 36012 : if( pFrm->IsAccessibleFrm() )
1838 : {
1839 25904 : SwRootFrm *pRootFrm = pFrm->getRootFrm();
1840 26020 : if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
1841 116 : pRootFrm->GetCurrShell() )
1842 : {
1843 116 : pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( pFrm, aFrm );
1844 : }
1845 : }
1846 :
1847 : // the move any objects
1848 36012 : lcl_MoveAllLowerObjs( pFrm, rOffset );
1849 :
1850 : // finally, for layout frames we have to call this function recursively:
1851 36012 : if ( pFrm->ISA(SwLayoutFrm) )
1852 : {
1853 24612 : SwFrm* pLowerFrm = pFrm->GetLower();
1854 75894 : while ( pLowerFrm )
1855 : {
1856 26670 : lcl_MoveAllLowers( pLowerFrm, rOffset );
1857 26670 : pLowerFrm = pLowerFrm->GetNext();
1858 : }
1859 : }
1860 36012 : }
1861 :
1862 : // Calculate how the pages have to be positioned
1863 81627 : void SwRootFrm::CheckViewLayout( const SwViewOption* pViewOpt, const SwRect* pVisArea )
1864 : {
1865 : // #i91432#
1866 : // No calculation of page positions, if only an empty page is present.
1867 : // This situation occurs when <SwRootFrm> instance is in construction
1868 : // and the document contains only left pages.
1869 137965 : if ( Lower()->GetNext() == 0 &&
1870 56338 : static_cast<SwPageFrm*>(Lower())->IsEmptyPage() )
1871 : {
1872 59307 : return;
1873 : }
1874 :
1875 81627 : if ( !pVisArea )
1876 : {
1877 : // no early return for bNewPage
1878 8150 : if ( mnViewWidth < 0 )
1879 5266 : mnViewWidth = 0;
1880 : }
1881 : else
1882 : {
1883 : OSL_ENSURE( pViewOpt, "CheckViewLayout required ViewOptions" );
1884 :
1885 73477 : const sal_uInt16 nColumns = pViewOpt->GetViewLayoutColumns();
1886 73477 : const bool bBookMode = pViewOpt->IsViewLayoutBookMode();
1887 :
1888 73477 : if ( nColumns == mnColumns && bBookMode == mbBookMode && pVisArea->Width() == mnViewWidth && !mbSidebarChanged )
1889 59307 : return;
1890 :
1891 14170 : mnColumns = nColumns;
1892 14170 : mbBookMode = bBookMode;
1893 14170 : mnViewWidth = pVisArea->Width();
1894 14170 : mbSidebarChanged = false;
1895 : }
1896 :
1897 22320 : if( GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE ) )
1898 : {
1899 1176 : mnColumns = 1;
1900 1176 : mbBookMode = false;
1901 : }
1902 :
1903 22320 : Calc();
1904 :
1905 22320 : const bool bOldCallbackActionEnabled = IsCallbackActionEnabled();
1906 22320 : SetCallbackActionEnabled( false );
1907 :
1908 22320 : maPageRects.clear();
1909 :
1910 22320 : const long nBorder = Frm().Pos().getX();
1911 22320 : const long nVisWidth = mnViewWidth - 2 * nBorder;
1912 22320 : const long nGapBetweenPages = GAPBETWEENPAGES;
1913 :
1914 : // check how many pages fit into the first page layout row:
1915 22320 : SwPageFrm* pPageFrm = static_cast<SwPageFrm*>(Lower());
1916 :
1917 : // will contain the number of pages per row. 0 means that
1918 : // the page does not fit.
1919 22320 : long nWidthRemain = nVisWidth;
1920 :
1921 : // after one row has been processed, these variables contain
1922 : // the width of the row and the maxium of the page heights
1923 22320 : long nCurrentRowHeight = 0;
1924 22320 : long nCurrentRowWidth = 0;
1925 :
1926 : // these variables are used to finally set the size of the
1927 : // root frame
1928 22320 : long nSumRowHeight = 0;
1929 22320 : SwTwips nMinPageLeft = TWIPS_MAX;
1930 22320 : SwTwips nMaxPageRight = 0;
1931 22320 : SwPageFrm* pStartOfRow = pPageFrm;
1932 22320 : sal_uInt16 nNumberOfPagesInRow = mbBookMode ? 1 : 0; // in book view, start with right page
1933 22320 : bool bFirstRow = true;
1934 :
1935 22320 : bool bPageChanged = false;
1936 22320 : const bool bRTL = !IsLeftToRightViewLayout();
1937 22320 : const SwTwips nSidebarWidth = SwPageFrm::GetSidebarBorderWidth( GetCurrShell() );
1938 :
1939 96596 : while ( pPageFrm )
1940 : {
1941 : // we consider the current page to be "start of row" if
1942 : // 1. it is the first page in the current row or
1943 : // 2. it is the second page in the row and the first page is an empty page in non-book view:
1944 104088 : const bool bStartOfRow = pPageFrm == pStartOfRow ||
1945 52572 : ( pStartOfRow->IsEmptyPage() && pPageFrm == pStartOfRow->GetNext() && !mbBookMode );
1946 :
1947 51956 : const bool bEmptyPage = pPageFrm->IsEmptyPage() && !mbBookMode;
1948 :
1949 : // no half doc border space for first page in each row and
1950 51956 : long nPageWidth = 0;
1951 51956 : long nPageHeight = 0;
1952 :
1953 51956 : if ( mbBookMode )
1954 : {
1955 0 : const SwFrm& rFormatPage = pPageFrm->GetFormatPage();
1956 :
1957 0 : nPageWidth = rFormatPage.Frm().Width() + nSidebarWidth + ((bStartOfRow || 1 == (pPageFrm->GetPhyPageNum()%2)) ? 0 : nGapBetweenPages);
1958 0 : nPageHeight = rFormatPage.Frm().Height() + nGapBetweenPages;
1959 : }
1960 : else
1961 : {
1962 51956 : if ( !pPageFrm->IsEmptyPage() )
1963 : {
1964 51660 : nPageWidth = pPageFrm->Frm().Width() + nSidebarWidth + (bStartOfRow ? 0 : nGapBetweenPages);
1965 51660 : nPageHeight = pPageFrm->Frm().Height() + nGapBetweenPages;
1966 : }
1967 : }
1968 :
1969 51956 : if ( !bEmptyPage )
1970 51660 : ++nNumberOfPagesInRow;
1971 :
1972 : // finish current row if
1973 : // 1. in dynamic mode the current page does not fit anymore or
1974 : // 2. the current page exceeds the maximum number of columns
1975 103914 : bool bRowFinished = (0 == mnColumns && nWidthRemain < nPageWidth ) ||
1976 55042 : (0 != mnColumns && mnColumns < nNumberOfPagesInRow);
1977 :
1978 : // make sure that at least one page goes to the current row:
1979 51956 : if ( !bRowFinished || bStartOfRow )
1980 : {
1981 : // current page is allowed to be in current row
1982 51808 : nWidthRemain = nWidthRemain - nPageWidth;
1983 :
1984 51808 : nCurrentRowWidth = nCurrentRowWidth + nPageWidth;
1985 51808 : nCurrentRowHeight = std::max( nCurrentRowHeight, nPageHeight );
1986 :
1987 51808 : pPageFrm = static_cast<SwPageFrm*>(pPageFrm->GetNext());
1988 :
1989 51808 : if ( !pPageFrm )
1990 22320 : bRowFinished = true;
1991 : }
1992 :
1993 51956 : if ( bRowFinished )
1994 : {
1995 : // pPageFrm now points to the first page in the new row or null
1996 : // pStartOfRow points to the first page in the current row
1997 :
1998 : // special centering for last row. pretend to fill the last row with virtual copies of the last page before centering:
1999 51518 : if ( !pPageFrm && nWidthRemain > 0 )
2000 : {
2001 : // find last page in current row:
2002 174 : const SwPageFrm* pLastPageInCurrentRow = pStartOfRow;
2003 402 : while( pLastPageInCurrentRow->GetNext() )
2004 54 : pLastPageInCurrentRow = static_cast<const SwPageFrm*>(pLastPageInCurrentRow->GetNext());
2005 :
2006 174 : if ( pLastPageInCurrentRow->IsEmptyPage() )
2007 0 : pLastPageInCurrentRow = static_cast<const SwPageFrm*>(pLastPageInCurrentRow->GetPrev());
2008 :
2009 : // check how many times the last page would still fit into the remaining space:
2010 174 : sal_uInt16 nNumberOfVirtualPages = 0;
2011 174 : const sal_uInt16 nMaxNumberOfVirtualPages = mnColumns > 0 ? mnColumns - nNumberOfPagesInRow : USHRT_MAX;
2012 174 : SwTwips nRemain = nWidthRemain;
2013 174 : SwTwips nVirtualPagesWidth = 0;
2014 174 : SwTwips nLastPageWidth = pLastPageInCurrentRow->Frm().Width() + nSidebarWidth;
2015 :
2016 614 : while ( ( mnColumns > 0 || nRemain > 0 ) && nNumberOfVirtualPages < nMaxNumberOfVirtualPages )
2017 : {
2018 266 : SwTwips nLastPageWidthWithGap = nLastPageWidth;
2019 266 : if ( !mbBookMode || ( 0 == (nNumberOfVirtualPages + nNumberOfPagesInRow) %2) )
2020 266 : nLastPageWidthWithGap += nGapBetweenPages;
2021 :
2022 266 : if ( mnColumns > 0 || nLastPageWidthWithGap < nRemain )
2023 : {
2024 92 : ++nNumberOfVirtualPages;
2025 92 : nVirtualPagesWidth += nLastPageWidthWithGap;
2026 : }
2027 266 : nRemain = nRemain - nLastPageWidthWithGap;
2028 : }
2029 :
2030 174 : nCurrentRowWidth = nCurrentRowWidth + nVirtualPagesWidth;
2031 : }
2032 :
2033 : // first page in book mode is always special:
2034 51518 : if ( bFirstRow && mbBookMode )
2035 : {
2036 : // #i88036#
2037 : nCurrentRowWidth +=
2038 0 : pStartOfRow->GetFormatPage().Frm().Width() + nSidebarWidth;
2039 : }
2040 :
2041 : // center page if possible
2042 : const long nSizeDiff = nVisWidth > nCurrentRowWidth ?
2043 320 : ( nVisWidth - nCurrentRowWidth ) / 2 :
2044 51838 : 0;
2045 :
2046 : // adjust positions of pages in current row
2047 51518 : long nX = nSizeDiff;
2048 :
2049 51518 : const long nRowStart = nBorder + nSizeDiff;
2050 51518 : const long nRowEnd = nRowStart + nCurrentRowWidth;
2051 :
2052 51518 : if ( bFirstRow && mbBookMode )
2053 : {
2054 : // #i88036#
2055 0 : nX += pStartOfRow->GetFormatPage().Frm().Width() + nSidebarWidth;
2056 : }
2057 :
2058 51518 : SwPageFrm* pEndOfRow = pPageFrm;
2059 51518 : SwPageFrm* pPageToAdjust = pStartOfRow;
2060 :
2061 51808 : do
2062 : {
2063 51808 : const SwPageFrm* pFormatPage = pPageToAdjust;
2064 51808 : if ( mbBookMode )
2065 0 : pFormatPage = &pPageToAdjust->GetFormatPage();
2066 :
2067 51808 : const SwTwips nCurrentPageWidth = pFormatPage->Frm().Width() + (pFormatPage->IsEmptyPage() ? 0 : nSidebarWidth);
2068 51808 : const Point aOldPagePos = pPageToAdjust->Frm().Pos();
2069 51808 : const bool bLeftSidebar = pPageToAdjust->SidebarPosition() == sw::sidebarwindows::SIDEBAR_LEFT;
2070 : const SwTwips nLeftPageAddOffset = bLeftSidebar ?
2071 : nSidebarWidth :
2072 51808 : 0;
2073 :
2074 51808 : Point aNewPagePos( nBorder + nX, nBorder + nSumRowHeight );
2075 51808 : Point aNewPagePosWithLeftOffset( nBorder + nX + nLeftPageAddOffset, nBorder + nSumRowHeight );
2076 :
2077 : // RTL view layout: Calculate mirrored page position
2078 51808 : if ( bRTL )
2079 : {
2080 174 : const long nXOffsetInRow = aNewPagePos.getX() - nRowStart;
2081 174 : aNewPagePos.setX(nRowEnd - nXOffsetInRow - nCurrentPageWidth);
2082 174 : aNewPagePosWithLeftOffset = aNewPagePos;
2083 174 : aNewPagePosWithLeftOffset.setX(aNewPagePosWithLeftOffset.getX() + nLeftPageAddOffset);
2084 : }
2085 :
2086 51808 : if ( aNewPagePosWithLeftOffset != aOldPagePos )
2087 : {
2088 8230 : lcl_MoveAllLowers( pPageToAdjust, aNewPagePosWithLeftOffset - aOldPagePos );
2089 8230 : pPageToAdjust->SetCompletePaint();
2090 8230 : bPageChanged = true;
2091 : }
2092 :
2093 : // calculate area covered by the current page and store to
2094 : // maPageRects. This is used e.g., for cursor setting
2095 51808 : const bool bFirstColumn = pPageToAdjust == pStartOfRow;
2096 51808 : const bool bLastColumn = pPageToAdjust->GetNext() == pEndOfRow;
2097 51808 : const bool bLastRow = !pEndOfRow;
2098 :
2099 51808 : nMinPageLeft = std::min( nMinPageLeft, aNewPagePos.getX() );
2100 51808 : nMaxPageRight = std::max( nMaxPageRight, aNewPagePos.getX() + nCurrentPageWidth);
2101 :
2102 : // border of nGapBetweenPages around the current page:
2103 51808 : SwRect aPageRectWithBorders( aNewPagePos.getX() - nGapBetweenPages,
2104 : aNewPagePos.getY(),
2105 51808 : pPageToAdjust->Frm().SSize().Width() + nGapBetweenPages + nSidebarWidth,
2106 155424 : nCurrentRowHeight );
2107 :
2108 : static const long nOuterClickDiff = 1000000;
2109 :
2110 : // adjust borders for these special cases:
2111 51808 : if ( (bFirstColumn && !bRTL) || (bLastColumn && bRTL) )
2112 51518 : aPageRectWithBorders.SubLeft( nOuterClickDiff );
2113 51808 : if ( (bLastColumn && !bRTL) || (bFirstColumn && bRTL) )
2114 51518 : aPageRectWithBorders.AddRight( nOuterClickDiff );
2115 51808 : if ( bFirstRow )
2116 22394 : aPageRectWithBorders.SubTop( nOuterClickDiff );
2117 51808 : if ( bLastRow )
2118 22440 : aPageRectWithBorders.AddBottom( nOuterClickDiff );
2119 :
2120 51808 : maPageRects.push_back( aPageRectWithBorders );
2121 :
2122 51808 : nX = nX + nCurrentPageWidth;
2123 51808 : pPageToAdjust = static_cast<SwPageFrm*>(pPageToAdjust->GetNext());
2124 :
2125 : // distance to next page
2126 51808 : if ( pPageToAdjust && pPageToAdjust != pEndOfRow )
2127 : {
2128 : // in book view, we add the x gap before left (even) pages:
2129 290 : if ( mbBookMode )
2130 : {
2131 0 : if ( 0 == (pPageToAdjust->GetPhyPageNum()%2) )
2132 0 : nX = nX + nGapBetweenPages;
2133 : }
2134 : else
2135 : {
2136 : // in non-book view, dont add x gap before
2137 : // 1. the last empty page in a row
2138 : // 2. after an empty page
2139 572 : const bool bDontAddGap = ( pPageToAdjust->IsEmptyPage() && pPageToAdjust->GetNext() == pEndOfRow ) ||
2140 572 : ( static_cast<SwPageFrm*>(pPageToAdjust->GetPrev())->IsEmptyPage() );
2141 :
2142 290 : if ( !bDontAddGap )
2143 108 : nX = nX + nGapBetweenPages;
2144 : }
2145 : }
2146 : }
2147 29488 : while (pPageToAdjust && pPageToAdjust != pEndOfRow);
2148 :
2149 : // adjust values for root frame size
2150 51518 : nSumRowHeight = nSumRowHeight + nCurrentRowHeight;
2151 :
2152 : // start new row:
2153 51518 : nCurrentRowHeight = 0;
2154 51518 : nCurrentRowWidth = 0;
2155 51518 : pStartOfRow = pEndOfRow;
2156 51518 : nWidthRemain = nVisWidth;
2157 51518 : nNumberOfPagesInRow = 0;
2158 51518 : bFirstRow = false;
2159 : } // end row finished
2160 : } // end while
2161 :
2162 : // set size of root frame:
2163 22320 : const Size aOldSize( Frm().SSize() );
2164 22320 : const Size aNewSize( nMaxPageRight - nBorder, nSumRowHeight - nGapBetweenPages );
2165 :
2166 22320 : if ( bPageChanged || aNewSize != aOldSize )
2167 : {
2168 8294 : ChgSize( aNewSize );
2169 8294 : ::AdjustSizeChgNotify( this );
2170 8294 : Calc();
2171 :
2172 8294 : SwViewShell* pSh = GetCurrShell();
2173 :
2174 8294 : if ( pSh && pSh->GetDoc()->GetDocShell() )
2175 : {
2176 8270 : pSh->SetFirstVisPageInvalid();
2177 8270 : if (bOldCallbackActionEnabled)
2178 : {
2179 1318 : pSh->InvalidateWindows( SwRect( 0, 0, LONG_MAX, LONG_MAX ) );
2180 1318 : pSh->GetDoc()->GetDocShell()->Broadcast(SfxSimpleHint(SFX_HINT_DOCCHANGED));
2181 : }
2182 : }
2183 : }
2184 :
2185 22320 : maPagesArea.Pos( Frm().Pos() );
2186 22320 : maPagesArea.SSize( aNewSize );
2187 22320 : if ( TWIPS_MAX != nMinPageLeft )
2188 22320 : maPagesArea._Left( nMinPageLeft );
2189 :
2190 22320 : SetCallbackActionEnabled( bOldCallbackActionEnabled );
2191 : }
2192 :
2193 352085 : bool SwRootFrm::IsLeftToRightViewLayout() const
2194 : {
2195 : // Layout direction determined by layout direction of the first page.
2196 : // #i88036#
2197 : // Only ask a non-empty page frame for its layout direction
2198 : const SwPageFrm& rPage =
2199 352085 : dynamic_cast<const SwPageFrm&>(*Lower()).GetFormatPage();
2200 352085 : return !rPage.IsRightToLeft() && !rPage.IsVertical();
2201 : }
2202 :
2203 352085 : const SwPageFrm& SwPageFrm::GetFormatPage() const
2204 : {
2205 352085 : const SwPageFrm* pRet = this;
2206 352085 : if ( IsEmptyPage() )
2207 : {
2208 208 : pRet = static_cast<const SwPageFrm*>( OnRightPage() ? GetNext() : GetPrev() );
2209 : // #i88035#
2210 : // Typically a right empty page frame has a next non-empty page frame and
2211 : // a left empty page frame has a previous non-empty page frame.
2212 : // But under certain cirsumstances this assumption is not true -
2213 : // e.g. during insertion of a left page at the end of the document right
2214 : // after a left page in an intermediate state a right empty page does not
2215 : // have a next page frame.
2216 208 : if ( pRet == 0 )
2217 : {
2218 0 : if ( OnRightPage() )
2219 : {
2220 0 : pRet = static_cast<const SwPageFrm*>( GetPrev() );
2221 : }
2222 : else
2223 : {
2224 0 : pRet = static_cast<const SwPageFrm*>( GetNext() );
2225 : }
2226 : }
2227 : assert(pRet &&
2228 : "<SwPageFrm::GetFormatPage()> - inconsistent layout: empty page without previous and next page frame --> crash.");
2229 : }
2230 352085 : return *pRet;
2231 : }
2232 :
2233 0 : bool SwPageFrm::IsOverHeaderFooterArea( const Point& rPt, FrameControlType &rControl ) const
2234 : {
2235 0 : long nUpperLimit = 0;
2236 0 : long nLowerLimit = 0;
2237 0 : const SwFrm* pFrm = Lower();
2238 0 : while ( pFrm )
2239 : {
2240 0 : if ( pFrm->IsBodyFrm() )
2241 : {
2242 0 : nUpperLimit = pFrm->Frm().Top();
2243 0 : nLowerLimit = pFrm->Frm().Bottom();
2244 : }
2245 0 : else if ( pFrm->IsFtnContFrm() )
2246 0 : nLowerLimit = pFrm->Frm().Bottom();
2247 :
2248 0 : pFrm = pFrm->GetNext();
2249 : }
2250 :
2251 0 : SwRect aHeaderArea( Frm().TopLeft(),
2252 0 : Size( Frm().Width(), nUpperLimit - Frm().Top() ) );
2253 :
2254 0 : if ( aHeaderArea.IsInside( rPt ) )
2255 : {
2256 0 : rControl = Header;
2257 0 : return true;
2258 : }
2259 : else
2260 : {
2261 0 : SwRect aFooterArea( Point( Frm().Left(), nLowerLimit ),
2262 0 : Size( Frm().Width(), Frm().Bottom() - nLowerLimit ) );
2263 :
2264 0 : if ( aFooterArea.IsInside( rPt ) )
2265 : {
2266 0 : rControl = Footer;
2267 0 : return true;
2268 : }
2269 : }
2270 :
2271 0 : return false;
2272 : }
2273 :
2274 803441 : SwTextGridItem const* GetGridItem(SwPageFrm const*const pPage)
2275 : {
2276 803441 : if (pPage && pPage->HasGrid())
2277 : {
2278 : SwTextGridItem const& rGridItem(
2279 8698 : pPage->GetPageDesc()->GetMaster().GetTextGrid());
2280 8698 : if (GRID_NONE != rGridItem.GetGridType())
2281 : {
2282 1172 : return &rGridItem;
2283 : }
2284 : }
2285 802269 : return 0;
2286 : }
2287 :
2288 0 : sal_uInt16 GetGridWidth(SwTextGridItem const& rG, SwDoc const& rDoc)
2289 : {
2290 0 : return (rDoc.IsSquaredPageMode()) ? rG.GetBaseHeight() : rG.GetBaseWidth();
2291 270 : }
2292 :
2293 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|