1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
19 #ifndef INCLUDED_SW_SOURCE_CORE_INC_ROOTFRM_HXX
20 #define INCLUDED_SW_SOURCE_CORE_INC_ROOTFRM_HXX
25 #include <IDocumentTimerAccess.hxx>
26 #include <o3tl/typed_flags_set.hxx>
39 class SwSelectionList
;
41 struct SwCursorMoveState
;
44 enum class RedlineMode
49 enum class FieldmarkMode
{ ShowCommand
= 1, ShowResult
= 2, ShowBoth
= 3 };
50 enum class ParagraphBreakMode
{ Shown
, Hidden
};
53 enum class SwInvalidateFlags
66 template<> struct typed_flags
<SwInvalidateFlags
> : is_typed_flags
<SwInvalidateFlags
, 0x7f> {};
69 enum class SwRemoveResult
75 using SwCurrShells
= std::set
<CurrShell
*>;
78 using SwDestroyList
= o3tl::sorted_vector
<SwSectionFrame
*>;
80 using SwFlyDestroyList
= o3tl::sorted_vector
<SwFlyFrame
*>;
82 /// The root element of a Writer document layout. Lower frames are expected to
83 /// be SwPageFrame instances.
84 class SW_DLLPUBLIC SwRootFrame final
: public SwLayoutFrame
86 // Needs to disable the Superfluous temporarily
87 friend void AdjustSizeChgNotify( SwRootFrame
*pRoot
);
89 // Maintains the mpLastPage (Cut() and Paste() of SwPageFrame
90 friend inline void SetLastPage( SwPageFrame
* );
92 // For creating and destroying of the virtual output device manager
93 friend void FrameInit(); // Creates s_pVout
94 friend void FrameFinit(); // Destroys s_pVout
96 std::vector
<SwRect
> maPageRects
;// returns the current rectangle for each page frame
97 // the rectangle is extended to the top/bottom/left/right
98 // for pages located at the outer margins
99 SwRect maPagesArea
; // the area covered by the pages
100 tools::Long mnViewWidth
; // the current page layout bases on this view width
101 sal_uInt16 mnColumns
; // the current page layout bases on this number of columns
102 bool mbBookMode
; // the current page layout is in book view
103 bool mbSidebarChanged
; // the notes sidebar state has changed
105 bool mbNeedGrammarCheck
; // true when sth needs to be checked (not necessarily started yet!)
107 static SwLayVout
*s_pVout
;
108 static bool s_isInPaint
; // Protection against double Paints
109 static bool s_isNoVirDev
;// No virt. Device for SystemPaints
110 /// The last, still alive SwRootFrame instance, for debugging.
111 static SwRootFrame
* s_pLast
;
113 /// Width of the HTML / Web document if not defined otherwise: 20cm.
114 static constexpr sal_Int64 MIN_BROWSE_WIDTH
= o3tl::toTwips(20000, o3tl::Length::mm100
);
116 bool mbCheckSuperfluous
:1; // Search for empty Pages?
117 bool mbIdleFormat
:1; // Trigger Idle Formatter?
118 bool mbBrowseWidthValid
:1; // Is mnBrowseWidth valid?
119 bool mbTurboAllowed
:1;
120 bool mbAssertFlyPages
:1; // Insert more Pages for Flys if needed?
121 bool mbTableUpdateInProgress
: 1; // tdf#139426 to allow suppression of AssertFlyPages during TableUpdate
122 bool mbIsVirtPageNum
:1; // Do we have a virtual pagenumber?
123 bool mbIsNewLayout
:1; // Layout loaded or newly created
124 bool mbCallbackActionEnabled
:1; // No Action in Notification desired
125 // @see dcontact.cxx, ::Changed()
126 bool mbLayoutFreezed
;
128 sw::FieldmarkMode m_FieldmarkMode
;
129 sw::ParagraphBreakMode m_ParagraphBreakMode
;
133 * mnBrowseWidth is the outer margin of the object most to the right.
134 * The page's right edge should not be smaller than this value.
136 tools::Long mnBrowseWidth
;
138 /// If we only have to format one ContentFrame, its in mpTurbo
139 const SwContentFrame
*mpTurbo
;
141 /// We should not need to always struggle to find the last page, so store it here
142 SwPageFrame
*mpLastPage
;
144 /** [ Comment from the original StarOffice checkin ]:
145 * The root takes care of the shell access. Via the document
146 * it should be possible to get at the root frame, and thus always
147 * have access to the shell.
148 * the pointer mpCurrShell is the pointer to any of the shells for
150 * Because sometimes it matters which shell is used, it is necessary to
151 * know the active shell.
152 * this is approximated by setting the pointer mpCurrShell when a
153 * shell gets the focus (FEShell). Additionally the pointer will be
154 * set temporarily by SwCurrShell typically via CurrShell
155 * The class can be found in the SwViewShell. These object can
156 * be created nested (also for different kinds of Shells). They are
157 * collected into the Array mpCurrShells.
158 * Furthermore it can happen that a shell is activated while a curshell
159 * object is still 'active'. This one will be entered into mpWaitingCurrShell
160 * and will be activated by the last d'tor of CurrShell.
161 * One other problem is the destruction of a shell while it is active.
162 * The pointer mpCurrShell is then reset to an arbitrary other shell.
163 * If at the time of the destruction of a shell, which is still referenced
164 * by a curshell object, that will be cleaned up as well.
166 friend class CurrShell
;
167 friend void SetShell( SwViewShell
*pSh
);
168 friend void InitCurrShells( SwRootFrame
*pRoot
);
169 SwViewShell
*mpCurrShell
;
170 SwViewShell
*mpWaitingCurrShell
;
171 std::unique_ptr
<SwCurrShells
> mpCurrShells
;
173 /// One Page per DrawModel per Document; is always the size of the Root
176 std::unique_ptr
<SwDestroyList
> mpDestroy
;
177 std::unique_ptr
<SwFlyDestroyList
> mpFlyDestroy
;
179 sal_uInt16 mnPhyPageNums
; /// Page count
180 sal_uInt16 mnAccessibleShells
; // Number of accessible shells
182 void ImplCalcBrowseWidth();
183 void ImplInvalidateBrowseWidth();
185 void DeleteEmptySct_(); // Destroys the registered SectionFrames
186 /// Destroys the registered FlyFrames.
187 void DeleteEmptyFlys_();
188 void RemoveFromList_( SwSectionFrame
* pSct
); // Removes SectionFrames from the Delete List
190 virtual void DestroyImpl() override
;
191 virtual ~SwRootFrame() override
;
193 virtual void MakeAll(vcl::RenderContext
* pRenderContext
) override
;
197 /// Remove MasterObjects from the Page (called by the ctors)
198 static void RemoveMasterObjs( SdrPage
*pPg
);
200 void AllCheckPageDescs() const;
201 void AllInvalidateAutoCompleteWords() const;
202 void AllAddPaintRect() const;
203 void AllRemoveFootnotes() ;
204 void AllInvalidateSmartTagsOrSpelling(bool bSmartTags
) const;
206 /// Output virtual Device (e.g. for animations)
207 static bool FlushVout();
209 /// Save Clipping if exactly the ClipRect is outputted
210 static bool HasSameRect( const SwRect
& rRect
);
212 SwRootFrame( SwFrameFormat
*, SwViewShell
* );
213 void Init(SwFrameFormat
*);
215 SwViewShell
*GetCurrShell() const { return mpCurrShell
; }
216 void DeRegisterShell( SwViewShell
*pSh
);
219 * Set up Start-/EndAction for all Shells on an as high as possible
220 * (Shell section) level.
221 * For the StarONE binding, which does not know the Shells directly.
222 * The ChangeLinkd of the CursorShell (UI notifications) is called
223 * automatically in the EndAllAction.
225 void StartAllAction();
229 * Certain UNO Actions (e.g. table cursor) require that all Actions are reset temporarily
230 * In order for that to work, every SwViewShell needs to remember its old Action counter
232 void UnoRemoveAllActions();
233 void UnoRestoreAllActions();
235 const SdrPage
* GetDrawPage() const { return mpDrawPage
; }
236 SdrPage
* GetDrawPage() { return mpDrawPage
; }
237 void SetDrawPage( SdrPage
* pNew
){ mpDrawPage
= pNew
; }
239 virtual bool GetModelPositionForViewPoint( SwPosition
*, Point
&,
240 SwCursorMoveState
* = nullptr, bool bTestBackground
= false ) const override
;
242 virtual void PaintSwFrame( vcl::RenderContext
& rRenderContext
, SwRect
const&,
243 SwPrintData
const*const pPrintData
= nullptr ) const override
;
244 virtual SwTwips
ShrinkFrame( SwTwips
, bool bTst
= false, bool bInfo
= false ) override
;
245 virtual SwTwips
GrowFrame ( SwTwips
, bool bTst
= false, bool bInfo
= false ) override
;
247 virtual void Cut() override
;
248 virtual void Paste( SwFrame
* pParent
, SwFrame
* pSibling
= nullptr ) override
;
251 virtual bool FillSelection( SwSelectionList
& rList
, const SwRect
& rRect
) const override
;
253 Point
GetNextPrevContentPos( const Point
&rPoint
, bool bNext
) const;
255 virtual Size
ChgSize( const Size
& aNewSize
) override
;
261 SwViewShell
* pCurrShell
= GetCurrShell();
262 // May be NULL if called from SfxBaseModel::dispose
263 // (this happens in the build test 'rtfexport').
264 if (pCurrShell
!= nullptr)
265 pCurrShell
->GetDoc()->getIDocumentTimerAccess().StartIdling();
267 bool IsIdleFormat() const { return mbIdleFormat
; }
268 void ResetIdleFormat() { mbIdleFormat
= false; }
270 bool IsNeedGrammarCheck() const { return mbNeedGrammarCheck
; }
271 void SetNeedGrammarCheck( bool bVal
)
273 mbNeedGrammarCheck
= bVal
;
277 SwViewShell
* pCurrShell
= GetCurrShell();
278 // May be NULL if called from SfxBaseModel::dispose
279 // (this happens in the build test 'rtfexport').
280 if (pCurrShell
!= nullptr)
281 pCurrShell
->GetDoc()->getIDocumentTimerAccess().StartIdling();
285 /// Makes sure that all requested page-bound Flys find a Page
286 void SetAssertFlyPages() { mbAssertFlyPages
= true; }
287 void AssertFlyPages();
288 bool IsAssertFlyPages() const { return mbAssertFlyPages
; }
290 void SetTableUpdateInProgress(bool bValue
) { mbTableUpdateInProgress
= bValue
; }
291 bool IsTableUpdateInProgress() const { return mbTableUpdateInProgress
; }
294 * Makes sure that, starting from the passed Page, all page-bound Frames
295 * are on the right Page (pagenumber).
297 static void AssertPageFlys( SwPageFrame
* );
299 /// Invalidate all Content, Size or PrtArea
300 void InvalidateAllContent( SwInvalidateFlags nInvalidate
);
303 * Invalidate/re-calculate the position of all floating
304 * screen objects (Writer fly frames and drawing objects), which are
305 * anchored to paragraph or to character.
307 void InvalidateAllObjPos();
309 /// Remove superfluous Pages
310 void SetSuperfluous() { mbCheckSuperfluous
= true; }
311 bool IsSuperfluous() const { return mbCheckSuperfluous
; }
312 void RemoveSuperfluous();
315 * Query/set the current Page and the collective Page count
316 * We'll format as much as necessary
318 sal_uInt16
GetCurrPage( const SwPaM
* ) const;
319 sal_uInt16
SetCurrPage( SwCursor
*, sal_uInt16 nPageNum
);
320 Point
GetPagePos( sal_uInt16 nPageNum
) const;
321 sal_uInt16
GetPageNum() const { return mnPhyPageNums
; }
322 void DecrPhyPageNums() { --mnPhyPageNums
; }
323 void IncrPhyPageNums() { ++mnPhyPageNums
; }
324 bool IsVirtPageNum() const { return mbIsVirtPageNum
; }
325 inline void SetVirtPageNum( const bool bOf
) const;
326 bool IsDummyPage( sal_uInt16 nPageNum
) const;
329 * Point rPt: The point that should be used to find the page
330 * Size pSize: If given, we return the (first) page that overlaps with the
331 * rectangle defined by rPt and pSize
332 * bool bExtend: Extend each page to the left/right/top/bottom up to the
335 const SwPageFrame
* GetPageAtPos( const Point
& rPt
, const Size
* pSize
= nullptr, bool bExtend
= false ) const;
338 * Point rPt: The point to test
339 * @returns true: if rPt is between top/bottom margins of two pages
340 * in hide-whitespace, rPt can be near the gap, but
341 * not strictly between pages (in a page) as gap is small.
342 * @returns false: if rPt is in a page or not strictly between two pages
344 bool IsBetweenPages(const Point
& rPt
) const;
346 void CalcFrameRects( SwShellCursor
& );
349 * Calculates the cells included from the current selection
351 * @returns false: There was no result because of an invalid layout
352 * @returns true: Everything worked fine.
354 bool MakeTableCursors( SwTableCursor
& );
356 void DisallowTurbo() const { const_cast<SwRootFrame
*>(this)->mbTurboAllowed
= false; }
357 void ResetTurboFlag() const { const_cast<SwRootFrame
*>(this)->mbTurboAllowed
= true; }
358 bool IsTurboAllowed() const { return mbTurboAllowed
; }
359 void SetTurbo( const SwContentFrame
*pContent
) { mpTurbo
= pContent
; }
360 void ResetTurbo() { mpTurbo
= nullptr; }
361 const SwContentFrame
*GetTurbo() const { return mpTurbo
; }
363 /// Update the footnote numbers of all Pages
364 void UpdateFootnoteNums(); // Only for page by page numbering!
366 /// Remove all footnotes (but no references)
367 void RemoveFootnotes( SwPageFrame
*pPage
= nullptr, bool bPageOnly
= false,
368 bool bEndNotes
= false );
369 void CheckFootnotePageDescs( bool bEndNote
);
371 const SwPageFrame
*GetLastPage() const { return mpLastPage
; }
372 SwPageFrame
*GetLastPage() { return mpLastPage
; }
374 static bool IsInPaint() { return s_isInPaint
; }
376 static void SetNoVirDev(const bool bNew
) { s_isNoVirDev
= bNew
; }
378 inline tools::Long
GetBrowseWidth() const;
379 inline void InvalidateBrowseWidth();
381 bool IsNewLayout() const { return mbIsNewLayout
; }
382 void ResetNewLayout() { mbIsNewLayout
= false;}
385 * Empty SwSectionFrames are registered here for deletion and
386 * destroyed later on or deregistered.
388 void InsertEmptySct( SwSectionFrame
* pDel
);
389 /// Empty SwFlyFrames are registered here for deletion and destroyed later if they are not
390 /// de-registered in the meantime.
391 void InsertEmptyFly(SwFlyFrame
* pDel
);
392 void DeleteEmptySct() { if( mpDestroy
) DeleteEmptySct_(); }
393 void DeleteEmptyFlys() { if( mpFlyDestroy
) DeleteEmptyFlys_(); }
394 void RemoveFromList( SwSectionFrame
* pSct
) { if( mpDestroy
) RemoveFromList_( pSct
); }
396 bool IsInDelList( SwSectionFrame
* pSct
) const;
398 bool IsInFlyDelList( SwFlyFrame
* pFly
) const;
400 void SetCallbackActionEnabled( bool b
) { mbCallbackActionEnabled
= b
; }
401 bool IsCallbackActionEnabled() const { return mbCallbackActionEnabled
; }
403 bool IsAnyShellAccessible() const { return mnAccessibleShells
> 0; }
404 void AddAccessibleShell() { ++mnAccessibleShells
; }
405 void RemoveAccessibleShell() { --mnAccessibleShells
; }
408 * Get page frame by physical page number
409 * looping through the lowers, which are page frame, in order to find the
410 * page frame with the given physical page number.
411 * if no page frame is found, 0 is returned.
412 * Note: Empty page frames are also returned.
414 * @param _nPageNum: physical page number of page frame to be searched and
417 * @return pointer to the page frame with the given physical page number
419 SwPageFrame
* GetPageByPageNum( sal_uInt16 _nPageNum
) const;
421 void CheckViewLayout( const SwViewOption
* pViewOpt
, const SwRect
* pVisArea
);
422 bool IsLeftToRightViewLayout() const;
423 const SwRect
& GetPagesArea() const { return maPagesArea
; }
424 void SetSidebarChanged() { mbSidebarChanged
= true; }
426 bool IsLayoutFreezed() const { return mbLayoutFreezed
; }
427 void FreezeLayout( bool freeze
) { mbLayoutFreezed
= freeze
; }
429 void RemovePage( SwPageFrame
**pDel
, SwRemoveResult eResult
);
432 * Replacement for sw::DocumentRedlineManager::GetRedlineFlags()
433 * (this is layout-level redline hiding).
435 bool IsHideRedlines() const { return mbHideRedlines
; }
436 void SetHideRedlines(bool);
437 sw::FieldmarkMode
GetFieldmarkMode() const { return m_FieldmarkMode
; }
438 void SetFieldmarkMode(sw::FieldmarkMode
, sw::ParagraphBreakMode
);
439 sw::ParagraphBreakMode
GetParagraphBreakMode() const { return m_ParagraphBreakMode
; }
440 bool HasMergedParas() const;
442 void dumpAsXml(xmlTextWriterPtr writer
= nullptr) const override
;
445 inline tools::Long
SwRootFrame::GetBrowseWidth() const
447 if ( !mbBrowseWidthValid
)
448 const_cast<SwRootFrame
*>(this)->ImplCalcBrowseWidth();
449 return mnBrowseWidth
;
452 inline void SwRootFrame::InvalidateBrowseWidth()
454 if ( mbBrowseWidthValid
)
455 ImplInvalidateBrowseWidth();
458 inline void SwRootFrame::SetVirtPageNum( const bool bOf
) const
460 const_cast<SwRootFrame
*>(this)->mbIsVirtPageNum
= bOf
;
463 /// helper class to disable creation of an action by a callback event
464 /// in particular, change event from a drawing object (SwDrawContact::Changed())
465 class DisableCallbackAction
468 SwRootFrame
& m_rRootFrame
;
469 bool m_bOldCallbackActionState
;
472 explicit DisableCallbackAction(SwRootFrame
& rRootFrame
)
473 : m_rRootFrame(rRootFrame
)
474 , m_bOldCallbackActionState(rRootFrame
.IsCallbackActionEnabled())
476 m_rRootFrame
.SetCallbackActionEnabled(false);
479 ~DisableCallbackAction()
481 m_rRootFrame
.SetCallbackActionEnabled(m_bOldCallbackActionState
);
485 #endif // INCLUDED_SW_SOURCE_CORE_INC_ROOTFRM_HXX
487 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */