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 <sal/config.h>
21
22 #include <o3tl/safeint.hxx>
23 #include <svx/svdpage.hxx>
24 #include <osl/diagnose.h>
25 #include <drawdoc.hxx>
26 #include <fmtpdsc.hxx>
27 #include <swtable.hxx>
28 #include <rootfrm.hxx>
29 #include <pagefrm.hxx>
30 #include <dflyobj.hxx>
31 #include <frmtool.hxx>
32 #include "virtoutp.hxx"
33 #include <notxtfrm.hxx>
34 #include <pagedesc.hxx>
35 #include <viewimp.hxx>
36 #include <hints.hxx>
37 #include <viewopt.hxx>
38 #include <set>
39 #include <IDocumentDrawModelAccess.hxx>
40 #include <IDocumentSettingAccess.hxx>
41 #include <IDocumentFieldsAccess.hxx>
42 #include <DocumentLayoutManager.hxx>
43 #include <DocumentRedlineManager.hxx>
44 #include <ndindex.hxx>
45
46 SwLayVout *SwRootFrame::s_pVout = nullptr;
47 bool SwRootFrame::s_isInPaint = false;
48 bool SwRootFrame::s_isNoVirDev = false;
49
50 SwCache *SwFrame::spCache = nullptr;
51
FirstMinusSecond(tools::Long nFirst,tools::Long nSecond)52 static tools::Long FirstMinusSecond( tools::Long nFirst, tools::Long nSecond )
53 { return nFirst - nSecond; }
SecondMinusFirst(tools::Long nFirst,tools::Long nSecond)54 static tools::Long SecondMinusFirst( tools::Long nFirst, tools::Long nSecond )
55 { return nSecond - nFirst; }
SwIncrement(tools::Long nA,tools::Long nAdd)56 static tools::Long SwIncrement( tools::Long nA, tools::Long nAdd )
57 { return nA + nAdd; }
SwDecrement(tools::Long nA,tools::Long nSub)58 static tools::Long SwDecrement( tools::Long nA, tools::Long nSub )
59 { return nA - nSub; }
60
61 static SwRectFnCollection aHorizontal = {
62 /*.fnGetTop =*/&SwRect::Top_,
63 /*.fnGetBottom =*/&SwRect::Bottom_,
64 /*.fnGetLeft =*/&SwRect::Left_,
65 /*.fnGetRight =*/&SwRect::Right_,
66 /*.fnGetWidth =*/&SwRect::Width_,
67 /*.fnGetHeight =*/&SwRect::Height_,
68 /*.fnGetPos =*/&SwRect::TopLeft,
69 /*.fnGetSize =*/&SwRect::Size_,
70
71 /*.fnSetTop =*/&SwRect::Top_,
72 /*.fnSetBottom =*/&SwRect::Bottom_,
73 /*.fnSetLeft =*/&SwRect::Left_,
74 /*.fnSetRight =*/&SwRect::Right_,
75 /*.fnSetWidth =*/&SwRect::Width_,
76 /*.fnSetHeight =*/&SwRect::Height_,
77
78 /*.fnSubTop =*/&SwRect::SubTop,
79 /*.fnAddBottom =*/&SwRect::AddBottom,
80 /*.fnSubLeft =*/&SwRect::SubLeft,
81 /*.fnAddRight =*/&SwRect::AddRight,
82 /*.fnAddWidth =*/&SwRect::AddWidth,
83 /*.fnAddHeight =*/&SwRect::AddHeight,
84
85 /*.fnSetPosX =*/&SwRect::SetPosX,
86 /*.fnSetPosY =*/&SwRect::SetPosY,
87
88 /*.fnGetTopMargin =*/&SwFrame::GetTopMargin,
89 /*.fnGetBottomMargin =*/&SwFrame::GetBottomMargin,
90 /*.fnGetLeftMargin =*/&SwFrame::GetLeftMargin,
91 /*.fnGetRightMargin =*/&SwFrame::GetRightMargin,
92 /*.fnSetXMargins =*/&SwFrame::SetLeftRightMargins,
93 /*.fnSetYMargins =*/&SwFrame::SetTopBottomMargins,
94 /*.fnGetPrtTop =*/&SwFrame::GetPrtTop,
95 /*.fnGetPrtBottom =*/&SwFrame::GetPrtBottom,
96 /*.fnGetPrtLeft =*/&SwFrame::GetPrtLeft,
97 /*.fnGetPrtRight =*/&SwFrame::GetPrtRight,
98 /*.fnTopDist =*/&SwRect::GetTopDistance,
99 /*.fnBottomDist =*/&SwRect::GetBottomDistance,
100 /*.fnLeftDist =*/&SwRect::GetLeftDistance,
101 /*.fnRightDist =*/&SwRect::GetRightDistance,
102 /*.fnSetLimit =*/&SwFrame::SetMaxBottom,
103 /*.fnOverStep =*/&SwRect::OverStepBottom,
104
105 /*.fnSetPos =*/&SwRect::SetUpperLeftCorner,
106 /*.fnMakePos =*/&SwFrame::MakeBelowPos,
107 /*.fnXDiff =*/&FirstMinusSecond,
108 /*.fnYDiff =*/&FirstMinusSecond,
109 /*.fnXInc =*/&SwIncrement,
110 /*.fnYInc =*/&o3tl::saturating_add<tools::Long>,
111
112 /*.fnSetLeftAndWidth =*/&SwRect::SetLeftAndWidth,
113 /*.fnSetTopAndHeight =*/&SwRect::SetTopAndHeight
114 };
115
116 static SwRectFnCollection aVertical = {
117 /*.fnGetTop =*/&SwRect::Right_,
118 /*.fnGetBottom =*/&SwRect::Left_,
119 /*.fnGetLeft =*/&SwRect::Top_,
120 /*.fnGetRight =*/&SwRect::Bottom_,
121 /*.fnGetWidth =*/&SwRect::Height_,
122 /*.fnGetHeight =*/&SwRect::Width_,
123 /*.fnGetPos =*/&SwRect::TopRight,
124 /*.fnGetSize =*/&SwRect::SwappedSize,
125
126 /*.fnSetTop =*/&SwRect::Right_,
127 /*.fnSetBottom =*/&SwRect::Left_,
128 /*.fnSetLeft =*/&SwRect::Top_,
129 /*.fnSetRight =*/&SwRect::Bottom_,
130 /*.fnSetWidth =*/&SwRect::Height_,
131 /*.fnSetHeight =*/&SwRect::Width_,
132
133 /*.fnSubTop =*/&SwRect::AddRight,
134 /*.fnAddBottom =*/&SwRect::SubLeft,
135 /*.fnSubLeft =*/&SwRect::SubTop,
136 /*.fnAddRight =*/&SwRect::AddBottom,
137 /*.fnAddWidth =*/&SwRect::AddHeight,
138 /*.fnAddHeight =*/&SwRect::AddWidth,
139
140 /*.fnSetPosX =*/&SwRect::SetPosY,
141 /*.fnSetPosY =*/&SwRect::SetPosX,
142
143 /*.fnGetTopMargin =*/&SwFrame::GetRightMargin,
144 /*.fnGetBottomMargin =*/&SwFrame::GetLeftMargin,
145 /*.fnGetLeftMargin =*/&SwFrame::GetTopMargin,
146 /*.fnGetRightMargin =*/&SwFrame::GetBottomMargin,
147 /*.fnSetXMargins =*/&SwFrame::SetTopBottomMargins,
148 /*.fnSetYMargins =*/&SwFrame::SetRightLeftMargins,
149 /*.fnGetPrtTop =*/&SwFrame::GetPrtRight,
150 /*.fnGetPrtBottom =*/&SwFrame::GetPrtLeft,
151 /*.fnGetPrtLeft =*/&SwFrame::GetPrtTop,
152 /*.fnGetPrtRight =*/&SwFrame::GetPrtBottom,
153 /*.fnTopDist =*/&SwRect::GetRightDistance,
154 /*.fnBottomDist =*/&SwRect::GetLeftDistance,
155 /*.fnLeftDist =*/&SwRect::GetTopDistance,
156 /*.fnRightDist =*/&SwRect::GetBottomDistance,
157 /*.fnSetLimit =*/&SwFrame::SetMinLeft,
158 /*.fnOverStep =*/&SwRect::OverStepLeft,
159
160 /*.fnSetPos =*/&SwRect::SetUpperRightCorner,
161 /*.fnMakePos =*/&SwFrame::MakeLeftPos,
162 /*.fnXDiff =*/&FirstMinusSecond,
163 /*.fnYDiff =*/&SecondMinusFirst,
164 /*.fnXInc =*/&SwIncrement,
165 /*.fnYInc =*/&SwDecrement,
166
167 /*.fnSetLeftAndWidth =*/&SwRect::SetTopAndHeight,
168 /*.fnSetTopAndHeight =*/&SwRect::SetRightAndWidth
169 };
170
171 static SwRectFnCollection aVerticalLeftToRight = {
172 /*.fnGetTop =*/&SwRect::Left_,
173 /*.fnGetBottom =*/&SwRect::Right_,
174 /*.fnGetLeft =*/&SwRect::Top_,
175 /*.fnGetRight =*/&SwRect::Bottom_,
176 /*.fnGetWidth =*/&SwRect::Height_,
177 /*.fnGetHeight =*/&SwRect::Width_,
178 /*.fnGetPos =*/&SwRect::TopLeft,
179 /*.fnGetSize =*/&SwRect::SwappedSize,
180
181 /*.fnSetTop =*/&SwRect::Left_,
182 /*.fnSetBottom =*/&SwRect::Right_,
183 /*.fnSetLeft =*/&SwRect::Top_,
184 /*.fnSetRight =*/&SwRect::Bottom_,
185 /*.fnSetWidth =*/&SwRect::Height_,
186 /*.fnSetHeight =*/&SwRect::Width_,
187
188 /*.fnSubTop =*/&SwRect::SubLeft,
189 /*.fnAddBottom =*/&SwRect::AddRight,
190 /*.fnSubLeft =*/&SwRect::SubTop,
191 /*.fnAddRight =*/&SwRect::AddBottom,
192 /*.fnAddWidth =*/&SwRect::AddHeight,
193 /*.fnAddHeight =*/&SwRect::AddWidth,
194
195 /*.fnSetPosX =*/&SwRect::SetPosY,
196 /*.fnSetPosY =*/&SwRect::SetPosX,
197
198 /*.fnGetTopMargin =*/&SwFrame::GetLeftMargin,
199 /*.fnGetBottomMargin =*/&SwFrame::GetRightMargin,
200 /*.fnGetLeftMargin =*/&SwFrame::GetTopMargin,
201 /*.fnGetRightMargin =*/&SwFrame::GetBottomMargin,
202 /*.fnSetXMargins =*/&SwFrame::SetTopBottomMargins,
203 /*.fnSetYMargins =*/&SwFrame::SetLeftRightMargins,
204 /*.fnGetPrtTop =*/&SwFrame::GetPrtLeft,
205 /*.fnGetPrtBottom =*/&SwFrame::GetPrtRight,
206 /*.fnGetPrtLeft =*/&SwFrame::GetPrtTop,
207 /*.fnGetPrtRight =*/&SwFrame::GetPrtBottom,
208 /*.fnTopDist =*/&SwRect::GetLeftDistance,
209 /*.fnBottomDist =*/&SwRect::GetRightDistance,
210 /*.fnLeftDist =*/&SwRect::GetTopDistance,
211 /*.fnRightDist =*/&SwRect::GetBottomDistance,
212 /*.fnSetLimit =*/&SwFrame::SetMaxRight,
213 /*.fnOverStep =*/&SwRect::OverStepRight,
214
215 /*.fnSetPos =*/&SwRect::SetUpperLeftCorner,
216 /*.fnMakePos =*/&SwFrame::MakeRightPos,
217 /*.fnXDiff =*/&FirstMinusSecond,
218 /*.fnYDiff =*/&FirstMinusSecond,
219 /*.fnXInc =*/&SwIncrement,
220 /*.fnYInc =*/&SwIncrement,
221
222 /*.fnSetLeftAndWidth =*/&SwRect::SetTopAndHeight,
223 /*.fnSetTopAndHeight =*/&SwRect::SetLeftAndWidth
224 };
225
226 /**
227 * This is the same as horizontal, but rotated counter-clockwise by 90 degrees.
228 * This means logical top is physical left, bottom is right, left is bottom,
229 * finally right is top. Values map from logical to physical.
230 */
231 static SwRectFnCollection aVerticalLeftToRightBottomToTop = {
232 /*.fnGetTop =*/&SwRect::Left_,
233 /*.fnGetBottom =*/&SwRect::Right_,
234 /*.fnGetLeft =*/&SwRect::Bottom_,
235 /*.fnGetRight =*/&SwRect::Top_,
236 /*.fnGetWidth =*/&SwRect::Height_,
237 /*.fnGetHeight =*/&SwRect::Width_,
238 /*.fnGetPos =*/&SwRect::BottomLeft,
239 /*.fnGetSize =*/&SwRect::SwappedSize,
240
241 /*.fnSetTop =*/&SwRect::Left_,
242 /*.fnSetBottom =*/&SwRect::Right_,
243 /*.fnSetLeft =*/&SwRect::Bottom_,
244 /*.fnSetRight =*/&SwRect::Top_,
245 /*.fnSetWidth =*/&SwRect::Height_,
246 /*.fnSetHeight =*/&SwRect::Width_,
247
248 /*.fnSubTop =*/&SwRect::SubLeft,
249 /*.fnAddBottom =*/&SwRect::AddRight,
250 /*.fnSubLeft =*/&SwRect::AddBottom,
251 /*.fnAddRight =*/&SwRect::SubTop,
252 /*.fnAddWidth =*/&SwRect::AddHeight,
253 /*.fnAddHeight =*/&SwRect::AddWidth,
254
255 /*.fnSetPosX =*/&SwRect::SetPosY,
256 /*.fnSetPosY =*/&SwRect::SetPosX,
257
258 /*.fnGetTopMargin =*/&SwFrame::GetLeftMargin,
259 /*.fnGetBottomMargin =*/&SwFrame::GetRightMargin,
260 /*.fnGetLeftMargin =*/&SwFrame::GetBottomMargin,
261 /*.fnGetRightMargin =*/&SwFrame::GetTopMargin,
262 /*.fnSetXMargins =*/&SwFrame::SetTopBottomMargins,
263 /*.fnSetYMargins =*/&SwFrame::SetLeftRightMargins,
264 /*.fnGetPrtTop =*/&SwFrame::GetPrtLeft,
265 /*.fnGetPrtBottom =*/&SwFrame::GetPrtRight,
266 /*.fnGetPrtLeft =*/&SwFrame::GetPrtBottom,
267 /*.fnGetPrtRight =*/&SwFrame::GetPrtTop,
268 /*.fnTopDist =*/&SwRect::GetLeftDistance,
269 /*.fnBottomDist =*/&SwRect::GetRightDistance,
270 /*.fnLeftDist =*/&SwRect::GetBottomDistance,
271 /*.fnRightDist =*/&SwRect::GetTopDistance,
272 /*.fnSetLimit =*/&SwFrame::SetMaxRight,
273 /*.fnOverStep =*/&SwRect::OverStepRight,
274
275 /*.fnSetPos =*/&SwRect::SetLowerLeftCorner,
276 /*.fnMakePos =*/&SwFrame::MakeRightPos,
277 /*.fnXDiff =*/&SecondMinusFirst,
278 /*.fnYDiff =*/&FirstMinusSecond,
279 /*.fnXInc =*/&SwDecrement,
280 /*.fnYInc =*/&SwIncrement,
281
282 /*.fnSetLeftAndWidth =*/&SwRect::SetBottomAndHeight,
283 /*.fnSetTopAndHeight =*/&SwRect::SetLeftAndWidth
284 };
285
286 SwRectFn fnRectHori = &aHorizontal;
287 SwRectFn fnRectVert = &aVertical;
288 SwRectFn fnRectVertL2R = &aVerticalLeftToRight;
289 SwRectFn fnRectVertL2RB2T = &aVerticalLeftToRightBottomToTop;
290
291 // #i65250#
292 sal_uInt32 SwFrameAreaDefinition::snLastFrameId=0;
293
294
FrameInit()295 void FrameInit()
296 {
297 SwRootFrame::s_pVout = new SwLayVout();
298 SwCache *pNew = new SwCache( 100
299 #ifdef DBG_UTIL
300 , "static SwBorderAttrs::pCache"
301 #endif
302 );
303 SwFrame::SetCache( pNew );
304 }
305
FrameFinit()306 void FrameFinit()
307 {
308 #if OSL_DEBUG_LEVEL > 0
309 // The cache may only contain null pointers at this time.
310 for( size_t n = SwFrame::GetCachePtr()->size(); n; )
311 if( (*SwFrame::GetCachePtr())[ --n ] )
312 {
313 SwCacheObj* pObj = (*SwFrame::GetCachePtr())[ n ];
314 OSL_ENSURE( !pObj, "Who didn't deregister?");
315 }
316 #endif
317 delete SwRootFrame::s_pVout;
318 delete SwFrame::GetCachePtr();
319 }
320
321 // RootFrame::Everything that belongs to CurrShell
322
CurrShell(SwViewShell * pNew)323 CurrShell::CurrShell( SwViewShell *pNew )
324 {
325 OSL_ENSURE( pNew, "insert 0-Shell?" );
326 pRoot = pNew->GetLayout();
327 if ( pRoot )
328 {
329 pPrev = pRoot->mpCurrShell;
330 pRoot->mpCurrShell = pNew;
331 pRoot->mpCurrShells->insert( this );
332 }
333 else
334 pPrev = nullptr;
335 }
336
~CurrShell()337 CurrShell::~CurrShell()
338 {
339 if ( pRoot )
340 {
341 pRoot->mpCurrShells->erase( this );
342 if ( pPrev )
343 pRoot->mpCurrShell = pPrev;
344 if ( pRoot->mpCurrShells->empty() && pRoot->mpWaitingCurrShell )
345 {
346 pRoot->mpCurrShell = pRoot->mpWaitingCurrShell;
347 pRoot->mpWaitingCurrShell = nullptr;
348 }
349 }
350 }
351
SetShell(SwViewShell * pSh)352 void SetShell( SwViewShell *pSh )
353 {
354 SwRootFrame *pRoot = pSh->GetLayout();
355 if ( pRoot->mpCurrShells->empty() )
356 pRoot->mpCurrShell = pSh;
357 else
358 pRoot->mpWaitingCurrShell = pSh;
359 }
360
DeRegisterShell(SwViewShell * pSh)361 void SwRootFrame::DeRegisterShell( SwViewShell *pSh )
362 {
363 // Activate some shell if possible
364 if ( mpCurrShell == pSh )
365 {
366 mpCurrShell = nullptr;
367 for(SwViewShell& rShell : pSh->GetRingContainer())
368 {
369 if(&rShell != pSh)
370 {
371 mpCurrShell = &rShell;
372 break;
373 }
374 }
375 }
376
377 // Doesn't matter anymore
378 if ( mpWaitingCurrShell == pSh )
379 mpWaitingCurrShell = nullptr;
380
381 // Remove references
382 for ( CurrShell *pC : *mpCurrShells )
383 {
384 if (pC->pPrev == pSh)
385 pC->pPrev = nullptr;
386 }
387 }
388
InitCurrShells(SwRootFrame * pRoot)389 void InitCurrShells( SwRootFrame *pRoot )
390 {
391 pRoot->mpCurrShells.reset( new SwCurrShells );
392 }
393
394 /*
395 |* The RootFrame requests an own FrameFormat from the document, which it is
396 |* going to delete again in the dtor. The own FrameFormat is derived from
397 |* the passed FrameFormat.
398 |*/
SwRootFrame(SwFrameFormat * pFormat,SwViewShell * pSh)399 SwRootFrame::SwRootFrame( SwFrameFormat *pFormat, SwViewShell * pSh ) :
400 SwLayoutFrame( pFormat->GetDoc()->MakeFrameFormat(
401 "Root", pFormat ), nullptr ),
402 maPagesArea(),
403 mnViewWidth( -1 ),
404 mnColumns( 0 ),
405 mbBookMode( false ),
406 mbSidebarChanged( false ),
407 mbNeedGrammarCheck( false ),
408 mbCheckSuperfluous( false ),
409 mbIdleFormat( true ),
410 mbBrowseWidthValid( false ),
411 mbTurboAllowed( true ),
412 mbAssertFlyPages( true ),
413 mbTableUpdateInProgress( false ),
414 mbIsVirtPageNum( false ),
415 mbIsNewLayout( true ),
416 mbCallbackActionEnabled ( false ),
417 mbLayoutFreezed ( false ),
418 mbHideRedlines(pFormat->GetDoc()->GetDocumentRedlineManager().IsHideRedlines()),
419 m_FieldmarkMode(sw::FieldmarkMode::ShowBoth),
420 mnBrowseWidth(MIN_BROWSE_WIDTH),
421 mpTurbo( nullptr ),
422 mpLastPage( nullptr ),
423 mpCurrShell( pSh ),
424 mpWaitingCurrShell( nullptr ),
425 mpDrawPage( nullptr ),
426 mnPhyPageNums( 0 ),
427 mnAccessibleShells( 0 )
428 {
429 mnFrameType = SwFrameType::Root;
430 setRootFrame( this );
431 }
432
Init(SwFrameFormat * pFormat)433 void SwRootFrame::Init( SwFrameFormat* pFormat )
434 {
435 InitCurrShells( this );
436
437 IDocumentTimerAccess& rTimerAccess = pFormat->getIDocumentTimerAccess();
438 IDocumentLayoutAccess& rLayoutAccess = pFormat->getIDocumentLayoutAccess();
439 IDocumentFieldsAccess& rFieldsAccess = pFormat->getIDocumentFieldsAccess();
440 const IDocumentSettingAccess& rSettingAccess = pFormat->getIDocumentSettingAccess();
441 rTimerAccess.StopIdling();
442 // For creating the Flys by MakeFrames()
443 rLayoutAccess.SetCurrentViewShell( GetCurrShell() );
444 mbCallbackActionEnabled = false; // needs to be set to true before leaving!
445
446 SwDrawModel* pMd = pFormat->getIDocumentDrawModelAccess().GetDrawModel();
447 if ( pMd )
448 {
449 // Disable "multiple layout"
450 mpDrawPage = pMd->GetPage(0);
451
452 mpDrawPage->SetSize( getFrameArea().SSize() );
453 }
454
455 // Initialize the layout: create pages, link content with Content etc.
456 // First, initialize some stuff, then get hold of the first
457 // node (which will be needed for the PageDesc).
458
459 SwDoc* pDoc = pFormat->GetDoc();
460 SwNodeIndex aIndex( *pDoc->GetNodes().GetEndOfContent().StartOfSectionNode() );
461 SwContentNode *pNode = pDoc->GetNodes().GoNextSection( &aIndex, true, false );
462 // #123067# pNode = 0 can really happen
463 SwTableNode *pTableNd= pNode ? pNode->FindTableNode() : nullptr;
464
465 // Get hold of PageDesc (either via FrameFormat of the first node or the initial one).
466 SwPageDesc *pDesc = nullptr;
467 ::std::optional<sal_uInt16> oPgNum;
468
469 if ( pTableNd )
470 {
471 const SwFormatPageDesc &rDesc = pTableNd->GetTable().GetFrameFormat()->GetPageDesc();
472 pDesc = const_cast<SwPageDesc*>(rDesc.GetPageDesc());
473 //#19104# respect the page number offset!!
474 oPgNum = rDesc.GetNumOffset();
475 if (oPgNum)
476 mbIsVirtPageNum = true;
477 }
478 else if ( pNode )
479 {
480 const SwFormatPageDesc &rDesc = pNode->GetSwAttrSet().GetPageDesc();
481 pDesc = const_cast<SwPageDesc*>(rDesc.GetPageDesc());
482 //#19104# respect the page number offset!!
483 oPgNum = rDesc.GetNumOffset();
484 if (oPgNum)
485 mbIsVirtPageNum = true;
486 }
487 else
488 mbIsVirtPageNum = false;
489 if ( !pDesc )
490 pDesc = &pDoc->GetPageDesc( 0 );
491
492 // Create a page and put it in the layout
493 // The first page is always a right-page and always a first-page
494 SwPageFrame* pPage = ::InsertNewPage(
495 *pDesc, /*pUpper=*/this, /*isRightPage=*/true, /*bFirst=*/true, /*bInsertEmpty=*/false,
496 /*bFootnote=*/false, /*pSibling=*/nullptr, /*bVeryFirstPage=*/true);
497
498 // Find the first page in the Bodytext section.
499 SwLayoutFrame *pLay = pPage->FindBodyCont();
500 while( pLay->Lower() )
501 pLay = static_cast<SwLayoutFrame*>(pLay->Lower());
502
503 SwNodeIndex aTmp( *pDoc->GetNodes().GetEndOfContent().StartOfSectionNode(), 1 );
504 ::InsertCnt_( pLay, pDoc, aTmp.GetIndex(), true );
505
506 if( rSettingAccess.get(DocumentSettingId::GLOBAL_DOCUMENT) )
507 rFieldsAccess.UpdateRefFields();
508 //b6433357: Update page fields after loading
509 if ( !mpCurrShell || !mpCurrShell->Imp()->IsUpdateExpFields() )
510 {
511 SwDocPosUpdate aMsgHint( pPage->getFrameArea().Top() );
512 rFieldsAccess.UpdatePageFields( &aMsgHint );
513 }
514
515 rTimerAccess.StartIdling();
516 mbCallbackActionEnabled = true;
517
518 SwViewShell *pViewSh = GetCurrShell();
519 if (pViewSh)
520 mbNeedGrammarCheck = pViewSh->GetViewOptions()->IsOnlineSpell();
521 }
522
DestroyImpl()523 void SwRootFrame::DestroyImpl()
524 {
525 mbTurboAllowed = false;
526 mpTurbo = nullptr;
527
528 SwFrameFormat *pRegisteredInNonConst = static_cast<SwFrameFormat*>(GetDep());
529 if ( pRegisteredInNonConst )
530 {
531 SwDoc *pDoc = pRegisteredInNonConst->GetDoc();
532 pDoc->DelFrameFormat( pRegisteredInNonConst );
533 // do this before calling RemoveFootnotes() because footnotes
534 // can contain anchored objects
535 pDoc->GetDocumentLayoutManager().ClearSwLayouterEntries();
536 }
537
538 mpDestroy.reset();
539
540 // Remove references
541 for ( auto& rpCurrShell : *mpCurrShells )
542 rpCurrShell->pRoot = nullptr;
543
544 mpCurrShells.reset();
545
546 // Some accessible shells are left => problems on second SwFrame::Destroy call
547 assert(0 == mnAccessibleShells);
548
549 // fdo#39510 crash on document close with footnotes
550 // Object ownership in writer and esp. in layout are a mess: Before the
551 // document/layout split SwDoc and SwRootFrame were essentially one object
552 // and magically/uncleanly worked around their common destruction by call
553 // to SwDoc::IsInDtor() -- even from the layout. As of now destruction of
554 // the layout proceeds forward through the frames. Since SwTextFootnote::DelFrames
555 // also searches backwards to find the master of footnotes, they must be
556 // considered to be owned by the SwRootFrame and also be destroyed here,
557 // before tearing down the (now footnote free) rest of the layout.
558 RemoveFootnotes(nullptr, false, true);
559
560 SwLayoutFrame::DestroyImpl();
561 }
562
~SwRootFrame()563 SwRootFrame::~SwRootFrame()
564 {
565 }
566
RemoveMasterObjs(SdrPage * pPg)567 void SwRootFrame::RemoveMasterObjs( SdrPage *pPg )
568 {
569 // Remove all master objects from the Page. But don't delete!
570 for( size_t i = pPg ? pPg->GetObjCount() : 0; i; )
571 {
572 SdrObject* pObj = pPg->GetObj( --i );
573 if( dynamic_cast< const SwFlyDrawObj *>( pObj ) != nullptr )
574 pPg->RemoveObject( i );
575 }
576 }
577
AllCheckPageDescs() const578 void SwRootFrame::AllCheckPageDescs() const
579 {
580 if ( !IsLayoutFreezed() )
581 CheckPageDescs( const_cast<SwPageFrame*>(static_cast<const SwPageFrame*>(Lower())) );
582 }
583
AllInvalidateAutoCompleteWords() const584 void SwRootFrame::AllInvalidateAutoCompleteWords() const
585 {
586 SwPageFrame *pPage = const_cast<SwPageFrame*>(static_cast<const SwPageFrame*>(Lower()));
587 while ( pPage )
588 {
589 pPage->InvalidateAutoCompleteWords();
590 pPage = static_cast<SwPageFrame*>(pPage->GetNext());
591 }
592 }
593
AllAddPaintRect() const594 void SwRootFrame::AllAddPaintRect() const
595 {
596 GetCurrShell()->AddPaintRect( getFrameArea() );
597 }
598
AllRemoveFootnotes()599 void SwRootFrame::AllRemoveFootnotes()
600 {
601 RemoveFootnotes();
602 }
603
AllInvalidateSmartTagsOrSpelling(bool bSmartTags) const604 void SwRootFrame::AllInvalidateSmartTagsOrSpelling(bool bSmartTags) const
605 {
606 SwPageFrame *pPage = const_cast<SwPageFrame*>(static_cast<const SwPageFrame*>(Lower()));
607 while ( pPage )
608 {
609 if ( bSmartTags )
610 pPage->InvalidateSmartTags();
611
612 pPage->InvalidateSpelling();
613 pPage = static_cast<SwPageFrame*>(pPage->GetNext());
614 }
615 }
616
617 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
618