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