xref: /core/sw/source/core/inc/frmtool.hxx (revision ebe1f639)
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 #ifndef INCLUDED_SW_SOURCE_CORE_INC_FRMTOOL_HXX
21 #define INCLUDED_SW_SOURCE_CORE_INC_FRMTOOL_HXX
22 
23 #include <swtypes.hxx>
24 #include <BorderCacheOwner.hxx>
25 #include "frame.hxx"
26 #include "txtfrm.hxx"
27 #include "swcache.hxx"
28 #include <swatrset.hxx>
29 
30 class SwLayoutFrame;
31 class SwFont;
32 class SwTextFrame;
33 class SwFormatAnchor;
34 class SwViewShell;
35 class SwPageFrame;
36 class SwFlyFrame;
37 class SwContentFrame;
38 class SwRootFrame;
39 class SwDoc;
40 class SdrObject;
41 class SvxBrushItem;
42 class SdrMarkList;
43 class SwNodeIndex;
44 class GraphicObject;
45 class GraphicAttr;
46 class SwPageDesc;
47 class SwFrameFormats;
48 class SwRegionRects;
49 class SwTextNode;
50 namespace sw { struct Extent; }
51 namespace basegfx::utils { class B2DClipState; }
52 
53 #define FAR_AWAY (SAL_MAX_INT32 - 20000)  // initial position of a Fly
54 constexpr tools::Long BROWSE_HEIGHT = 56700 * 10; // 10 Meters
55 #define GRFNUM_NO 0
56 #define GRFNUM_YES 1
57 #define GRFNUM_REPLACE 2
58 
59 void AppendObjs( const SwFrameFormats *pTable, sal_uLong nIndex,
60                        SwFrame *pFrame, SwPageFrame *pPage, SwDoc* doc );
61 
62 void AppendObjsOfNode(SwFrameFormats const* pTable, sal_uLong nIndex,
63         SwFrame * pFrame, SwPageFrame * pPage, SwDoc * pDoc,
64         std::vector<sw::Extent>::const_iterator const* pIter,
65         std::vector<sw::Extent>::const_iterator const* pEnd,
66         SwTextNode const* pFirstNode, SwTextNode const* pLastNode);
67 
68 void RemoveHiddenObjsOfNode(SwTextNode const& rNode,
69         std::vector<sw::Extent>::const_iterator const* pIter,
70         std::vector<sw::Extent>::const_iterator const* pEnd,
71         SwTextNode const* pFirstNode, SwTextNode const* pLastNode);
72 
73 bool IsAnchoredObjShown(SwTextFrame const& rFrame, SwFormatAnchor const& rAnchor);
74 
75 void AppendAllObjs(const SwFrameFormats* pTable, const SwFrame* pSib);
76 
77 // draw background with brush or graphics
78 // The 6th parameter indicates that the method should consider background
79 // transparency, saved in the color of the brush item.
80 void DrawGraphic(
81     const SvxBrushItem *,
82     vcl::RenderContext *,
83     const SwRect &rOrg,
84     const SwRect &rOut,
85     const sal_uInt8 nGrfNum = GRFNUM_NO,
86     const bool bConsiderBackgroundTransparency = false );
87 bool DrawFillAttributes(
88     const drawinglayer::attribute::SdrAllFillAttributesHelperPtr& rFillAttributes,
89     const SwRect& rOriginalLayoutRect,
90     const SwRegionRects& rPaintRegion,
91     const basegfx::utils::B2DClipState& rClipState,
92     vcl::RenderContext& rOut);
93 
94 // RotGrfFlyFrame: Adapted to rotation
95 void paintGraphicUsingPrimitivesHelper(
96     vcl::RenderContext & rOutputDevice,
97     GraphicObject const& rGraphicObj,
98     GraphicAttr const& rGraphicAttr,
99     const basegfx::B2DHomMatrix& rGraphicTransform,
100     const OUString& rName,
101     const OUString& rTitle,
102     const OUString& rDescription);
103 
104 // MM02 new VOC and primitive-based version
105 void paintGraphicUsingPrimitivesHelper(
106     vcl::RenderContext & rOutputDevice,
107     drawinglayer::primitive2d::Primitive2DContainer& rContent,
108     const basegfx::B2DHomMatrix& rGraphicTransform,
109     const OUString& rName,
110     const OUString& rTitle,
111     const OUString& rDescription);
112 
113 // method to align rectangle.
114 // Created declaration here to avoid <extern> declarations
115 void SwAlignRect( SwRect &rRect, const SwViewShell *pSh, const vcl::RenderContext* pRenderContext );
116 
117 // method to align graphic rectangle
118 // Created declaration here to avoid <extern> declarations
119 void SwAlignGrfRect( SwRect *pGrfRect, const vcl::RenderContext &rOut );
120 
121 /**
122  * Paint border around a run of characters using frame painting code.
123  *
124  * @param[in]   rFont            font object of actual text, which specify the border
125  * @param[in]   rPaintArea       rectangle area in which line portion takes place
126  * @param[in]   bVerticalLayout  corresponding text frame verticality
127  * @param[in]   bVerticalLayoutLRBT corresponding text frame verticality (LRBT subset)
128  * @param[in]   bJoinWithPrev    leave border with which actual border joins to the previous portion
129  * @param[in]   bJoinWithNext    leave border with which actual border joins to the next portion
130 **/
131 void PaintCharacterBorder(const SwFont& rFont, const SwRect& rPaintArea, const bool bVerticalLayout,
132                           const bool bVerticalLayoutLRBT, const bool bJoinWithPrev,
133                           const bool bJoinWithNext);
134 
135 // get Fly, if no List is given use the current shell
136 // Implementation in feshview.cxx
137 SwFlyFrame *GetFlyFromMarked( const SdrMarkList *pLst, SwViewShell *pSh );
138 
139 SwFrame *SaveContent( SwLayoutFrame *pLay, SwFrame *pStart = nullptr );
140 void RestoreContent( SwFrame *pSav, SwLayoutFrame *pParent, SwFrame *pSibling );
141 
142 // Get ContentNodes, create ContentFrames, and add them to LayFrame.
143 void InsertCnt_( SwLayoutFrame *pLay, SwDoc *pDoc, sal_uLong nIndex,
144                  bool bPages = false, sal_uLong nEndIndex = 0,
145                  SwFrame *pPrv = nullptr, sw::FrameMode eMode = sw::FrameMode::New);
146 
147 // Creation of frames for a specific section (uses InsertCnt_)
148 void MakeFrames( SwDoc *pDoc, const SwNodeIndex &rSttIdx,
149                             const SwNodeIndex &rEndIdx );
150 
151 extern bool bObjsDirect;
152 
153 // prevent creation of Flys in InsertCnt_, e.g. for table headlines
154 extern bool bDontCreateObjects;
155 
156 // for FlyCnts, see SwFlyAtContentFrame::MakeAll()
157 extern bool bSetCompletePaintOnInvalidate;
158 
159 // for table settings via keyboard
160 SwTwips CalcRowRstHeight( SwLayoutFrame *pRow );
161 tools::Long CalcHeightWithFlys( const SwFrame *pFrame );
162 
163 namespace sw {
164 
165 bool IsRightPageByNumber(SwRootFrame const& rLayout, sal_uInt16 nPageNum);
166 
167 } // namespace sw
168 
169 SwPageFrame *InsertNewPage( SwPageDesc &rDesc, SwFrame *pUpper,
170                           bool isRightPage, bool bFirst, bool bInsertEmpty, bool bFootnote,
171                           SwFrame *pSibling, bool bVeryFirstPage = false );
172 
173 // connect Flys with page
174 void RegistFlys( SwPageFrame*, const SwLayoutFrame* );
175 
176 // notification of Fly's background if needed
177 void Notify( SwFlyFrame *pFly, SwPageFrame *pOld, const SwRect &rOld,
178              const SwRect* pOldRect = nullptr );
179 
180 void Notify_Background( const SdrObject* pObj,
181                         SwPageFrame* pPage,
182                         const SwRect& rRect,
183                         const PrepareHint eHint,
184                         const bool bInva );
185 
186 const SwFrame* GetVirtualUpper( const SwFrame* pFrame, const Point& rPos );
187 
188 bool Is_Lower_Of( const SwFrame *pCurrFrame, const SdrObject* pObj );
189 
190 // FIXME: EasyHack (refactoring): rename method and parameter name in all files
191 const SwFrame *FindContext( const SwFrame *pFrame, SwFrameType nAdditionalContextTyp );
192 
193 bool IsFrameInSameContext( const SwFrame *pInnerFrame, const SwFrame *pFrame );
194 
195 const SwFrame * FindPage( const SwRect &rRect, const SwFrame *pPage );
196 
197 /** @see SwContentNode::getLayoutFrame()
198     @param pPos
199       Document model position; for a text frame, the returned frame will be
200       one containing this position.
201     @param pViewPosAndCalcFrame
202       First is a point in the document view; the returned frame will be the one
203       with the minimal distance to this point.  To get the first frame in the
204       document, pass in a default-initialized Point with coordinates 0,0.
205       Second indicates whether the frames should be formatted before retrieving
206       their position for the test; this cannot be done by every caller so use
207       with care!
208  */
209 SwFrame* GetFrameOfModify( const SwRootFrame* pLayout,
210                        sw::BroadcastingModify const&,
211                        SwFrameType const nFrameType,
212                        const SwPosition *pPos = nullptr,
213                        std::pair<Point, bool> const* pViewPosAndCalcFrame = nullptr);
214 
215 // Should extra data (redline stroke, line numbers) be painted?
216 bool IsExtraData( const SwDoc *pDoc );
217 
218 // #i11760# - method declaration <CalcContent(..)>
219 void CalcContent( SwLayoutFrame *pLay, bool bNoColl = false );
220 
221 // Notify classes memorize the current sizes in their constructor and do
222 // the necessary notifications in their destructor if needed
223 class SwFrameNotify
224 {
225 protected:
226     SwFrame *mpFrame;
227     const SwRect maFrame;
228     const SwRect maPrt;
229     SwTwips mnFlyAnchorOfst;
230     SwTwips mnFlyAnchorOfstNoWrap;
231     bool     mbHadFollow;
232     bool     mbInvaKeep;
233     bool     mbValidSize;
234 
235 public:
236     SwFrameNotify( SwFrame *pFrame );
237     ~SwFrameNotify() COVERITY_NOEXCEPT_FALSE;
238 
239     const SwRect &getFrameArea() const { return maFrame; }
240     void SetInvaKeep() { mbInvaKeep = true; }
241 };
242 
243 class SwLayNotify : public SwFrameNotify
244 {
245     bool m_bLowersComplete;
246 
247 public:
248     SwLayNotify( SwLayoutFrame *pLayFrame );
249     ~SwLayNotify();
250 
251     void SetLowersComplete( bool b ) { m_bLowersComplete = b; }
252     bool IsLowersComplete() const    { return m_bLowersComplete; }
253 };
254 
255 class SwFlyNotify : public SwLayNotify
256 {
257     SwPageFrame *pOldPage;
258     const SwRect aFrameAndSpace;
259 
260 public:
261     SwFlyNotify( SwFlyFrame *pFlyFrame );
262     ~SwFlyNotify();
263 };
264 
265 class SwContentNotify : public SwFrameNotify
266 {
267 private:
268     // #i11859#
269     bool    mbChkHeightOfLastLine;
270     SwTwips mnHeightOfLastLine;
271 
272     // #i25029#
273     bool        mbInvalidatePrevPrtArea;
274     bool        mbBordersJoinedWithPrev;
275 
276 public:
277     SwContentNotify( SwContentFrame *pContentFrame );
278     ~SwContentNotify();
279 
280     // #i25029#
281     void SetInvalidatePrevPrtArea()
282     {
283         mbInvalidatePrevPrtArea = true;
284     }
285 
286     void SetBordersJoinedWithPrev()
287     {
288         mbBordersJoinedWithPrev = true;
289     }
290 };
291 
292 // SwBorderAttrs encapsulates the calculation for margin attributes including
293 // border. The whole class is cached.
294 
295 // WARNING! If more attributes should be cached also adjust the method
296 //          Modify::Modify!
297 class SwBorderAttrs : public SwCacheObj
298 {
299     const SwAttrSet      &m_rAttrSet;
300     const SvxULSpaceItem &m_rUL;
301     // #i96772#
302     std::shared_ptr<SvxLRSpaceItem> m_rLR;
303     const SvxBoxItem     &m_rBox;
304     const SvxShadowItem  &m_rShadow;
305     const Size            m_aFrameSize;
306 
307     // the following bool values set the cached values to INVALID - until they
308     // are calculated for the first time
309     bool m_bTopLine     : 1;
310     bool m_bBottomLine  : 1;
311     bool m_bLeftLine    : 1;
312     bool m_bRightLine   : 1;
313     bool m_bTop         : 1;
314     bool m_bBottom      : 1;
315     bool m_bLine        : 1;
316     bool m_bLineSpacing : 1;
317 
318     bool m_bIsLine      : 1; // border on at least one side?
319 
320     bool m_bCacheGetLine        : 1; // cache GetTopLine(), GetBottomLine()?
321     bool m_bCachedGetTopLine    : 1; // is GetTopLine() cached?
322     bool m_bCachedGetBottomLine : 1; // is GetBottomLine() cached?
323     // Booleans indicate that <m_bJoinedWithPrev> and <m_bJoinedWithNext> are
324     // cached and valid.
325     // Caching depends on value of <m_bCacheGetLine>.
326     mutable bool m_bCachedJoinedWithPrev : 1;
327     mutable bool m_bCachedJoinedWithNext : 1;
328     // Booleans indicate that borders are joined with previous/next frame.
329     bool m_bJoinedWithPrev :1;
330     bool m_bJoinedWithNext :1;
331 
332     // The cached values (un-defined until calculated for the first time)
333     sal_uInt16 m_nTopLine,
334            m_nBottomLine,
335            m_nLeftLine,
336            m_nRightLine,
337            m_nTop,
338            m_nBottom,
339            m_nGetTopLine,
340            m_nGetBottomLine,
341            m_nLineSpacing;
342 
343     // only calculate lines and shadow
344     void CalcTopLine_();
345     void CalcBottomLine_();
346     void CalcLeftLine_();
347     void CalcRightLine_();
348 
349     // lines + shadow + margin
350     void CalcTop_();
351     void CalcBottom_();
352 
353     void IsLine_();
354 
355     // #i25029# - If <_pPrevFrame> is set, its value is taken for testing, if
356     // borders/shadow have to be joined with previous frame.
357     void GetTopLine_   ( const SwFrame& _rFrame,
358                          const SwFrame* _pPrevFrame );
359     void GetBottomLine_( const SwFrame& _rFrame );
360 
361     // calculate cached values <m_bJoinedWithPrev> and <m_bJoinedWithNext>
362     // #i25029# - If <_pPrevFrame> is set, its value is taken for testing, if
363     // borders/shadow have to be joined with previous frame.
364     void CalcJoinedWithPrev( const SwFrame& _rFrame,
365                               const SwFrame* _pPrevFrame );
366     void CalcJoinedWithNext( const SwFrame& _rFrame );
367 
368     // internal helper method for CalcJoinedWithPrev and CalcJoinedWithNext
369     bool JoinWithCmp( const SwFrame& _rCallerFrame,
370                        const SwFrame& _rCmpFrame ) const;
371 
372     // Are the left and right line and the LRSpace equal?
373     bool CmpLeftRight( const SwBorderAttrs &rCmpAttrs,
374                        const SwFrame *pCaller,
375                        const SwFrame *pCmp ) const;
376 
377     // tdf#125300 line spacing before cell border
378     void CalcLineSpacing_();
379 
380 public:
381     SwBorderAttrs( const sw::BorderCacheOwner* pOwner, const SwFrame *pConstructor );
382     virtual ~SwBorderAttrs() override;
383 
384     const SwAttrSet      &GetAttrSet() const { return m_rAttrSet;  }
385     const SvxULSpaceItem &GetULSpace() const { return m_rUL;       }
386     const SvxBoxItem     &GetBox()     const { return m_rBox;      }
387     const SvxShadowItem  &GetShadow()  const { return m_rShadow;   }
388 
389     inline sal_uInt16 CalcTopLine() const;
390     inline sal_uInt16 CalcBottomLine() const;
391     inline sal_uInt16 CalcLeftLine() const;
392     inline sal_uInt16 CalcRightLine() const;
393     inline sal_uInt16 CalcTop() const;
394     inline sal_uInt16 CalcBottom() const;
395     inline sal_uInt16 CalcLineSpacing() const;
396            tools::Long CalcLeft( const SwFrame *pCaller ) const;
397            tools::Long CalcRight( const SwFrame *pCaller ) const;
398 
399     inline bool IsLine() const;
400 
401     const Size &GetSize()     const { return m_aFrameSize; }
402 
403     // Should upper (or lower) border be evaluated for this frame?
404     // #i25029# - If <_pPrevFrame> is set, its value is taken for testing, if
405     // borders/shadow have to be joined with previous frame.
406     inline sal_uInt16 GetTopLine   ( const SwFrame& _rFrame,
407                                  const SwFrame* _pPrevFrame = nullptr ) const;
408     inline sal_uInt16 GetBottomLine( const SwFrame& _rFrame ) const;
409     inline void   SetGetCacheLine( bool bNew ) const;
410 
411     // Accessors for cached values <m_bJoinedWithPrev> and <m_bJoinedWithNext>
412     // #i25029# - If <_pPrevFrame> is set, its value is taken for testing, if
413     // borders/shadow have to be joined with previous frame.
414     bool JoinedWithPrev( const SwFrame& _rFrame,
415                          const SwFrame* _pPrevFrame = nullptr ) const;
416     bool JoinedWithNext( const SwFrame& _rFrame ) const;
417 };
418 
419 class SwBorderAttrAccess final : public SwCacheAccess
420 {
421     const SwFrame *m_pConstructor;      //opt: for passing on to SwBorderAttrs
422 
423     virtual SwCacheObj *NewObj() override;
424 
425 public:
426     SwBorderAttrAccess( SwCache &rCache, const SwFrame *pOwner );
427 
428     SwBorderAttrs *Get();
429 };
430 
431 // Iterator for draw objects of a page. The objects will be iterated sorted by
432 // their Z-order. Iterating is not cheap since for each operation the _whole_
433 // SortArray needs to be traversed.
434 class SwOrderIter
435 {
436     const SwPageFrame *m_pPage;
437     const SdrObject *m_pCurrent;
438 
439 public:
440     SwOrderIter( const SwPageFrame *pPage );
441 
442     void             Current( const SdrObject *pNew ) { m_pCurrent = pNew; }
443     const SdrObject *operator()() const { return m_pCurrent; }
444     void             Top();
445     const SdrObject *Bottom();
446     const SdrObject *Next();
447     void             Prev();
448 };
449 
450 class StackHack
451 {
452     static sal_uInt8 s_nCnt;
453     static bool s_bLocked;
454 
455 public:
456     StackHack()
457     {
458         if ( ++StackHack::s_nCnt > 50 )
459             StackHack::s_bLocked = true;
460     }
461     ~StackHack()
462     {
463         if ( --StackHack::s_nCnt < 5 )
464             StackHack::s_bLocked = false;
465     }
466 
467     static bool IsLocked()  { return StackHack::s_bLocked; }
468     static sal_uInt8 Count()        { return StackHack::s_nCnt; }
469 };
470 
471 // Should upper (or lower) border be evaluated for this frame?
472 // #i25029# - If <_pPrevFrame> is set, its value is taken for testing, if
473 // borders/shadow have to be joined with previous frame.
474 inline sal_uInt16 SwBorderAttrs::GetTopLine ( const SwFrame& _rFrame,
475                                           const SwFrame* _pPrevFrame ) const
476 {
477     if ( !m_bCachedGetTopLine || _pPrevFrame )
478     {
479         const_cast<SwBorderAttrs*>(this)->GetTopLine_( _rFrame, _pPrevFrame );
480     }
481     return m_nGetTopLine;
482 }
483 inline sal_uInt16 SwBorderAttrs::GetBottomLine( const SwFrame& _rFrame ) const
484 {
485     if ( !m_bCachedGetBottomLine )
486         const_cast<SwBorderAttrs*>(this)->GetBottomLine_( _rFrame );
487     return m_nGetBottomLine;
488 }
489 inline void SwBorderAttrs::SetGetCacheLine( bool bNew ) const
490 {
491     const_cast<SwBorderAttrs*>(this)->m_bCacheGetLine = bNew;
492     const_cast<SwBorderAttrs*>(this)->m_bCachedGetBottomLine =
493     const_cast<SwBorderAttrs*>(this)->m_bCachedGetTopLine = false;
494     // invalidate cache for values <m_bJoinedWithPrev> and <m_bJoinedWithNext>
495     m_bCachedJoinedWithPrev = false;
496     m_bCachedJoinedWithNext = false;
497 }
498 
499 inline sal_uInt16 SwBorderAttrs::CalcTopLine() const
500 {
501     if ( m_bTopLine )
502         const_cast<SwBorderAttrs*>(this)->CalcTopLine_();
503     return m_nTopLine;
504 }
505 inline sal_uInt16 SwBorderAttrs::CalcBottomLine() const
506 {
507     if ( m_bBottomLine )
508         const_cast<SwBorderAttrs*>(this)->CalcBottomLine_();
509     return m_nBottomLine;
510 }
511 inline sal_uInt16 SwBorderAttrs::CalcLeftLine() const
512 {
513     if ( m_bLeftLine )
514         const_cast<SwBorderAttrs*>(this)->CalcLeftLine_();
515     return m_nLeftLine;
516 }
517 inline sal_uInt16 SwBorderAttrs::CalcRightLine() const
518 {
519     if ( m_bRightLine )
520         const_cast<SwBorderAttrs*>(this)->CalcRightLine_();
521     return m_nRightLine;
522 }
523 inline sal_uInt16 SwBorderAttrs::CalcTop() const
524 {
525     if ( m_bTop )
526         const_cast<SwBorderAttrs*>(this)->CalcTop_();
527     return m_nTop;
528 }
529 inline sal_uInt16 SwBorderAttrs::CalcBottom() const
530 {
531     if ( m_bBottom )
532         const_cast<SwBorderAttrs*>(this)->CalcBottom_();
533     return m_nBottom;
534 }
535 inline sal_uInt16 SwBorderAttrs::CalcLineSpacing() const
536 {
537     if ( m_bLineSpacing )
538         const_cast<SwBorderAttrs*>(this)->CalcLineSpacing_();
539     return m_nLineSpacing;
540 }
541 inline bool SwBorderAttrs::IsLine() const
542 {
543     if ( m_bLine )
544         const_cast<SwBorderAttrs*>(this)->IsLine_();
545     return m_bIsLine;
546 }
547 
548 /** method to determine the spacing values of a frame
549 
550     #i28701#
551     Values only provided for flow frames (table, section or text frames)
552     Note: line spacing value is only determined for text frames
553     #i102458#
554     Add output parameter <obIsLineSpacingProportional>
555 
556     @param rFrame
557     input parameter - frame, for which the spacing values are determined.
558 
559     @param onPrevLowerSpacing
560     output parameter - lower spacing of the frame in SwTwips
561 
562     @param onPrevLineSpacing
563     output parameter - line spacing of the frame in SwTwips
564 
565     @param obIsLineSpacingProportional
566 
567     @param bIdenticalStyles true if the styles of the actual and the next paragraphs (text-frames) are the same
568 */
569 void GetSpacingValuesOfFrame( const SwFrame& rFrame,
570                             SwTwips& onLowerSpacing,
571                             SwTwips& onLineSpacing,
572                             bool& obIsLineSpacingProportional,
573                             bool bIdenticalStyles );
574 
575 /** method to get the content of the table cell
576 
577     Content from any nested tables will be omitted.
578     Note: line spacing value is only determined for text frames
579 
580     @param rCell_
581     input parameter - the cell which should be searched for content.
582 
583     return
584         pointer to the found content frame or 0
585 */
586 
587 const SwContentFrame* GetCellContent( const SwLayoutFrame& rCell_ );
588 
589 /** helper class to check if a frame has been deleted during an operation
590  *  WARNING! This should only be used as a last and desperate means to make the
591  *  code robust.
592  */
593 
594 class SwDeletionChecker
595 {
596 private:
597     const SwFrame* mpFrame;
598     const sw::BroadcastingModify* mpRegIn;
599 
600 public:
601     SwDeletionChecker(const SwFrame* pFrame);
602 
603     /**
604      *  return
605      *    true if mpFrame != 0 and mpFrame is not client of pRegIn
606      *    false otherwise
607      */
608     bool HasBeenDeleted() const;
609 };
610 
611 #endif
612 
613 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
614