LibreOffice Module sw (master)  1
trvlfrm.cxx
Go to the documentation of this file.
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 <hints.hxx>
21 #include <comphelper/flagguard.hxx>
22 #include <tools/line.hxx>
23 #include <editeng/opaqitem.hxx>
24 #include <editeng/protitem.hxx>
25 #include <vcl/settings.hxx>
26 #include <fmtpdsc.hxx>
27 #include <fmtsrnd.hxx>
28 #include <pagedesc.hxx>
29 #include <pagefrm.hxx>
30 #include <rootfrm.hxx>
31 #include <ftnfrm.hxx>
32 #include <flyfrm.hxx>
33 #include <tabfrm.hxx>
34 #include <rowfrm.hxx>
35 #include <cellfrm.hxx>
36 #include <txtfrm.hxx>
37 #include <notxtfrm.hxx>
38 #include <viewopt.hxx>
40 #include <viscrs.hxx>
41 #include <dflyobj.hxx>
42 #include <crstate.hxx>
43 #include <dcontact.hxx>
44 #include <sortedobjs.hxx>
45 #include <txatbase.hxx>
46 #include <fmtfld.hxx>
47 #include <fldbas.hxx>
48 #include <frmatr.hxx>
49 #include <frmtool.hxx>
50 #include <ndtxt.hxx>
51 #include <undobj.hxx>
52 
53 #include <swselectionlist.hxx>
54 #include <comphelper/lok.hxx>
55 
56 namespace {
57  bool lcl_GetCursorOfst_Objects( const SwPageFrame* pPageFrame, bool bSearchBackground,
58  SwPosition *pPos, Point const & rPoint, SwCursorMoveState* pCMS )
59  {
60  bool bRet = false;
61  Point aPoint( rPoint );
62  SwOrderIter aIter( pPageFrame );
63  aIter.Top();
64  while ( aIter() )
65  {
66  const SwVirtFlyDrawObj* pObj =
67  static_cast<const SwVirtFlyDrawObj*>(aIter());
68  const SwAnchoredObject* pAnchoredObj = GetUserCall( aIter() )->GetAnchoredObj( aIter() );
69  const SwFormatSurround& rSurround = pAnchoredObj->GetFrameFormat().GetSurround();
70  const SvxOpaqueItem& rOpaque = pAnchoredObj->GetFrameFormat().GetOpaque();
71  bool bInBackground = ( rSurround.GetSurround() == css::text::WrapTextMode_THROUGH ) && !rOpaque.GetValue();
72 
73  bool bBackgroundMatches = bInBackground == bSearchBackground;
74 
75  const SwFlyFrame* pFly = pObj ? pObj->GetFlyFrame() : nullptr;
76  if ( pFly && bBackgroundMatches &&
77  ( ( pCMS && pCMS->m_bSetInReadOnly ) ||
78  !pFly->IsProtected() ) &&
79  pFly->GetCursorOfst( pPos, aPoint, pCMS ) )
80  {
81  bRet = true;
82  break;
83  }
84 
85  if ( pCMS && pCMS->m_bStop )
86  return false;
87  aIter.Prev();
88  }
89  return bRet;
90  }
91 
92  double lcl_getDistance( const SwRect& rRect, const Point& rPoint )
93  {
94  double nDist = 0.0;
95 
96  // If the point is inside the rectangle, then distance is 0
97  // Otherwise, compute the distance to the center of the rectangle.
98  if ( !rRect.IsInside( rPoint ) )
99  {
100  tools::Line aLine( rPoint, rRect.Center( ) );
101  nDist = aLine.GetLength( );
102  }
103 
104  return nDist;
105  }
106 }
107 
108 namespace {
109 
110 //For SwFlyFrame::GetCursorOfst
111 class SwCursorOszControl
112 {
113 public:
114  // So the compiler can initialize the class already. No DTOR and member
115  // as public members
116  const SwFlyFrame *pEntry;
117  const SwFlyFrame *pStack1;
118  const SwFlyFrame *pStack2;
119 
120  bool ChkOsz( const SwFlyFrame *pFly )
121  {
122  bool bRet = true;
123  if ( pFly != pStack1 && pFly != pStack2 )
124  {
125  pStack1 = pStack2;
126  pStack2 = pFly;
127  bRet = false;
128  }
129  return bRet;
130  }
131 
132  void Entry( const SwFlyFrame *pFly )
133  {
134  if ( !pEntry )
135  pEntry = pStack1 = pFly;
136  }
137 
138  void Exit( const SwFlyFrame *pFly )
139  {
140  if ( pFly == pEntry )
141  pEntry = pStack1 = pStack2 = nullptr;
142  }
143 };
144 
145 }
146 
147 static SwCursorOszControl g_OszCtrl = { nullptr, nullptr, nullptr };
148 
151  SwCursorMoveState* pCMS, bool ) const
152 {
153  vcl::RenderContext* pRenderContext = getRootFrame()->GetCurrShell()->GetOut();
154  bool bRet = false;
155  const SwFrame *pFrame = Lower();
156  while ( !bRet && pFrame )
157  {
158  pFrame->Calc(pRenderContext);
159 
160  // #i43742# New function
161  const bool bContentCheck = pFrame->IsTextFrame() && pCMS && pCMS->m_bContentCheck;
162  const SwRect aPaintRect( bContentCheck ?
163  pFrame->UnionFrame() :
164  pFrame->GetPaintArea() );
165 
166  if ( aPaintRect.IsInside( rPoint ) &&
167  ( bContentCheck || pFrame->GetCursorOfst( pPos, rPoint, pCMS ) ) )
168  bRet = true;
169  else
170  pFrame = pFrame->GetNext();
171  if ( pCMS && pCMS->m_bStop )
172  return false;
173  }
174  return bRet;
175 }
176 
180  SwCursorMoveState* pCMS, bool bTestBackground ) const
181 {
182  Point aPoint( rPoint );
183 
184  // check, if we have to adjust the point
185  if ( !getFrameArea().IsInside( aPoint ) )
186  {
187  aPoint.setX( std::max( aPoint.X(), getFrameArea().Left() ) );
188  aPoint.setX( std::min( aPoint.X(), getFrameArea().Right() ) );
189  aPoint.setY( std::max( aPoint.Y(), getFrameArea().Top() ) );
190  aPoint.setY( std::min( aPoint.Y(), getFrameArea().Bottom() ) );
191  }
192 
193  bool bRet = false;
194  //Could it be a free flying one?
195  //If his content should be protected, we can't set the Cursor in it, thus
196  //all changes should be impossible.
197  if ( GetSortedObjs() )
198  {
199  bRet = lcl_GetCursorOfst_Objects( this, false, pPos, rPoint, pCMS );
200  }
201 
202  if ( !bRet )
203  {
204  SwPosition aBackPos( *pPos );
205  SwPosition aTextPos( *pPos );
206 
207  //We fix the StartPoint if no Content below the page 'answers' and then
208  //start all over again one page before the current one.
209  //However we can't use Flys in such a case.
210  if (!SwLayoutFrame::GetCursorOfst(&aTextPos, aPoint, pCMS))
211  {
212  if ( pCMS && (pCMS->m_bStop || pCMS->m_bExactOnly) )
213  {
214  pCMS->m_bStop = true;
215  return false;
216  }
217 
218  const SwContentFrame *pCnt = GetContentPos( aPoint, false, false, pCMS, false );
219  // GetContentPos may have modified pCMS
220  if ( pCMS && pCMS->m_bStop )
221  return false;
222 
223  bool bTextRet = false;
224 
225  OSL_ENSURE( pCnt, "Cursor is gone to a Black hole" );
226  if( pCMS && pCMS->m_pFill && pCnt->IsTextFrame() )
227  bTextRet = pCnt->GetCursorOfst( &aTextPos, rPoint, pCMS );
228  else
229  bTextRet = pCnt->GetCursorOfst( &aTextPos, aPoint, pCMS );
230 
231  if ( !bTextRet )
232  {
233  // Set point to pCnt, delete mark
234  // this may happen, if pCnt is hidden
235  if (pCnt->IsTextFrame())
236  {
237  aTextPos = static_cast<SwTextFrame const*>(pCnt)->MapViewToModelPos(TextFrameIndex(0));
238  }
239  else
240  {
241  assert(pCnt->IsNoTextFrame());
242  aTextPos = SwPosition( *static_cast<SwNoTextFrame const*>(pCnt)->GetNode() );
243  }
244  }
245  }
246 
247  SwContentNode* pContentNode = aTextPos.nNode.GetNode().GetContentNode();
248  bool bConsiderBackground = true;
249  // If the text position is a clickable field, then that should have priority.
250  if (pContentNode && pContentNode->IsTextNode())
251  {
252  SwTextNode* pTextNd = pContentNode->GetTextNode();
253  SwTextAttr* pTextAttr = pTextNd->GetTextAttrForCharAt(aTextPos.nContent.GetIndex(), RES_TXTATR_FIELD);
254  if (pTextAttr)
255  {
256  const SwField* pField = pTextAttr->GetFormatField().GetField();
257  if (pField->IsClickable())
258  bConsiderBackground = false;
259  }
260  }
261 
262  bool bBackRet = false;
263  // Check objects in the background if nothing else matched
264  if ( GetSortedObjs() )
265  {
266  bBackRet = lcl_GetCursorOfst_Objects( this, true, &aBackPos, rPoint, pCMS );
267  }
268 
269  if (bConsiderBackground && bTestBackground && bBackRet)
270  {
271  (*pPos) = aBackPos;
272  }
273  else if (!bBackRet)
274  {
275  (*pPos) = aTextPos;
276  }
277  else // bBackRet && !(bConsiderBackground && bTestBackground)
278  {
279  /* In order to provide a selection as accurate as possible when we have both
280  * text and background object, then we compute the distance between both
281  * would-be positions and the click point. The shortest distance wins.
282  */
283  double nTextDistance = 0;
284  bool bValidTextDistance = false;
285  if (pContentNode)
286  {
287  SwContentFrame* pTextFrame = pContentNode->getLayoutFrame( getRootFrame( ) );
288 
289  // try this again but prefer the "previous" position
290  SwCursorMoveState aMoveState;
291  SwCursorMoveState *const pState(pCMS ? pCMS : &aMoveState);
293  pState->m_bPosMatchesBounds, true);
294  SwPosition prevTextPos(*pPos);
295  SwLayoutFrame::GetCursorOfst(&prevTextPos, aPoint, pState);
296 
297  SwRect aTextRect;
298  pTextFrame->GetCharRect(aTextRect, prevTextPos);
299 
300  if (prevTextPos.nContent < pContentNode->Len())
301  {
302  // aRextRect is just a line on the left edge of the
303  // previous character; to get a better measure from
304  // lcl_getDistance, extend that to a rectangle over
305  // the entire character.
306  SwPosition const nextTextPos(prevTextPos.nNode,
307  SwIndex(prevTextPos.nContent, +1));
308  SwRect nextTextRect;
309  pTextFrame->GetCharRect(nextTextRect, nextTextPos);
310  SwRectFnSet aRectFnSet(pTextFrame);
311  if (aRectFnSet.GetTop(aTextRect) ==
312  aRectFnSet.GetTop(nextTextRect)) // same line?
313  {
314  // need to handle mixed RTL/LTR portions somehow
315  if (aRectFnSet.GetLeft(aTextRect) <
316  aRectFnSet.GetLeft(nextTextRect))
317  {
318  aRectFnSet.SetRight( aTextRect,
319  aRectFnSet.GetLeft(nextTextRect));
320  }
321  else // RTL
322  {
323  aRectFnSet.SetLeft( aTextRect,
324  aRectFnSet.GetLeft(nextTextRect));
325  }
326  }
327  }
328 
329  nTextDistance = lcl_getDistance(aTextRect, rPoint);
330  bValidTextDistance = true;
331  }
332 
333  double nBackDistance = 0;
334  bool bValidBackDistance = false;
335  SwContentNode* pBackNd = aBackPos.nNode.GetNode( ).GetContentNode( );
336  if ( pBackNd && bConsiderBackground)
337  {
338  // FIXME There are still cases were we don't have the proper node here.
339  SwContentFrame* pBackFrame = pBackNd->getLayoutFrame( getRootFrame( ) );
340  SwRect rBackRect;
341  if (pBackFrame)
342  {
343  pBackFrame->GetCharRect( rBackRect, aBackPos );
344 
345  nBackDistance = lcl_getDistance( rBackRect, rPoint );
346  bValidBackDistance = true;
347  }
348  }
349 
350  if ( bValidTextDistance && bValidBackDistance && basegfx::fTools::more( nTextDistance, nBackDistance ) )
351  {
352  (*pPos) = aBackPos;
353  }
354  else
355  {
356  (*pPos) = aTextPos;
357  }
358  }
359  }
360 
361  rPoint = aPoint;
362  return true;
363 }
364 
365 bool SwLayoutFrame::FillSelection( SwSelectionList& rList, const SwRect& rRect ) const
366 {
367  if( rRect.IsOver(GetPaintArea()) )
368  {
369  const SwFrame* pFrame = Lower();
370  while( pFrame )
371  {
372  pFrame->FillSelection( rList, rRect );
373  pFrame = pFrame->GetNext();
374  }
375  }
376  return false;
377 }
378 
379 bool SwPageFrame::FillSelection( SwSelectionList& rList, const SwRect& rRect ) const
380 {
381  bool bRet = false;
382  if( rRect.IsOver(GetPaintArea()) )
383  {
384  bRet = SwLayoutFrame::FillSelection( rList, rRect );
385  if( GetSortedObjs() )
386  {
387  const SwSortedObjs &rObjs = *GetSortedObjs();
388  for (SwAnchoredObject* pAnchoredObj : rObjs)
389  {
390  if( dynamic_cast< const SwFlyFrame *>( pAnchoredObj ) == nullptr )
391  continue;
392  const SwFlyFrame* pFly = static_cast<const SwFlyFrame*>(pAnchoredObj);
393  if( pFly->FillSelection( rList, rRect ) )
394  bRet = true;
395  }
396  }
397  }
398  return bRet;
399 }
400 
401 bool SwRootFrame::FillSelection( SwSelectionList& aSelList, const SwRect& rRect) const
402 {
403  const SwFrame *pPage = Lower();
404  const long nBottom = rRect.Bottom();
405  while( pPage )
406  {
407  if( pPage->getFrameArea().Top() < nBottom )
408  {
409  if( pPage->getFrameArea().Bottom() > rRect.Top() )
410  pPage->FillSelection( aSelList, rRect );
411  pPage = pPage->GetNext();
412  }
413  else
414  pPage = nullptr;
415  }
416  return !aSelList.isEmpty();
417 }
418 
424  SwCursorMoveState* pCMS, bool bTestBackground ) const
425 {
426  const bool bOldAction = IsCallbackActionEnabled();
427  const_cast<SwRootFrame*>(this)->SetCallbackActionEnabled( false );
428  OSL_ENSURE( (Lower() && Lower()->IsPageFrame()), "No PageFrame found." );
429  if( pCMS && pCMS->m_pFill )
430  pCMS->m_bFillRet = false;
431  Point aOldPoint = rPoint;
432 
433  // search for page containing rPoint. The borders around the pages are considered
434  const SwPageFrame* pPage = GetPageAtPos( rPoint, nullptr, true );
435 
436  // #i95626#
437  // special handling for <rPoint> beyond root frames area
438  if ( !pPage &&
439  rPoint.X() > getFrameArea().Right() &&
440  rPoint.Y() > getFrameArea().Bottom() )
441  {
442  pPage = dynamic_cast<const SwPageFrame*>(Lower());
443  while ( pPage && pPage->GetNext() )
444  {
445  pPage = dynamic_cast<const SwPageFrame*>(pPage->GetNext());
446  }
447  }
448  if ( pPage )
449  {
450  pPage->SwPageFrame::GetCursorOfst( pPos, rPoint, pCMS, bTestBackground );
451  }
452 
453  const_cast<SwRootFrame*>(this)->SetCallbackActionEnabled( bOldAction );
454  if( pCMS )
455  {
456  if( pCMS->m_bStop )
457  return false;
458  if( pCMS->m_pFill )
459  return pCMS->m_bFillRet;
460  }
461  return aOldPoint == rPoint;
462 }
463 
471  SwCursorMoveState* pCMS, bool ) const
472 {
473  vcl::RenderContext* pRenderContext = getRootFrame()->GetCurrShell()->GetOut();
474  // cell frame does not necessarily have a lower (split table cell)
475  if ( !Lower() )
476  return false;
477 
478  if ( !(pCMS && pCMS->m_bSetInReadOnly) &&
479  GetFormat()->GetProtect().IsContentProtected() )
480  return false;
481 
482  if ( pCMS && pCMS->m_eState == MV_TBLSEL )
483  {
484  const SwTabFrame *pTab = FindTabFrame();
485  if ( pTab->IsFollow() && pTab->IsInHeadline( *this ) )
486  {
487  pCMS->m_bStop = true;
488  return false;
489  }
490  }
491 
492  if ( Lower() )
493  {
494  if ( Lower()->IsLayoutFrame() )
495  return SwLayoutFrame::GetCursorOfst( pPos, rPoint, pCMS );
496  else
497  {
498  Calc(pRenderContext);
499  bool bRet = false;
500 
501  const SwFrame *pFrame = Lower();
502  while ( pFrame && !bRet )
503  {
504  pFrame->Calc(pRenderContext);
505  if ( pFrame->getFrameArea().IsInside( rPoint ) )
506  {
507  bRet = pFrame->GetCursorOfst( pPos, rPoint, pCMS );
508  if ( pCMS && pCMS->m_bStop )
509  return false;
510  }
511  pFrame = pFrame->GetNext();
512  }
513  if ( !bRet )
514  {
515  const bool bFill = pCMS && pCMS->m_pFill;
516  Point aPoint( rPoint );
517  const SwContentFrame *pCnt = GetContentPos( rPoint, true );
518  if( bFill && pCnt->IsTextFrame() )
519  {
520  rPoint = aPoint;
521  }
522  pCnt->GetCursorOfst( pPos, rPoint, pCMS );
523  }
524  return true;
525  }
526  }
527 
528  return false;
529 }
530 
531 //Problem: If two Flys have the same size and share the same position then
532 //they end inside each other.
533 //Because we recursively check if a Point doesn't randomly lie inside another
534 //fly which lies completely inside the current Fly we could trigger an endless
535 //loop with the mentioned situation above.
536 //Using the helper class SwCursorOszControl we prevent the recursion. During
537 //a recursion GetCursorOfst picks the one which lies on top.
539  SwCursorMoveState* pCMS, bool ) const
540 {
541  vcl::RenderContext* pRenderContext = getRootFrame()->GetCurrShell()->GetOut();
542  g_OszCtrl.Entry( this );
543 
544  //If the Points lies inside the Fly, we try hard to set the Cursor inside it.
545  //However if the Point sits inside a Fly which is completely located inside
546  //the current one, we call GetCursorOfst for it.
547  Calc(pRenderContext);
548  bool bInside = getFrameArea().IsInside( rPoint ) && Lower();
549  bool bRet = false;
550 
551  //If a Frame contains a graphic, but only text was requested, it basically
552  //won't accept the Cursor.
553  if ( bInside && pCMS && pCMS->m_eState == MV_SETONLYTEXT &&
554  (!Lower() || Lower()->IsNoTextFrame()) )
555  bInside = false;
556 
557  const SwPageFrame *pPage = FindPageFrame();
558  if ( bInside && pPage && pPage->GetSortedObjs() )
559  {
560  SwOrderIter aIter( pPage );
561  aIter.Top();
562  while ( aIter() && !bRet )
563  {
564  const SwVirtFlyDrawObj* pObj = static_cast<const SwVirtFlyDrawObj*>(aIter());
565  const SwFlyFrame* pFly = pObj ? pObj->GetFlyFrame() : nullptr;
566  if ( pFly && pFly->getFrameArea().IsInside( rPoint ) &&
567  getFrameArea().IsInside( pFly->getFrameArea() ) )
568  {
569  if (g_OszCtrl.ChkOsz(pFly))
570  break;
571  bRet = pFly->GetCursorOfst( pPos, rPoint, pCMS );
572  if ( bRet )
573  break;
574  if ( pCMS && pCMS->m_bStop )
575  return false;
576  }
577  aIter.Next();
578  }
579  }
580 
581  while ( bInside && !bRet )
582  {
583  const SwFrame *pFrame = Lower();
584  while ( pFrame && !bRet )
585  {
586  pFrame->Calc(pRenderContext);
587  if ( pFrame->getFrameArea().IsInside( rPoint ) )
588  {
589  bRet = pFrame->GetCursorOfst( pPos, rPoint, pCMS );
590  if ( pCMS && pCMS->m_bStop )
591  return false;
592  }
593  pFrame = pFrame->GetNext();
594  }
595  if ( !bRet )
596  {
597  const bool bFill = pCMS && pCMS->m_pFill;
598  Point aPoint( rPoint );
599  const SwContentFrame *pCnt = GetContentPos( rPoint, true, false, pCMS );
600  if ( pCMS && pCMS->m_bStop )
601  return false;
602  if( bFill && pCnt->IsTextFrame() )
603  {
604  rPoint = aPoint;
605  }
606  pCnt->GetCursorOfst( pPos, rPoint, pCMS );
607  bRet = true;
608  }
609  }
610  g_OszCtrl.Exit( this );
611  return bRet;
612 }
613 
616 {
617  if( &pPam->GetNode() != GetNode() )
618  return false;
619  const_cast<SwContentNode*>(GetNode())->
620  MakeStartIndex(&pPam->GetPoint()->nContent);
621  return true;
622 }
623 
624 bool SwNoTextFrame::RightMargin(SwPaM *pPam, bool) const
625 {
626  if( &pPam->GetNode() != GetNode() )
627  return false;
628  const_cast<SwContentNode*>(GetNode())->
629  MakeEndIndex(&pPam->GetPoint()->nContent);
630  return true;
631 }
632 
633 static const SwContentFrame *lcl_GetNxtCnt( const SwContentFrame* pCnt )
634 {
635  return pCnt->GetNextContentFrame();
636 }
637 
638 static const SwContentFrame *lcl_GetPrvCnt( const SwContentFrame* pCnt )
639 {
640  return pCnt->GetPrevContentFrame();
641 }
642 
643 typedef const SwContentFrame *(*GetNxtPrvCnt)( const SwContentFrame* );
644 
646 static bool lcl_IsInRepeatedHeadline( const SwFrame *pFrame,
647  const SwTabFrame** ppTFrame = nullptr )
648 {
649  const SwTabFrame *pTab = pFrame->FindTabFrame();
650  if( ppTFrame )
651  *ppTFrame = pTab;
652  return pTab && pTab->IsFollow() && pTab->IsInHeadline( *pFrame );
653 }
654 
656 //MA 1998-01-26: Chg also skip other protected areas
657 //FME: Skip follow flow cells
659  GetNxtPrvCnt fnNxtPrv,
660  bool bMissHeadline,
661  bool bInReadOnly,
662  bool bMissFollowFlowLine )
663 {
664  if ( pCnt && pCnt->IsInTab() )
665  {
666  bool bProtect = true;
667  while ( pCnt && bProtect )
668  {
669  const SwLayoutFrame *pCell = pCnt->GetUpper();
670  while ( pCell && !pCell->IsCellFrame() )
671  pCell = pCell->GetUpper();
672  if ( !pCell ||
673  ( ( bInReadOnly || !pCell->GetFormat()->GetProtect().IsContentProtected() ) &&
674  ( !bMissHeadline || !lcl_IsInRepeatedHeadline( pCell ) ) &&
675  ( !bMissFollowFlowLine || !pCell->IsInFollowFlowRow() ) &&
676  !pCell->IsCoveredCell() ) )
677  bProtect = false;
678  else
679  pCnt = (*fnNxtPrv)( pCnt );
680  }
681  }
682  else if ( !bInReadOnly )
683  while ( pCnt && pCnt->IsProtected() )
684  pCnt = (*fnNxtPrv)( pCnt );
685 
686  return pCnt;
687 }
688 
689 static bool lcl_UpDown( SwPaM *pPam, const SwContentFrame *pStart,
690  GetNxtPrvCnt fnNxtPrv, bool bInReadOnly )
691 {
692  OSL_ENSURE( FrameContainsNode(*pStart, pPam->GetNode().GetIndex()),
693  "lcl_UpDown doesn't work for others." );
694 
695  const SwContentFrame *pCnt = nullptr;
696 
697  //We have to cheat a little bit during a table selection: Go to the
698  //beginning of the cell while going up and go to the end of the cell while
699  //going down.
700  bool bTableSel = false;
701  if ( pStart->IsInTab() &&
702  pPam->GetNode().StartOfSectionNode() !=
703  pPam->GetNode( false ).StartOfSectionNode() )
704  {
705  bTableSel = true;
706  const SwLayoutFrame *pCell = pStart->GetUpper();
707  while ( !pCell->IsCellFrame() )
708  pCell = pCell->GetUpper();
709 
710  // Check, if cell has a Prev/Follow cell:
711  const bool bFwd = ( fnNxtPrv == lcl_GetNxtCnt );
712  const SwLayoutFrame* pTmpCell = bFwd ?
713  static_cast<const SwCellFrame*>(pCell)->GetFollowCell() :
714  static_cast<const SwCellFrame*>(pCell)->GetPreviousCell();
715 
716  const SwContentFrame* pTmpStart = pStart;
717  while ( pTmpCell && nullptr != ( pTmpStart = pTmpCell->ContainsContent() ) )
718  {
719  pCell = pTmpCell;
720  pTmpCell = bFwd ?
721  static_cast<const SwCellFrame*>(pCell)->GetFollowCell() :
722  static_cast<const SwCellFrame*>(pCell)->GetPreviousCell();
723  }
724  const SwContentFrame *pNxt = pCnt = pTmpStart;
725 
726  while ( pCell->IsAnLower( pNxt ) )
727  {
728  pCnt = pNxt;
729  pNxt = (*fnNxtPrv)( pNxt );
730  }
731  }
732 
733  pCnt = (*fnNxtPrv)( pCnt ? pCnt : pStart );
734  pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, true, bInReadOnly, bTableSel );
735 
736  const SwTabFrame *pStTab = pStart->FindTabFrame();
737  const SwTabFrame *pTable = nullptr;
738  const bool bTab = pStTab || (pCnt && pCnt->IsInTab());
739  bool bEnd = !bTab;
740 
741  const SwFrame* pVertRefFrame = pStart;
742  if ( bTableSel && pStTab )
743  pVertRefFrame = pStTab;
744  SwRectFnSet aRectFnSet(pVertRefFrame);
745 
746  SwTwips nX = 0;
747  if ( bTab )
748  {
749  // pStart or pCnt is inside a table. nX will be used for travelling:
750  SwRect aRect( pStart->getFrameArea() );
751  pStart->GetCharRect( aRect, *pPam->GetPoint() );
752  Point aCenter = aRect.Center();
753  nX = aRectFnSet.IsVert() ? aCenter.Y() : aCenter.X();
754 
755  pTable = pCnt ? pCnt->FindTabFrame() : nullptr;
756  if ( !pTable )
757  pTable = pStTab;
758 
759  if ( pStTab &&
760  !pStTab->GetUpper()->IsInTab() &&
761  !pTable->GetUpper()->IsInTab() )
762  {
763  const SwFrame *pCell = pStart->GetUpper();
764  while ( pCell && !pCell->IsCellFrame() )
765  pCell = pCell->GetUpper();
766  OSL_ENSURE( pCell, "could not find the cell" );
767  nX = aRectFnSet.XInc(aRectFnSet.GetLeft(pCell->getFrameArea()),
768  aRectFnSet.GetWidth(pCell->getFrameArea()) / 2);
769 
770  //The flow leads from one table to the next. The X-value needs to be
771  //corrected based on the middle of the starting cell by the amount
772  //of the offset of the tables.
773  if ( pStTab != pTable )
774  {
775  nX += aRectFnSet.GetLeft(pTable->getFrameArea()) -
776  aRectFnSet.GetLeft(pStTab->getFrameArea());
777  }
778  }
779 
780  // Restrict nX to the left and right borders of pTab:
781  // (is this really necessary?)
782  if (pTable && !pTable->GetUpper()->IsInTab())
783  {
784  const bool bRTL = pTable->IsRightToLeft();
785  const long nPrtLeft = bRTL ?
786  aRectFnSet.GetPrtRight(*pTable) :
787  aRectFnSet.GetPrtLeft(*pTable);
788  if (bRTL != (aRectFnSet.XDiff(nPrtLeft, nX) > 0))
789  nX = nPrtLeft;
790  else
791  {
792  const long nPrtRight = bRTL ?
793  aRectFnSet.GetPrtLeft(*pTable) :
794  aRectFnSet.GetPrtRight(*pTable);
795  if (bRTL != (aRectFnSet.XDiff(nX, nPrtRight) > 0))
796  nX = nPrtRight;
797  }
798  }
799  }
800 
801  do
802  {
803  //If I'm in the DocumentBody, I want to stay there.
804  if ( pStart->IsInDocBody() )
805  {
806  while ( pCnt && (!pCnt->IsInDocBody() ||
807  (pCnt->IsTextFrame() && static_cast<const SwTextFrame*>(pCnt)->IsHiddenNow())))
808  {
809  pCnt = (*fnNxtPrv)( pCnt );
810  pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, true, bInReadOnly, bTableSel );
811  }
812  }
813 
814  //If I'm in the FootNoteArea, I try to reach the next FootNoteArea in
815  //case of necessity.
816  else if ( pStart->IsInFootnote() )
817  {
818  while ( pCnt && (!pCnt->IsInFootnote() ||
819  (pCnt->IsTextFrame() && static_cast<const SwTextFrame*>(pCnt)->IsHiddenNow())))
820  {
821  pCnt = (*fnNxtPrv)( pCnt );
822  pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, true, bInReadOnly, bTableSel );
823  }
824  }
825 
826  //In Flys we can go ahead blindly as long as we find a Content.
827  else if ( pStart->IsInFly() )
828  {
829  if ( pCnt && pCnt->IsTextFrame() && static_cast<const SwTextFrame*>(pCnt)->IsHiddenNow() )
830  {
831  pCnt = (*fnNxtPrv)( pCnt );
832  pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, true, bInReadOnly, bTableSel );
833  }
834  }
835 
836  //Otherwise I'll just refuse to leave to current area.
837  else if ( pCnt )
838  {
839  const SwFrame *pUp = pStart->GetUpper();
840  while (pUp && pUp->GetUpper() && !(pUp->GetType() & FRM_HEADFOOT))
841  pUp = pUp->GetUpper();
842  bool bSame = false;
843  const SwFrame *pCntUp = pCnt->GetUpper();
844  while ( pCntUp && !bSame )
845  {
846  if ( pUp == pCntUp )
847  bSame = true;
848  else
849  pCntUp = pCntUp->GetUpper();
850  }
851  if ( !bSame )
852  pCnt = nullptr;
853  else if (pCnt->IsTextFrame() && static_cast<const SwTextFrame*>(pCnt)->IsHiddenNow()) // i73332
854  {
855  pCnt = (*fnNxtPrv)( pCnt );
856  pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, true, bInReadOnly, bTableSel );
857  }
858  }
859 
860  if ( bTab )
861  {
862  if ( !pCnt )
863  bEnd = true;
864  else
865  {
866  const SwTabFrame *pTab = pCnt->FindTabFrame();
867  if( !pTab )
868  bEnd = true;
869  else
870  {
871  if ( pTab != pTable )
872  {
873  //The flow leads from one table to the next. The X-value
874  //needs to be corrected by the amount of the offset of
875  //the tables
876  if ( pTable &&
877  !pTab->GetUpper()->IsInTab() &&
878  !pTable->GetUpper()->IsInTab() )
879  nX += pTab->getFrameArea().Left() - pTable->getFrameArea().Left();
880  pTable = pTab;
881  }
882  const SwLayoutFrame *pCell = pCnt->GetUpper();
883  while ( pCell && !pCell->IsCellFrame() )
884  pCell = pCell->GetUpper();
885 
886  Point aInsideCell;
887  Point aInsideCnt;
888  if ( pCell )
889  {
890  long nTmpTop = aRectFnSet.GetTop(pCell->getFrameArea());
891  if ( aRectFnSet.IsVert() )
892  {
893  if ( nTmpTop )
894  nTmpTop = aRectFnSet.XInc(nTmpTop, -1);
895 
896  aInsideCell = Point( nTmpTop, nX );
897  }
898  else
899  aInsideCell = Point( nX, nTmpTop );
900  }
901 
902  long nTmpTop = aRectFnSet.GetTop(pCnt->getFrameArea());
903  if ( aRectFnSet.IsVert() )
904  {
905  if ( nTmpTop )
906  nTmpTop = aRectFnSet.XInc(nTmpTop, -1);
907 
908  aInsideCnt = Point( nTmpTop, nX );
909  }
910  else
911  aInsideCnt = Point( nX, nTmpTop );
912 
913  if ( pCell && pCell->getFrameArea().IsInside( aInsideCell ) )
914  {
915  bEnd = true;
916  //Get the right Content out of the cell.
917  if ( !pCnt->getFrameArea().IsInside( aInsideCnt ) )
918  {
919  pCnt = pCell->ContainsContent();
920  if ( fnNxtPrv == lcl_GetPrvCnt )
921  while ( pCell->IsAnLower(pCnt->GetNextContentFrame()) )
922  pCnt = pCnt->GetNextContentFrame();
923  }
924  }
925  else if ( pCnt->getFrameArea().IsInside( aInsideCnt ) )
926  bEnd = true;
927  }
928  }
929  if ( !bEnd )
930  {
931  pCnt = (*fnNxtPrv)( pCnt );
932  pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, true, bInReadOnly, bTableSel );
933  }
934  }
935 
936  } while ( !bEnd ||
937  (pCnt && pCnt->IsTextFrame() && static_cast<const SwTextFrame*>(pCnt)->IsHiddenNow()));
938 
939  if (pCnt == nullptr)
940  {
941  return false;
942  }
943  if (pCnt->IsTextFrame())
944  {
945  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(pCnt));
946  *pPam->GetPoint() = pFrame->MapViewToModelPos(TextFrameIndex(
947  fnNxtPrv == lcl_GetPrvCnt
948  ? pFrame->GetText().getLength()
949  : 0));
950  }
951  else
952  { // set the Point on the Content-Node
953  assert(pCnt->IsNoTextFrame());
954  SwContentNode *const pCNd = const_cast<SwContentNode*>(static_cast<SwNoTextFrame const*>(pCnt)->GetNode());
955  pPam->GetPoint()->nNode = *pCNd;
956  if ( fnNxtPrv == lcl_GetPrvCnt )
957  pCNd->MakeEndIndex( &pPam->GetPoint()->nContent );
958  else
959  pCNd->MakeStartIndex( &pPam->GetPoint()->nContent );
960  }
961  return true;
962 }
963 
964 bool SwContentFrame::UnitUp( SwPaM* pPam, const SwTwips, bool bInReadOnly ) const
965 {
966  return ::lcl_UpDown( pPam, this, lcl_GetPrvCnt, bInReadOnly );
967 }
968 
969 bool SwContentFrame::UnitDown( SwPaM* pPam, const SwTwips, bool bInReadOnly ) const
970 {
971  return ::lcl_UpDown( pPam, this, lcl_GetNxtCnt, bInReadOnly );
972 }
973 
979 sal_uInt16 SwRootFrame::GetCurrPage( const SwPaM *pActualCursor ) const
980 {
981  OSL_ENSURE( pActualCursor, "got no page cursor" );
982  SwFrame const*const pActFrame = pActualCursor->GetPoint()->nNode.GetNode().
984  pActualCursor->GetPoint());
985  return pActFrame->FindPageFrame()->GetPhyPageNum();
986 }
987 
995 sal_uInt16 SwRootFrame::SetCurrPage( SwCursor* pToSet, sal_uInt16 nPageNum )
996 {
997  vcl::RenderContext* pRenderContext = GetCurrShell() ? GetCurrShell()->GetOut() : nullptr;
998  OSL_ENSURE( Lower() && Lower()->IsPageFrame(), "No page available." );
999 
1000  SwPageFrame *pPage = static_cast<SwPageFrame*>(Lower());
1001  bool bEnd =false;
1002  while ( !bEnd && pPage->GetPhyPageNum() != nPageNum )
1003  { if ( pPage->GetNext() )
1004  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
1005  else
1006  { //Search the first ContentFrame and format until a new page is started
1007  //or until the ContentFrame are all done.
1008  const SwContentFrame *pContent = pPage->ContainsContent();
1009  while ( pContent && pPage->IsAnLower( pContent ) )
1010  {
1011  pContent->Calc(pRenderContext);
1012  pContent = pContent->GetNextContentFrame();
1013  }
1014  //Either this is a new page or we found the last page.
1015  if ( pPage->GetNext() )
1016  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
1017  else
1018  bEnd = true;
1019  }
1020  }
1021  //pPage now points to the 'requested' page. Now we have to create the PaM
1022  //on the beginning of the first ContentFrame in the body-text.
1023  //If this is a footnote-page, the PaM will be set in the first footnote.
1024  const SwContentFrame *pContent = pPage->ContainsContent();
1025  if ( pPage->IsFootnotePage() )
1026  while ( pContent && !pContent->IsInFootnote() )
1027  pContent = pContent->GetNextContentFrame();
1028  else
1029  while ( pContent && !pContent->IsInDocBody() )
1030  pContent = pContent->GetNextContentFrame();
1031  if ( pContent )
1032  {
1033  assert(pContent->IsTextFrame());
1034  SwTextFrame const*const pFrame(static_cast<const SwTextFrame*>(pContent));
1035  *pToSet->GetPoint() = pFrame->MapViewToModelPos(pFrame->GetOfst());
1036 
1037  SwShellCursor* pSCursor = dynamic_cast<SwShellCursor*>(pToSet);
1038  if( pSCursor )
1039  {
1040  Point &rPt = pSCursor->GetPtPos();
1041  rPt = pContent->getFrameArea().Pos();
1042  rPt += pContent->getFramePrintArea().Pos();
1043  }
1044  return pPage->GetPhyPageNum();
1045  }
1046  return 0;
1047 }
1048 
1050 {
1051  return const_cast<SwPageFrame*>(static_cast<const SwPageFrame*>(pLayout))->FindFirstBodyContent();
1052 }
1053 
1055 {
1056  return const_cast<SwPageFrame*>(static_cast<const SwPageFrame*>(pLayout))->FindLastBodyContent();
1057 }
1058 
1060 {
1061  SwLayoutFrame *pNext =
1062  (pFrame->GetNext() && pFrame->GetNext()->IsLayoutFrame()) ?
1063  const_cast<SwLayoutFrame*>(static_cast<const SwLayoutFrame*>(pFrame->GetNext())) : nullptr;
1064  // #i39402# in case of an empty page
1065  if(pNext && !pNext->ContainsContent())
1066  pNext = (pNext->GetNext() && pNext->GetNext()->IsLayoutFrame()) ?
1067  static_cast<SwLayoutFrame*>(pNext->GetNext()) : nullptr;
1068  return pNext;
1069 }
1070 
1072 {
1073  return const_cast<SwLayoutFrame*>(pFrame);
1074 }
1075 
1077 {
1078  SwLayoutFrame *pPrev =
1079  (pFrame->GetPrev() && pFrame->GetPrev()->IsLayoutFrame()) ?
1080  const_cast<SwLayoutFrame*>(static_cast<const SwLayoutFrame*>(pFrame->GetPrev())) : nullptr;
1081  // #i39402# in case of an empty page
1082  if(pPrev && !pPrev->ContainsContent())
1083  pPrev = (pPrev->GetPrev() && pPrev->GetPrev()->IsLayoutFrame()) ?
1084  static_cast<SwLayoutFrame*>(pPrev->GetPrev()) : nullptr;
1085  return pPrev;
1086 }
1087 
1092 bool GetFrameInPage( const SwContentFrame *pCnt, SwWhichPage fnWhichPage,
1093  SwPosPage fnPosPage, SwPaM *pPam )
1094 {
1095  //First find the requested page, at first the current, then the one which
1096  //was requests through fnWichPage.
1097  const SwLayoutFrame *pLayoutFrame = pCnt->FindPageFrame();
1098  if ( !pLayoutFrame || (nullptr == (pLayoutFrame = (*fnWhichPage)(pLayoutFrame))) )
1099  return false;
1100 
1101  //Now the desired ContentFrame below the page
1102  if( nullptr == (pCnt = (*fnPosPage)(pLayoutFrame)) )
1103  return false;
1104  else
1105  {
1106  // repeated headlines in tables
1107  if ( pCnt->IsInTab() && fnPosPage == GetFirstSub )
1108  {
1109  const SwTabFrame* pTab = pCnt->FindTabFrame();
1110  if ( pTab->IsFollow() )
1111  {
1112  if ( pTab->IsInHeadline( *pCnt ) )
1113  {
1114  SwLayoutFrame* pRow = pTab->GetFirstNonHeadlineRow();
1115  if ( pRow )
1116  {
1117  // We are in the first line of a follow table
1118  // with repeated headings.
1119  // To actually make a "real" move we take the first content
1120  // of the next row
1121  pCnt = pRow->ContainsContent();
1122  if ( ! pCnt )
1123  return false;
1124  }
1125  }
1126  }
1127  }
1128 
1129  assert(pCnt->IsTextFrame());
1130  SwTextFrame const*const pFrame(static_cast<const SwTextFrame*>(pCnt));
1131  TextFrameIndex const nIdx((fnPosPage == GetFirstSub)
1132  ? pFrame->GetOfst()
1133  : (pFrame->GetFollow())
1134  ? pFrame->GetFollow()->GetOfst() - TextFrameIndex(1)
1135  : TextFrameIndex(pFrame->GetText().getLength()));
1136  *pPam->GetPoint() = pFrame->MapViewToModelPos(nIdx);
1137  return true;
1138  }
1139 }
1140 
1141 static sal_uInt64 CalcDiff(const Point &rPt1, const Point &rPt2)
1142 {
1143  //Calculate the distance between the two points.
1144  //'delta' X^2 + 'delta'Y^2 = 'distance'^2
1145  sal_uInt64 dX = std::max( rPt1.X(), rPt2.X() ) -
1146  std::min( rPt1.X(), rPt2.X() ),
1147  dY = std::max( rPt1.Y(), rPt2.Y() ) -
1148  std::min( rPt1.Y(), rPt2.Y() );
1149  return (dX * dX) + (dY * dY);
1150 }
1151 
1158 static const SwLayoutFrame* lcl_Inside( const SwContentFrame *pCnt, Point const & rPt )
1159 {
1160  const SwLayoutFrame* pUp = pCnt->GetUpper();
1161  while( pUp )
1162  {
1163  if( pUp->IsPageBodyFrame() || pUp->IsFooterFrame() || pUp->IsHeaderFrame() )
1164  {
1165  if( rPt.Y() >= pUp->getFrameArea().Top() && rPt.Y() <= pUp->getFrameArea().Bottom() )
1166  return pUp;
1167  return nullptr;
1168  }
1169  if( pUp->IsFootnoteContFrame() )
1170  return pUp->getFrameArea().IsInside( rPt ) ? pUp : nullptr;
1171  pUp = pUp->GetUpper();
1172  }
1173  return nullptr;
1174 }
1175 
1184  const bool bDontLeave,
1185  const bool bBodyOnly,
1186  SwCursorMoveState *pCMS,
1187  const bool bDefaultExpand ) const
1188 {
1189  //Determine the first ContentFrame.
1190  const SwLayoutFrame *pStart = (!bDontLeave && bDefaultExpand && GetPrev()) ?
1191  static_cast<const SwLayoutFrame*>(GetPrev()) : this;
1192  const SwContentFrame *pContent = pStart->ContainsContent();
1193 
1194  if ( !pContent && (GetPrev() && !bDontLeave) )
1195  pContent = ContainsContent();
1196 
1197  if ( bBodyOnly && pContent && !pContent->IsInDocBody() )
1198  while ( pContent && !pContent->IsInDocBody() )
1199  pContent = pContent->GetNextContentFrame();
1200 
1201  const SwContentFrame *pActual= pContent;
1202  const SwLayoutFrame *pInside = nullptr;
1203  sal_uInt16 nMaxPage = GetPhyPageNum() + (bDefaultExpand ? 1 : 0);
1204  Point aPoint = rPoint;
1205  sal_uInt64 nDistance = SAL_MAX_UINT64;
1206 
1207  while ( true ) //A loop to be sure we always find one.
1208  {
1209  while ( pContent &&
1210  ((!bDontLeave || IsAnLower( pContent )) &&
1211  (pContent->GetPhyPageNum() <= nMaxPage)) )
1212  {
1213  if ( pContent->getFrameArea().Width() &&
1214  ( !bBodyOnly || pContent->IsInDocBody() ) )
1215  {
1216  //If the Content lies in a protected area (cell, Footnote, section),
1217  //we search the next Content which is not protected.
1218  const SwContentFrame *pComp = pContent;
1219  pContent = ::lcl_MissProtectedFrames( pContent, lcl_GetNxtCnt, false,
1220  pCMS && pCMS->m_bSetInReadOnly, false );
1221  if ( pComp != pContent )
1222  continue;
1223 
1224  if ( !pContent->IsTextFrame() || !static_cast<const SwTextFrame*>(pContent)->IsHiddenNow() )
1225  {
1226  SwRect aContentFrame( pContent->UnionFrame() );
1227  if ( aContentFrame.IsInside( rPoint ) )
1228  {
1229  pActual = pContent;
1230  aPoint = rPoint;
1231  break;
1232  }
1233  //The distance from rPoint to the nearest Point of pContent
1234  //will now be calculated.
1235  Point aContentPoint( rPoint );
1236 
1237  //First set the vertical position
1238  if ( aContentFrame.Top() > aContentPoint.Y() )
1239  aContentPoint.setY( aContentFrame.Top() );
1240  else if ( aContentFrame.Bottom() < aContentPoint.Y() )
1241  aContentPoint.setY( aContentFrame.Bottom() );
1242 
1243  //Now the horizontal position
1244  if ( aContentFrame.Left() > aContentPoint.X() )
1245  aContentPoint.setX( aContentFrame.Left() );
1246  else if ( aContentFrame.Right() < aContentPoint.X() )
1247  aContentPoint.setX( aContentFrame.Right() );
1248 
1249  // pInside is a page area in which the point lies. As soon
1250  // as pInside != 0 only frames are accepted which are
1251  // placed inside.
1252  if( !pInside || ( pInside->IsAnLower( pContent ) &&
1253  ( !pContent->IsInFootnote() || pInside->IsFootnoteContFrame() ) ) )
1254  {
1255  const sal_uInt64 nDiff = ::CalcDiff(aContentPoint, rPoint);
1256  bool bBetter = nDiff < nDistance; // This one is nearer
1257  if( !pInside )
1258  {
1259  pInside = lcl_Inside( pContent, rPoint );
1260  if( pInside ) // In the "right" page area
1261  bBetter = true;
1262  }
1263  if( bBetter )
1264  {
1265  aPoint = aContentPoint;
1266  nDistance = nDiff;
1267  pActual = pContent;
1268  }
1269  }
1270  }
1271  }
1272  pContent = pContent->GetNextContentFrame();
1273  if ( bBodyOnly )
1274  while ( pContent && !pContent->IsInDocBody() )
1275  pContent = pContent->GetNextContentFrame();
1276  }
1277  if ( !pActual )
1278  { //If we not yet found one we have to expand the searched
1279  //area, sometime we will find one!
1280  //MA 1997-01-09: Opt for many empty pages - if we only search inside
1281  //the body, we can expand the searched area sufficiently in one step.
1282  if ( bBodyOnly )
1283  {
1284  while ( !pContent && pStart->GetPrev() )
1285  {
1286  ++nMaxPage;
1287  if( !pStart->GetPrev()->IsLayoutFrame() )
1288  return nullptr;
1289  pStart = static_cast<const SwLayoutFrame*>(pStart->GetPrev());
1290  pContent = pStart->IsInDocBody()
1291  ? pStart->ContainsContent()
1292  : pStart->FindPageFrame()->FindFirstBodyContent();
1293  }
1294  if ( !pContent ) // Somewhere down the road we have to start with one!
1295  {
1296  pContent = pStart->FindPageFrame()->GetUpper()->ContainsContent();
1297  while ( pContent && !pContent->IsInDocBody() )
1298  pContent = pContent->GetNextContentFrame();
1299  if ( !pContent )
1300  return nullptr; // There is no document content yet!
1301  }
1302  }
1303  else
1304  {
1305  ++nMaxPage;
1306  if ( pStart->GetPrev() )
1307  {
1308  if( !pStart->GetPrev()->IsLayoutFrame() )
1309  return nullptr;
1310  pStart = static_cast<const SwLayoutFrame*>(pStart->GetPrev());
1311  pContent = pStart->ContainsContent();
1312  }
1313  else // Somewhere down the road we have to start with one!
1314  pContent = pStart->FindPageFrame()->GetUpper()->ContainsContent();
1315  }
1316  pActual = pContent;
1317  }
1318  else
1319  break;
1320  }
1321 
1322  OSL_ENSURE( pActual, "no Content found." );
1323  OSL_ENSURE( !bBodyOnly || pActual->IsInDocBody(), "Content not in Body." );
1324 
1325  //Special case for selecting tables not in repeated TableHeadlines.
1326  if ( pActual->IsInTab() && pCMS && pCMS->m_eState == MV_TBLSEL )
1327  {
1328  const SwTabFrame *pTab = pActual->FindTabFrame();
1329  if ( pTab->IsFollow() && pTab->IsInHeadline( *pActual ) )
1330  {
1331  pCMS->m_bStop = true;
1332  return nullptr;
1333  }
1334  }
1335 
1336  //A small correction at the first/last
1337  Size aActualSize( pActual->getFramePrintArea().SSize() );
1338  if ( aActualSize.Height() > pActual->GetUpper()->getFramePrintArea().Height() )
1339  aActualSize.setHeight( pActual->GetUpper()->getFramePrintArea().Height() );
1340 
1341  SwRectFnSet aRectFnSet(pActual);
1342  if ( !pActual->GetPrev() &&
1343  aRectFnSet.YDiff( aRectFnSet.GetPrtTop(*pActual),
1344  aRectFnSet.IsVert() ? rPoint.X() : rPoint.Y() ) > 0 )
1345  {
1346  aPoint.setY( pActual->getFrameArea().Top() + pActual->getFramePrintArea().Top() );
1347  aPoint.setX( pActual->getFrameArea().Left() +
1348  ( pActual->IsRightToLeft() || aRectFnSet.IsVert() ?
1349  pActual->getFramePrintArea().Right() :
1350  pActual->getFramePrintArea().Left() ) );
1351  }
1352  else if ( !pActual->GetNext() &&
1353  aRectFnSet.YDiff( aRectFnSet.GetPrtBottom(*pActual),
1354  aRectFnSet.IsVert() ? rPoint.X() : rPoint.Y() ) < 0 )
1355  {
1356  aPoint.setY( pActual->getFrameArea().Top() + pActual->getFramePrintArea().Bottom() );
1357  aPoint.setX( pActual->getFrameArea().Left() +
1358  ( pActual->IsRightToLeft() || aRectFnSet.IsVert() ?
1359  pActual->getFramePrintArea().Left() :
1360  pActual->getFramePrintArea().Right() ) );
1361  }
1362 
1363  //Bring the Point into the PrtArea
1364  const SwRect aRect( pActual->getFrameArea().Pos() + pActual->getFramePrintArea().Pos(),
1365  aActualSize );
1366  if ( aPoint.Y() < aRect.Top() )
1367  aPoint.setY( aRect.Top() );
1368  else if ( aPoint.Y() > aRect.Bottom() )
1369  aPoint.setY( aRect.Bottom() );
1370  if ( aPoint.X() < aRect.Left() )
1371  aPoint.setX( aRect.Left() );
1372  else if ( aPoint.X() > aRect.Right() )
1373  aPoint.setX( aRect.Right() );
1374  rPoint = aPoint;
1375  return pActual;
1376 }
1377 
1379 void SwPageFrame::GetContentPosition( const Point &rPt, SwPosition &rPos ) const
1380 {
1381  //Determine the first ContentFrame.
1383  if ( pContent )
1384  {
1385  //Look back one more (if possible).
1386  const SwContentFrame *pTmp = pContent->GetPrevContentFrame();
1387  while ( pTmp && !pTmp->IsInDocBody() )
1388  pTmp = pTmp->GetPrevContentFrame();
1389  if ( pTmp )
1390  pContent = pTmp;
1391  }
1392  else
1393  pContent = GetUpper()->ContainsContent();
1394 
1395  const SwContentFrame *pAct = pContent;
1396  Point aAct = rPt;
1397  sal_uInt64 nDist = SAL_MAX_UINT64;
1398 
1399  while ( pContent )
1400  {
1401  SwRect aContentFrame( pContent->UnionFrame() );
1402  if ( aContentFrame.IsInside( rPt ) )
1403  {
1404  //This is the nearest one.
1405  pAct = pContent;
1406  break;
1407  }
1408 
1409  //Calculate the distance from rPt to the nearest point of pContent.
1410  Point aPoint( rPt );
1411 
1412  //Calculate the vertical position first
1413  if ( aContentFrame.Top() > rPt.Y() )
1414  aPoint.setY( aContentFrame.Top() );
1415  else if ( aContentFrame.Bottom() < rPt.Y() )
1416  aPoint.setY( aContentFrame.Bottom() );
1417 
1418  //And now the horizontal position
1419  if ( aContentFrame.Left() > rPt.X() )
1420  aPoint.setX( aContentFrame.Left() );
1421  else if ( aContentFrame.Right() < rPt.X() )
1422  aPoint.setX( aContentFrame.Right() );
1423 
1424  const sal_uInt64 nDiff = ::CalcDiff( aPoint, rPt );
1425  if ( nDiff < nDist )
1426  {
1427  aAct = aPoint;
1428  nDist = nDiff;
1429  pAct = pContent;
1430  }
1431  else if ( aContentFrame.Top() > getFrameArea().Bottom() )
1432  //In terms of fields, it's not possible to be closer any more!
1433  break;
1434 
1435  pContent = pContent->GetNextContentFrame();
1436  while ( pContent && !pContent->IsInDocBody() )
1437  pContent = pContent->GetNextContentFrame();
1438  }
1439 
1440  //Bring the point into the PrtArea.
1441  const SwRect aRect( pAct->getFrameArea().Pos() + pAct->getFramePrintArea().Pos(), pAct->getFramePrintArea().SSize() );
1442  if ( aAct.Y() < aRect.Top() )
1443  aAct.setY( aRect.Top() );
1444  else if ( aAct.Y() > aRect.Bottom() )
1445  aAct.setY( aRect.Bottom() );
1446  if ( aAct.X() < aRect.Left() )
1447  aAct.setX( aRect.Left() );
1448  else if ( aAct.X() > aRect.Right() )
1449  aAct.setX( aRect.Right() );
1450 
1451  if (!pAct->isFrameAreaDefinitionValid() ||
1452  (pAct->IsTextFrame() && !static_cast<SwTextFrame const*>(pAct)->HasPara()))
1453  {
1454  // ContentFrame not formatted -> always on node-beginning
1455  // tdf#100635 also if the SwTextFrame would require reformatting,
1456  // which is unwanted in case this is called from text formatting code
1457  rPos = static_cast<SwTextFrame const*>(pAct)->MapViewToModelPos(TextFrameIndex(0));
1458  }
1459  else
1460  {
1461  SwCursorMoveState aTmpState( MV_SETONLYTEXT );
1462  pAct->GetCursorOfst( &rPos, aAct, &aTmpState );
1463  }
1464 }
1465 
1472 Point SwRootFrame::GetNextPrevContentPos( const Point& rPoint, bool bNext ) const
1473 {
1474  vcl::RenderContext* pRenderContext = GetCurrShell() ? GetCurrShell()->GetOut() : nullptr;
1475  // #123110# - disable creation of an action by a callback
1476  // event during processing of this method. Needed because formatting is
1477  // triggered by this method.
1478  DisableCallbackAction aDisableCallbackAction(const_cast<SwRootFrame&>(*this));
1479  //Search the first ContentFrame and his successor in the body area.
1480  //To be efficient (and not formatting too much) we'll start at the correct
1481  //page.
1482  const SwLayoutFrame *pPage = static_cast<const SwLayoutFrame*>(Lower());
1483  if( pPage )
1484  while( pPage->GetNext() && pPage->getFrameArea().Bottom() < rPoint.Y() )
1485  pPage = static_cast<const SwLayoutFrame*>(pPage->GetNext());
1486 
1487  const SwContentFrame *pCnt = pPage ? pPage->ContainsContent() : ContainsContent();
1488  while ( pCnt && !pCnt->IsInDocBody() )
1489  pCnt = pCnt->GetNextContentFrame();
1490 
1491  if ( !pCnt )
1492  return Point( 0, 0 );
1493 
1494  pCnt->Calc(pRenderContext);
1495  if( !bNext )
1496  {
1497  // As long as the point lies before the first ContentFrame and there are
1498  // still precedent pages I'll go to the next page.
1499  while ( rPoint.Y() < pCnt->getFrameArea().Top() && pPage->GetPrev() )
1500  {
1501  pPage = static_cast<const SwLayoutFrame*>(pPage->GetPrev());
1502  pCnt = pPage->ContainsContent();
1503  while ( !pCnt )
1504  {
1505  pPage = static_cast<const SwLayoutFrame*>(pPage->GetPrev());
1506  if ( pPage )
1507  pCnt = pPage->ContainsContent();
1508  else
1509  return ContainsContent()->UnionFrame().Pos();
1510  }
1511  pCnt->Calc(pRenderContext);
1512  }
1513  }
1514 
1515  //Does the point lie above the first ContentFrame?
1516  if ( rPoint.Y() < pCnt->getFrameArea().Top() && !lcl_IsInRepeatedHeadline( pCnt ) )
1517  return pCnt->UnionFrame().Pos();
1518 
1519  Point aRet(0, 0);
1520  do
1521  {
1522  //Does the point lie in the current ContentFrame?
1523  SwRect aContentFrame( pCnt->UnionFrame() );
1524  if ( aContentFrame.IsInside( rPoint ) && !lcl_IsInRepeatedHeadline( pCnt ))
1525  {
1526  aRet = rPoint;
1527  break;
1528  }
1529 
1530  //Is the current one the last ContentFrame?
1531  //If the next ContentFrame lies behind the point, then the current on is the
1532  //one we searched.
1533  const SwContentFrame *pNxt = pCnt->GetNextContentFrame();
1534  while ( pNxt && !pNxt->IsInDocBody() )
1535  pNxt = pNxt->GetNextContentFrame();
1536 
1537  //Does the point lie behind the last ContentFrame?
1538  if ( !pNxt )
1539  {
1540  aRet = Point( aContentFrame.Right(), aContentFrame.Bottom() );
1541  break;
1542  }
1543 
1544  //If the next ContentFrame lies behind the point then it is the one we
1545  //searched.
1546  const SwTabFrame* pTFrame;
1547  pNxt->Calc(pRenderContext);
1548  if( pNxt->getFrameArea().Top() > rPoint.Y() &&
1549  !lcl_IsInRepeatedHeadline( pCnt, &pTFrame ) &&
1550  ( !pTFrame || pNxt->getFrameArea().Left() > rPoint.X() ))
1551  {
1552  if (bNext)
1553  aRet = pNxt->getFrameArea().Pos();
1554  else
1555  aRet = Point( aContentFrame.Right(), aContentFrame.Bottom() );
1556  break;
1557  }
1558  pCnt = pNxt;
1559  }
1560  while (pCnt);
1561  return aRet;
1562 }
1563 
1571 Point SwRootFrame::GetPagePos( sal_uInt16 nPageNum ) const
1572 {
1573  OSL_ENSURE( Lower() && Lower()->IsPageFrame(), "No page available." );
1574 
1575  const SwPageFrame *pPage = static_cast<const SwPageFrame*>(Lower());
1576  while ( true )
1577  {
1578  if ( pPage->GetPhyPageNum() >= nPageNum || !pPage->GetNext() )
1579  break;
1580  pPage = static_cast<const SwPageFrame*>(pPage->GetNext());
1581  }
1582  return pPage->getFrameArea().Pos();
1583 }
1584 
1589 SwPageFrame* SwRootFrame::GetPageByPageNum( sal_uInt16 _nPageNum ) const
1590 {
1591  const SwPageFrame* pPageFrame = static_cast<const SwPageFrame*>( Lower() );
1592  while ( pPageFrame && pPageFrame->GetPhyPageNum() < _nPageNum )
1593  {
1594  pPageFrame = static_cast<const SwPageFrame*>( pPageFrame->GetNext() );
1595  }
1596 
1597  if ( pPageFrame && pPageFrame->GetPhyPageNum() == _nPageNum )
1598  {
1599  return const_cast<SwPageFrame*>( pPageFrame );
1600  }
1601  else
1602  {
1603  return nullptr;
1604  }
1605 }
1606 
1610 bool SwRootFrame::IsDummyPage( sal_uInt16 nPageNum ) const
1611 {
1612  if( !Lower() || !nPageNum || nPageNum > GetPageNum() )
1613  return true;
1614 
1615  const SwPageFrame *pPage = static_cast<const SwPageFrame*>(Lower());
1616  while( pPage && nPageNum < pPage->GetPhyPageNum() )
1617  pPage = static_cast<const SwPageFrame*>(pPage->GetNext());
1618  return !pPage || pPage->IsEmptyPage();
1619 }
1620 
1626 {
1627  if (IsTextFrame())
1628  {
1629  const SwDoc *pDoc = &static_cast<const SwTextFrame*>(this)->GetDoc();
1630  bool isFormProtected=pDoc->GetDocumentSettingManager().get(DocumentSettingId::PROTECT_FORM );
1631  if (isFormProtected)
1632  {
1633  return false; // TODO a hack for now, well deal with it later, I we return true here we have a "double" locking
1634  }
1635  }
1636  //The Frame can be protected in borders, cells or sections.
1637  //Also goes up FlyFrames recursive and from footnote to anchor.
1638  const SwFrame *pFrame = this;
1639  do
1640  {
1641  if (pFrame->IsTextFrame())
1642  { // sw_redlinehide: redlines can't overlap section nodes, so any node will do
1643  if (static_cast<SwTextFrame const*>(pFrame)->GetTextNodeFirst()->IsInProtectSect())
1644  {
1645  return true;
1646  }
1647  }
1648  else if ( pFrame->IsContentFrame() )
1649  {
1650  assert(pFrame->IsNoTextFrame());
1651  if (static_cast<const SwNoTextFrame*>(pFrame)->GetNode() &&
1652  static_cast<const SwNoTextFrame*>(pFrame)->GetNode()->IsInProtectSect())
1653  {
1654  return true;
1655  }
1656  }
1657  else
1658  {
1659  if ( static_cast<const SwLayoutFrame*>(pFrame)->GetFormat() &&
1660  static_cast<const SwLayoutFrame*>(pFrame)->GetFormat()->
1661  GetProtect().IsContentProtected() )
1662  return true;
1663  if ( pFrame->IsCoveredCell() )
1664  return true;
1665  }
1666  if ( pFrame->IsFlyFrame() )
1667  {
1668  //In a chain the protection of the content can be specified by the
1669  //master of the chain.
1670  if ( static_cast<const SwFlyFrame*>(pFrame)->GetPrevLink() )
1671  {
1672  const SwFlyFrame *pMaster = static_cast<const SwFlyFrame*>(pFrame);
1673  do
1674  { pMaster = pMaster->GetPrevLink();
1675  } while ( pMaster->GetPrevLink() );
1676  if ( pMaster->IsProtected() )
1677  return true;
1678  }
1679  pFrame = static_cast<const SwFlyFrame*>(pFrame)->GetAnchorFrame();
1680  }
1681  else if ( pFrame->IsFootnoteFrame() )
1682  pFrame = static_cast<const SwFootnoteFrame*>(pFrame)->GetRef();
1683  else
1684  pFrame = pFrame->GetUpper();
1685 
1686  } while ( pFrame );
1687 
1688  return false;
1689 }
1690 
1692 sal_uInt16 SwFrame::GetPhyPageNum() const
1693 {
1694  const SwPageFrame *pPage = FindPageFrame();
1695  return pPage ? pPage->GetPhyPageNum() : 0;
1696 }
1697 
1710 {
1711  const SwPageFrame *pPage = FindPageFrame();
1712  if ( !pPage || !pPage->GetUpper() )
1713  return true;
1714 
1715  const SwFrame *pFlow = pPage->FindFirstBodyContent();
1716  const SwPageDesc *pDesc = nullptr;
1717  ::o3tl::optional<sal_uInt16> oPgNum;
1718  if ( pFlow )
1719  {
1720  if ( pFlow->IsInTab() )
1721  pFlow = pFlow->FindTabFrame();
1722  const SwFlowFrame *pTmp = SwFlowFrame::CastFlowFrame( pFlow );
1723  if ( !pTmp->IsFollow() )
1724  {
1725  const SwFormatPageDesc& rPgDesc = pFlow->GetPageDescItem();
1726  pDesc = rPgDesc.GetPageDesc();
1727  oPgNum = rPgDesc.GetNumOffset();
1728  }
1729  }
1730  if ( !pDesc )
1731  {
1732  SwPageFrame *pPrv = const_cast<SwPageFrame*>(static_cast<const SwPageFrame*>(pPage->GetPrev()));
1733  if( pPrv && pPrv->IsEmptyPage() )
1734  pPrv = static_cast<SwPageFrame*>(pPrv->GetPrev());
1735  if( pPrv )
1736  pDesc = pPrv->GetPageDesc()->GetFollow();
1737  else
1738  {
1739  const SwDoc* pDoc = pPage->GetFormat()->GetDoc();
1740  pDesc = &pDoc->GetPageDesc( 0 );
1741  }
1742  }
1743  OSL_ENSURE( pDesc, "No pagedescriptor" );
1744  bool bOdd;
1745  if( oPgNum )
1746  bOdd = (*oPgNum % 2) != 0;
1747  else
1748  {
1749  bOdd = pPage->OnRightPage();
1750  if( pPage->GetPrev() && static_cast<const SwPageFrame*>(pPage->GetPrev())->IsEmptyPage() )
1751  bOdd = !bOdd;
1752  }
1753  if( !pPage->IsEmptyPage() )
1754  {
1755  if( !pDesc->GetRightFormat() )
1756  bOdd = false;
1757  else if( !pDesc->GetLeftFormat() )
1758  bOdd = true;
1759  }
1760  return bOdd;
1761 }
1762 
1764 {
1765  bool bRet = false;
1766  const SwPageFrame *pPage = FindPageFrame();
1767 
1768  if (pPage)
1769  {
1770  const SwPageFrame* pPrevFrame = dynamic_cast<const SwPageFrame*>(pPage->GetPrev());
1771  if (pPrevFrame)
1772  {
1773  if (pPrevFrame->IsEmptyPage() && pPrevFrame->GetPhyPageNum()==1)
1774  {
1775  // This was the first page of the document, but its page number
1776  // was set to an even number, so a blank page was automatically
1777  // inserted before it to make this be a "left" page.
1778  // We still use the first page format of the page style here.
1779  bRet = true;
1780  } else {
1781  const SwPageDesc* pDesc = pPage->GetPageDesc();
1782  bRet = pPrevFrame->GetPageDesc() != pDesc;
1783  }
1784  }
1785  else
1786  bRet = true;
1787  }
1788  return bRet;
1789 }
1790 
1791 void SwFrame::Calc(vcl::RenderContext* pRenderContext) const
1792 {
1794  {
1795  const_cast<SwFrame*>(this)->PrepareMake(pRenderContext);
1796  }
1797 }
1798 
1800 {
1801  Point aRet( getFrameArea().Pos() );
1802  // here we cast since SwLayoutFrame is declared only as forwarded
1803  aRet -= GetUpper()->getFramePrintArea().Pos();
1804  aRet -= GetUpper()->getFrameArea().Pos();
1805  return aRet;
1806 }
1807 
1809 sal_uInt16 SwFrame::GetVirtPageNum() const
1810 {
1811  const SwPageFrame *pPage = FindPageFrame();
1812  if ( !pPage || !pPage->GetUpper() )
1813  return 0;
1814 
1815  sal_uInt16 nPhyPage = pPage->GetPhyPageNum();
1816  if ( !static_cast<const SwRootFrame*>(pPage->GetUpper())->IsVirtPageNum() )
1817  return nPhyPage;
1818 
1819  //Search the nearest section using the virtual page number.
1820  //Because searching backwards needs a lot of time we search specific using
1821  //the dependencies. From the PageDescs we get the attributes and from the
1822  //attributes we get the sections.
1823  const SwPageFrame *pVirtPage = nullptr;
1824  const SwFrame *pFrame = nullptr;
1825  const SfxItemPool &rPool = pPage->GetFormat()->GetDoc()->GetAttrPool();
1826  for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(RES_PAGEDESC))
1827  {
1828  const SwFormatPageDesc *pDesc = dynamic_cast<const SwFormatPageDesc*>(pItem);
1829  if ( !pDesc )
1830  continue;
1831 
1832  if ( pDesc->GetNumOffset() && pDesc->GetDefinedIn() )
1833  {
1834  const SwModify *pMod = pDesc->GetDefinedIn();
1835  SwVirtPageNumInfo aInfo( pPage );
1836  pMod->GetInfo( aInfo );
1837  if ( aInfo.GetPage() )
1838  {
1839  if( !pVirtPage || aInfo.GetPage()->GetPhyPageNum() > pVirtPage->GetPhyPageNum() )
1840  {
1841  pVirtPage = aInfo.GetPage();
1842  pFrame = aInfo.GetFrame();
1843  }
1844  }
1845  }
1846  }
1847  if ( pFrame )
1848  {
1849  ::o3tl::optional<sal_uInt16> oNumOffset = pFrame->GetPageDescItem().GetNumOffset();
1850  if (oNumOffset)
1851  {
1852  return nPhyPage - pFrame->GetPhyPageNum() + *oNumOffset;
1853  }
1854  else
1855  {
1856  return nPhyPage - pFrame->GetPhyPageNum();
1857  }
1858  }
1859  return nPhyPage;
1860 }
1861 
1864 {
1865  //Find Union-Rects and tables (Follows) of the selection.
1866  OSL_ENSURE( rTableCursor.GetContentNode() && rTableCursor.GetContentNode( false ),
1867  "Tabselection not on Cnt." );
1868 
1869  bool bRet = false;
1870 
1871  // For new table models there's no need to ask the layout...
1872  if( rTableCursor.NewTableSelection() )
1873  return true;
1874 
1875  Point aPtPt, aMkPt;
1876  {
1877  SwShellCursor* pShCursor = dynamic_cast<SwShellCursor*>(&rTableCursor);
1878 
1879  if( pShCursor )
1880  {
1881  aPtPt = pShCursor->GetPtPos();
1882  aMkPt = pShCursor->GetMkPos();
1883  }
1884  }
1885 
1886  // #151012# Made code robust here
1887  const SwContentNode* pTmpStartNode = rTableCursor.GetContentNode();
1888  const SwContentNode* pTmpEndNode = rTableCursor.GetContentNode(false);
1889 
1890  std::pair<Point, bool> tmp(aPtPt, false);
1891  const SwFrame *const pTmpStartFrame = pTmpStartNode ? pTmpStartNode->getLayoutFrame(this, nullptr, &tmp) : nullptr;
1892  tmp.first = aMkPt;
1893  const SwFrame *const pTmpEndFrame = pTmpEndNode ? pTmpEndNode->getLayoutFrame(this, nullptr, &tmp) : nullptr;
1894 
1895  const SwLayoutFrame* pStart = pTmpStartFrame ? pTmpStartFrame->GetUpper() : nullptr;
1896  const SwLayoutFrame* pEnd = pTmpEndFrame ? pTmpEndFrame->GetUpper() : nullptr;
1897 
1898  OSL_ENSURE( pStart && pEnd, "MakeTableCursors: Good to have the code robust here!" );
1899 
1900  /* #109590# Only change table boxes if the frames are
1901  valid. Needed because otherwise the table cursor after moving
1902  table cells by dnd resulted in an empty tables cursor. */
1903  if ( pStart && pEnd && pStart->isFrameAreaDefinitionValid() && pEnd->isFrameAreaDefinitionValid())
1904  {
1905  SwSelUnions aUnions;
1906  ::MakeSelUnions( aUnions, pStart, pEnd );
1907 
1908  SwSelBoxes aNew;
1909 
1910  const bool bReadOnlyAvailable = rTableCursor.IsReadOnlyAvailable();
1911 
1912  for (SwSelUnion & rUnion : aUnions)
1913  {
1914  const SwTabFrame *pTable = rUnion.GetTable();
1915 
1916  // Skip any repeated headlines in the follow:
1917  SwLayoutFrame* pRow = pTable->IsFollow() ?
1918  pTable->GetFirstNonHeadlineRow() :
1919  const_cast<SwLayoutFrame*>(static_cast<const SwLayoutFrame*>(pTable->Lower()));
1920 
1921  while ( pRow )
1922  {
1923  if ( pRow->getFrameArea().IsOver( rUnion.GetUnion() ) )
1924  {
1925  const SwLayoutFrame *pCell = pRow->FirstCell();
1926 
1927  while ( pCell && pRow->IsAnLower( pCell ) )
1928  {
1929  OSL_ENSURE( pCell->IsCellFrame(), "Frame without cell" );
1930  if( IsFrameInTableSel( rUnion.GetUnion(), pCell ) &&
1931  (bReadOnlyAvailable ||
1932  !pCell->GetFormat()->GetProtect().IsContentProtected()))
1933  {
1934  SwTableBox* pInsBox = const_cast<SwTableBox*>(
1935  static_cast<const SwCellFrame*>(pCell)->GetTabBox());
1936  aNew.insert( pInsBox );
1937  }
1938  if ( pCell->GetNext() )
1939  {
1940  pCell = static_cast<const SwLayoutFrame*>(pCell->GetNext());
1941  if ( pCell->Lower() && pCell->Lower()->IsRowFrame() )
1942  pCell = pCell->FirstCell();
1943  }
1944  else
1945  {
1946  const SwLayoutFrame* pLastCell = pCell;
1947  do
1948  {
1949  pCell = pCell->GetNextLayoutLeaf();
1950  } while ( pCell && pLastCell->IsAnLower( pCell ) );
1951  // For sections with columns
1952  if( pCell && pCell->IsInTab() )
1953  {
1954  while( !pCell->IsCellFrame() )
1955  {
1956  pCell = pCell->GetUpper();
1957  OSL_ENSURE( pCell, "Where's my cell?" );
1958  }
1959  }
1960  }
1961  }
1962  }
1963  pRow = static_cast<SwLayoutFrame*>(pRow->GetNext());
1964  }
1965  }
1966 
1967  rTableCursor.ActualizeSelection( aNew );
1968  bRet = true;
1969  }
1970 
1971  return bRet;
1972 }
1973 
1974 static void Sub( SwRegionRects& rRegion, const SwRect& rRect )
1975 {
1976  if( rRect.Width() > 1 && rRect.Height() > 1 &&
1977  rRect.IsOver( rRegion.GetOrigin() ))
1978  rRegion -= rRect;
1979 }
1980 
1981 static void Add( SwRegionRects& rRegion, const SwRect& rRect )
1982 {
1983  if( rRect.Width() > 1 && rRect.Height() > 1 )
1984  rRegion += rRect;
1985 }
1986 
1987 /*
1988  * The following situations can happen:
1989  * 1. Start and end lie in one screen-row and in the same node
1990  * -> one rectangle out of start and end; and we're okay
1991  * 2. Start and end lie in one frame (therefore in the same node!)
1992  * -> expand start to the right, end to the left and if more than two
1993  * screen-rows are involved - calculate the in-between
1994  * 3. Start and end lie in different frames
1995  * -> expand start to the right until frame-end, calculate Rect
1996  * expand end to the left until frame-start, calculate Rect
1997  * and if more than two frames are involved add the PrtArea of all
1998  * frames which lie in between
1999  *
2000  * Big reorganization because of the FlyFrame - those need to be locked out.
2001  * Exceptions: - The Fly in which the selection took place (if it took place
2002  * in a Fly)
2003  * - The Flys which are underrun by the text
2004  * - The Flys which are anchored to somewhere inside the selection.
2005  * Functioning: First a SwRegion with a root gets initialized.
2006  * Out of the region the inverted sections are cut out. The
2007  * section gets compressed and finally inverted and thereby the
2008  * inverted rectangles are available.
2009  * In the end the Flys are cut out of the section.
2010  */
2012 {
2013  SwPosition *pStartPos = rCursor.Start(),
2014  *pEndPos = rCursor.GetPoint() == pStartPos ? rCursor.GetMark() : rCursor.GetPoint();
2015 
2016  SwViewShell *pSh = GetCurrShell();
2017 
2018  bool bIgnoreVisArea = true;
2019  if (pSh)
2020  bIgnoreVisArea = pSh->GetViewOptions()->IsPDFExport() || comphelper::LibreOfficeKit::isActive();
2021 
2022  // #i12836# enhanced pdf
2023  SwRegionRects aRegion( !bIgnoreVisArea ?
2024  pSh->VisArea() :
2025  getFrameArea() );
2026  if( !pStartPos->nNode.GetNode().IsContentNode() ||
2027  !pStartPos->nNode.GetNode().GetContentNode()->getLayoutFrame(this) ||
2028  ( pStartPos->nNode != pEndPos->nNode &&
2029  ( !pEndPos->nNode.GetNode().IsContentNode() ||
2030  !pEndPos->nNode.GetNode().GetContentNode()->getLayoutFrame(this) ) ) )
2031  {
2032  return;
2033  }
2034 
2035  DisableCallbackAction a(*this); // the GetCharRect below may format
2036 
2037  //First obtain the ContentFrames for the start and the end - those are needed
2038  //anyway.
2039  std::pair<Point, bool> tmp(rCursor.GetSttPos(), true);
2040  SwContentFrame* pStartFrame = pStartPos->nNode.GetNode().
2041  GetContentNode()->getLayoutFrame(this, pStartPos, &tmp);
2042 
2043  tmp.first = rCursor.GetEndPos();
2044  SwContentFrame* pEndFrame = pEndPos->nNode.GetNode().
2045  GetContentNode()->getLayoutFrame(this, pEndPos, &tmp);
2046 
2047  assert(pStartFrame && pEndFrame && "No ContentFrames found.");
2048  //tdf#119224 start and end are expected to exist for the scope of this function
2049  SwFrameDeleteGuard aStartFrameGuard(pStartFrame), aEndFrameGuard(pEndFrame);
2050 
2051  //Do not subtract the FlyFrames in which selected Frames lie.
2052  SwSortedObjs aSortObjs;
2053  if ( pStartFrame->IsInFly() )
2054  {
2055  const SwAnchoredObject* pObj = pStartFrame->FindFlyFrame();
2056  OSL_ENSURE( pObj, "No Start Object." );
2057  if (pObj) aSortObjs.Insert( *const_cast<SwAnchoredObject*>(pObj) );
2058  const SwAnchoredObject* pObj2 = pEndFrame->FindFlyFrame();
2059  OSL_ENSURE( pObj2, "SwRootFrame::CalcFrameRects(..) - FlyFrame missing - looks like an invalid selection" );
2060  if ( pObj2 != nullptr && pObj2 != pObj )
2061  {
2062  aSortObjs.Insert( *const_cast<SwAnchoredObject*>(pObj2) );
2063  }
2064  }
2065 
2066  // if a selection which is not allowed exists, we correct what is not
2067  // allowed (header/footer/table-headline) for two pages.
2068  do { // middle check loop
2069  const SwLayoutFrame* pSttLFrame = pStartFrame->GetUpper();
2071  while( pSttLFrame &&
2072  ! (cHdFtTableHd & pSttLFrame->GetType() ))
2073  pSttLFrame = pSttLFrame->GetUpper();
2074  if( !pSttLFrame )
2075  break;
2076  const SwLayoutFrame* pEndLFrame = pEndFrame->GetUpper();
2077  while( pEndLFrame &&
2078  ! (cHdFtTableHd & pEndLFrame->GetType() ))
2079  pEndLFrame = pEndLFrame->GetUpper();
2080  if( !pEndLFrame )
2081  break;
2082 
2083  OSL_ENSURE( pEndLFrame->GetType() == pSttLFrame->GetType(),
2084  "Selection over different content" );
2085  switch( pSttLFrame->GetType() )
2086  {
2087  case SwFrameType::Header:
2088  case SwFrameType::Footer:
2089  // On different pages? Then always on the start-page
2090  if( pEndLFrame->FindPageFrame() != pSttLFrame->FindPageFrame() )
2091  {
2092  // Set end- to the start-ContentFrame
2093  if( pStartPos == rCursor.GetPoint() )
2094  pEndFrame = pStartFrame;
2095  else
2096  pStartFrame = pEndFrame;
2097  }
2098  break;
2099  case SwFrameType::Tab:
2100  // On different pages? Then check for table-headline
2101  {
2102  const SwTabFrame* pTabFrame = static_cast<const SwTabFrame*>(pSttLFrame);
2103  if( ( pTabFrame->GetFollow() ||
2104  static_cast<const SwTabFrame*>(pEndLFrame)->GetFollow() ) &&
2105  pTabFrame->GetTable()->GetRowsToRepeat() > 0 &&
2106  pTabFrame->GetLower() != static_cast<const SwTabFrame*>(pEndLFrame)->GetLower() &&
2107  ( lcl_IsInRepeatedHeadline( pStartFrame ) ||
2108  lcl_IsInRepeatedHeadline( pEndFrame ) ) )
2109  {
2110  // Set end- to the start-ContentFrame
2111  if( pStartPos == rCursor.GetPoint() )
2112  pEndFrame = pStartFrame;
2113  else
2114  pStartFrame = pEndFrame;
2115  }
2116  }
2117  break;
2118  default: break;
2119  }
2120  } while( false );
2121 
2122  SwCursorMoveState aTmpState( MV_NONE );
2123  aTmpState.m_b2Lines = true;
2124  aTmpState.m_bNoScroll = true;
2125  aTmpState.m_nCursorBidiLevel = pStartFrame->IsRightToLeft() ? 1 : 0;
2126 
2127  //ContentRects to Start- and EndFrames.
2128  SwRect aStRect, aEndRect;
2129  pStartFrame->GetCharRect( aStRect, *pStartPos, &aTmpState );
2130  std::unique_ptr<Sw2LinesPos> pSt2Pos = std::move(aTmpState.m_p2Lines);
2131  aTmpState.m_nCursorBidiLevel = pEndFrame->IsRightToLeft() ? 1 : 0;
2132 
2133  pEndFrame->GetCharRect( aEndRect, *pEndPos, &aTmpState );
2134  std::unique_ptr<Sw2LinesPos> pEnd2Pos = std::move(aTmpState.m_p2Lines);
2135 
2136  SwRect aStFrame ( pStartFrame->UnionFrame( true ) );
2137  aStFrame.Intersection( pStartFrame->GetPaintArea() );
2138  SwRect aEndFrame( pStartFrame == pEndFrame ? aStFrame : pEndFrame->UnionFrame( true ) );
2139  if( pStartFrame != pEndFrame )
2140  {
2141  aEndFrame.Intersection( pEndFrame->GetPaintArea() );
2142  }
2143  SwRectFnSet aRectFnSet(pStartFrame);
2144  const bool bR2L = pStartFrame->IsRightToLeft();
2145  const bool bEndR2L = pEndFrame->IsRightToLeft();
2146  const bool bB2T = pStartFrame->IsVertLRBT();
2147 
2148  // If there's no doubleline portion involved or start and end are both
2149  // in the same doubleline portion, all works fine, but otherwise
2150  // we need the following...
2151  if( pSt2Pos != pEnd2Pos && ( !pSt2Pos || !pEnd2Pos ||
2152  pSt2Pos->aPortion != pEnd2Pos->aPortion ) )
2153  {
2154  // If we have a start(end) position inside a doubleline portion
2155  // the surrounded part of the doubleline portion is subtracted
2156  // from the region and the aStRect(aEndRect) is set to the
2157  // end(start) of the doubleline portion.
2158  if( pSt2Pos )
2159  {
2160  SwRect aTmp( aStRect );
2161 
2162  // BiDi-Portions are swimming against the current.
2163  const bool bPorR2L = ( MultiPortionType::BIDI == pSt2Pos->nMultiType ) ?
2164  ! bR2L :
2165  bR2L;
2166 
2167  if( MultiPortionType::BIDI == pSt2Pos->nMultiType &&
2168  aRectFnSet.GetWidth(pSt2Pos->aPortion2) )
2169  {
2170  // nested bidi portion
2171  long nRightAbs = aRectFnSet.GetRight(pSt2Pos->aPortion);
2172  nRightAbs -= aRectFnSet.GetLeft(pSt2Pos->aPortion2);
2173  long nLeftAbs = nRightAbs - aRectFnSet.GetWidth(pSt2Pos->aPortion2);
2174 
2175  aRectFnSet.SetRight( aTmp, nRightAbs );
2176 
2177  if ( ! pEnd2Pos || pEnd2Pos->aPortion != pSt2Pos->aPortion )
2178  {
2179  SwRect aTmp2( pSt2Pos->aPortion );
2180  aRectFnSet.SetRight( aTmp2, nLeftAbs );
2181  aTmp2.Intersection( aEndFrame );
2182  Sub( aRegion, aTmp2 );
2183  }
2184  }
2185  else
2186  {
2187  if( bPorR2L )
2188  aRectFnSet.SetLeft( aTmp, aRectFnSet.GetLeft(pSt2Pos->aPortion) );
2189  else
2190  aRectFnSet.SetRight( aTmp, aRectFnSet.GetRight(pSt2Pos->aPortion) );
2191  }
2192 
2193  if( MultiPortionType::ROT_90 == pSt2Pos->nMultiType ||
2194  aRectFnSet.GetTop(pSt2Pos->aPortion) ==
2195  aRectFnSet.GetTop(aTmp) )
2196  {
2197  aRectFnSet.SetTop( aTmp, aRectFnSet.GetTop(pSt2Pos->aLine) );
2198  }
2199 
2200  aTmp.Intersection( aStFrame );
2201  Sub( aRegion, aTmp );
2202 
2203  SwTwips nTmp = aRectFnSet.GetBottom(pSt2Pos->aLine);
2204  if( MultiPortionType::ROT_90 != pSt2Pos->nMultiType &&
2205  aRectFnSet.BottomDist( aStRect, nTmp ) > 0 )
2206  {
2207  aRectFnSet.SetTop( aTmp, aRectFnSet.GetBottom(aTmp) );
2208  aRectFnSet.SetBottom( aTmp, nTmp );
2209  if( aRectFnSet.BottomDist( aStRect, aRectFnSet.GetBottom(pSt2Pos->aPortion) ) > 0 )
2210  {
2211  if( bPorR2L )
2212  aRectFnSet.SetRight( aTmp, aRectFnSet.GetRight(pSt2Pos->aPortion) );
2213  else
2214  aRectFnSet.SetLeft( aTmp, aRectFnSet.GetLeft(pSt2Pos->aPortion) );
2215  }
2216  aTmp.Intersection( aStFrame );
2217  Sub( aRegion, aTmp );
2218  }
2219 
2220  aStRect = pSt2Pos->aLine;
2221  aRectFnSet.SetLeft( aStRect, bR2L ?
2222  aRectFnSet.GetLeft(pSt2Pos->aPortion) :
2223  aRectFnSet.GetRight(pSt2Pos->aPortion) );
2224  aRectFnSet.SetWidth( aStRect, 1 );
2225  }
2226 
2227  if( pEnd2Pos )
2228  {
2229  SwRectFnSet fnRectX(pEndFrame);
2230  SwRect aTmp( aEndRect );
2231 
2232  // BiDi-Portions are swimming against the current.
2233  const bool bPorR2L = ( MultiPortionType::BIDI == pEnd2Pos->nMultiType ) ?
2234  ! bEndR2L :
2235  bEndR2L;
2236 
2237  if( MultiPortionType::BIDI == pEnd2Pos->nMultiType &&
2238  fnRectX.GetWidth(pEnd2Pos->aPortion2) )
2239  {
2240  // nested bidi portion
2241  long nRightAbs = fnRectX.GetRight(pEnd2Pos->aPortion);
2242  nRightAbs = nRightAbs - fnRectX.GetLeft(pEnd2Pos->aPortion2);
2243  long nLeftAbs = nRightAbs - fnRectX.GetWidth(pEnd2Pos->aPortion2);
2244 
2245  fnRectX.SetLeft( aTmp, nLeftAbs );
2246 
2247  if ( ! pSt2Pos || pSt2Pos->aPortion != pEnd2Pos->aPortion )
2248  {
2249  SwRect aTmp2( pEnd2Pos->aPortion );
2250  fnRectX.SetLeft( aTmp2, nRightAbs );
2251  aTmp2.Intersection( aEndFrame );
2252  Sub( aRegion, aTmp2 );
2253  }
2254  }
2255  else
2256  {
2257  if ( bPorR2L )
2258  fnRectX.SetRight( aTmp, fnRectX.GetRight(pEnd2Pos->aPortion) );
2259  else
2260  fnRectX.SetLeft( aTmp, fnRectX.GetLeft(pEnd2Pos->aPortion) );
2261  }
2262 
2263  if( MultiPortionType::ROT_90 == pEnd2Pos->nMultiType ||
2264  fnRectX.GetBottom(pEnd2Pos->aPortion) ==
2265  fnRectX.GetBottom(aEndRect) )
2266  {
2267  fnRectX.SetBottom( aTmp, fnRectX.GetBottom(pEnd2Pos->aLine) );
2268  }
2269 
2270  aTmp.Intersection( aEndFrame );
2271  Sub( aRegion, aTmp );
2272 
2273  // The next statement means neither ruby nor rotate(90):
2274  if( MultiPortionType::RUBY != pEnd2Pos->nMultiType && MultiPortionType::ROT_90 != pEnd2Pos->nMultiType )
2275  {
2276  SwTwips nTmp = fnRectX.GetTop(pEnd2Pos->aLine);
2277  if( fnRectX.GetTop(aEndRect) != nTmp )
2278  {
2279  fnRectX.SetBottom( aTmp, fnRectX.GetTop(aTmp) );
2280  fnRectX.SetTop( aTmp, nTmp );
2281  if( fnRectX.GetTop(aEndRect) !=
2282  fnRectX.GetTop(pEnd2Pos->aPortion) )
2283  {
2284  if( bPorR2L )
2285  fnRectX.SetLeft( aTmp, fnRectX.GetLeft(pEnd2Pos->aPortion) );
2286  else
2287  fnRectX.SetRight( aTmp, fnRectX.GetRight(pEnd2Pos->aPortion) );
2288  }
2289  aTmp.Intersection( aEndFrame );
2290  Sub( aRegion, aTmp );
2291  }
2292  }
2293 
2294  aEndRect = pEnd2Pos->aLine;
2295  fnRectX.SetLeft( aEndRect, bEndR2L ?
2296  fnRectX.GetRight(pEnd2Pos->aPortion) :
2297  fnRectX.GetLeft(pEnd2Pos->aPortion) );
2298  fnRectX.SetWidth( aEndRect, 1 );
2299  }
2300  }
2301  else if( pSt2Pos && pEnd2Pos &&
2302  MultiPortionType::BIDI == pSt2Pos->nMultiType &&
2303  MultiPortionType::BIDI == pEnd2Pos->nMultiType &&
2304  pSt2Pos->aPortion == pEnd2Pos->aPortion &&
2305  pSt2Pos->aPortion2 != pEnd2Pos->aPortion2 )
2306  {
2307  // This is the ugly special case, where the selection starts and
2308  // ends in the same bidi portion but one start or end is inside a
2309  // nested bidi portion.
2310 
2311  if ( aRectFnSet.GetWidth(pSt2Pos->aPortion2) )
2312  {
2313  SwRect aTmp( aStRect );
2314  long nRightAbs = aRectFnSet.GetRight(pSt2Pos->aPortion);
2315  nRightAbs -= aRectFnSet.GetLeft(pSt2Pos->aPortion2);
2316  long nLeftAbs = nRightAbs - aRectFnSet.GetWidth(pSt2Pos->aPortion2);
2317 
2318  aRectFnSet.SetRight( aTmp, nRightAbs );
2319  aTmp.Intersection( aStFrame );
2320  Sub( aRegion, aTmp );
2321 
2322  aStRect = pSt2Pos->aLine;
2323  aRectFnSet.SetLeft( aStRect, bR2L ? nRightAbs : nLeftAbs );
2324  aRectFnSet.SetWidth( aStRect, 1 );
2325  }
2326 
2327  SwRectFnSet fnRectX(pEndFrame);
2328  if ( fnRectX.GetWidth(pEnd2Pos->aPortion2) )
2329  {
2330  SwRect aTmp( aEndRect );
2331  long nRightAbs = fnRectX.GetRight(pEnd2Pos->aPortion);
2332  nRightAbs -= fnRectX.GetLeft(pEnd2Pos->aPortion2);
2333  long nLeftAbs = nRightAbs - fnRectX.GetWidth(pEnd2Pos->aPortion2);
2334 
2335  fnRectX.SetLeft( aTmp, nLeftAbs );
2336  aTmp.Intersection( aEndFrame );
2337  Sub( aRegion, aTmp );
2338 
2339  aEndRect = pEnd2Pos->aLine;
2340  fnRectX.SetLeft( aEndRect, bEndR2L ? nLeftAbs : nRightAbs );
2341  fnRectX.SetWidth( aEndRect, 1 );
2342  }
2343  }
2344 
2345  // The charrect may be outside the paintarea (for cursortravelling)
2346  // but the selection has to be restricted to the paintarea
2347  if( aStRect.Left() < aStFrame.Left() )
2348  aStRect.Left( aStFrame.Left() );
2349  else if( aStRect.Left() > aStFrame.Right() )
2350  aStRect.Left( aStFrame.Right() );
2351  SwTwips nTmp = aStRect.Right();
2352  if( nTmp < aStFrame.Left() )
2353  aStRect.Right( aStFrame.Left() );
2354  else if( nTmp > aStFrame.Right() )
2355  aStRect.Right( aStFrame.Right() );
2356  if( aEndRect.Left() < aEndFrame.Left() )
2357  aEndRect.Left( aEndFrame.Left() );
2358  else if( aEndRect.Left() > aEndFrame.Right() )
2359  aEndRect.Left( aEndFrame.Right() );
2360  nTmp = aEndRect.Right();
2361  if( nTmp < aEndFrame.Left() )
2362  aEndRect.Right( aEndFrame.Left() );
2363  else if( nTmp > aEndFrame.Right() )
2364  aEndRect.Right( aEndFrame.Right() );
2365 
2366  if( pStartFrame == pEndFrame )
2367  {
2368  bool bSameRotatedOrBidi = pSt2Pos && pEnd2Pos &&
2369  ( MultiPortionType::BIDI == pSt2Pos->nMultiType ||
2370  MultiPortionType::ROT_270 == pSt2Pos->nMultiType ||
2371  MultiPortionType::ROT_90 == pSt2Pos->nMultiType ) &&
2372  pSt2Pos->aPortion == pEnd2Pos->aPortion;
2373  //case 1: (Same frame and same row)
2374  if( bSameRotatedOrBidi ||
2375  aRectFnSet.GetTop(aStRect) == aRectFnSet.GetTop(aEndRect) )
2376  {
2377  Point aTmpSt( aStRect.Pos() );
2378  Point aTmpEnd( aEndRect.Right(), aEndRect.Bottom() );
2379  if (bSameRotatedOrBidi || bR2L || bB2T)
2380  {
2381  if( aTmpSt.Y() > aTmpEnd.Y() )
2382  {
2383  long nTmpY = aTmpEnd.Y();
2384  aTmpEnd.setY( aTmpSt.Y() );
2385  aTmpSt.setY( nTmpY );
2386  }
2387  if( aTmpSt.X() > aTmpEnd.X() )
2388  {
2389  long nTmpX = aTmpEnd.X();
2390  aTmpEnd.setX( aTmpSt.X() );
2391  aTmpSt.setX( nTmpX );
2392  }
2393  }
2394 
2395  SwRect aTmp( aTmpSt, aTmpEnd );
2396  // Bug 34888: If content is selected which doesn't take space
2397  // away (i.e. PostIts, RefMarks, TOXMarks), then at
2398  // least set the width of the Cursor.
2399  if( 1 == aRectFnSet.GetWidth(aTmp) &&
2400  pStartPos->nContent.GetIndex() !=
2401  pEndPos->nContent.GetIndex() )
2402  {
2403  OutputDevice* pOut = pSh->GetOut();
2404  long nCursorWidth = pOut->GetSettings().GetStyleSettings().
2405  GetCursorSize();
2406  aRectFnSet.SetWidth( aTmp, pOut->PixelToLogic(
2407  Size( nCursorWidth, 0 ) ).Width() );
2408  }
2409  aTmp.Intersection( aStFrame );
2410  Sub( aRegion, aTmp );
2411  }
2412  //case 2: (Same frame, but not the same line)
2413  else
2414  {
2415  SwTwips lLeft, lRight;
2416  if( pSt2Pos && pEnd2Pos && pSt2Pos->aPortion == pEnd2Pos->aPortion )
2417  {
2418  lLeft = aRectFnSet.GetLeft(pSt2Pos->aPortion);
2419  lRight = aRectFnSet.GetRight(pSt2Pos->aPortion);
2420  }
2421  else
2422  {
2423  lLeft = aRectFnSet.GetLeft(pStartFrame->getFrameArea()) +
2424  aRectFnSet.GetLeft(pStartFrame->getFramePrintArea());
2425  lRight = aRectFnSet.GetRight(aEndFrame);
2426  }
2427  if( lLeft < aRectFnSet.GetLeft(aStFrame) )
2428  lLeft = aRectFnSet.GetLeft(aStFrame);
2429  if( lRight > aRectFnSet.GetRight(aStFrame) )
2430  lRight = aRectFnSet.GetRight(aStFrame);
2431  SwRect aSubRect( aStRect );
2432  //First line
2433  if( bR2L )
2434  aRectFnSet.SetLeft( aSubRect, lLeft );
2435  else
2436  aRectFnSet.SetRight( aSubRect, lRight );
2437  Sub( aRegion, aSubRect );
2438 
2439  //If there's at least a twips between start- and endline,
2440  //so the whole area between will be added.
2441  SwTwips aTmpBottom = aRectFnSet.GetBottom(aStRect);
2442  SwTwips aTmpTop = aRectFnSet.GetTop(aEndRect);
2443  if( aTmpBottom != aTmpTop )
2444  {
2445  aRectFnSet.SetLeft( aSubRect, lLeft );
2446  aRectFnSet.SetRight( aSubRect, lRight );
2447  aRectFnSet.SetTop( aSubRect, aTmpBottom );
2448  aRectFnSet.SetBottom( aSubRect, aTmpTop );
2449  Sub( aRegion, aSubRect );
2450  }
2451  //and the last line
2452  aSubRect = aEndRect;
2453  if( bR2L )
2454  aRectFnSet.SetRight( aSubRect, lRight );
2455  else
2456  aRectFnSet.SetLeft( aSubRect, lLeft );
2457  Sub( aRegion, aSubRect );
2458  }
2459  }
2460  //case 3: (Different frames, maybe with other frames between)
2461  else
2462  {
2463  //The startframe first...
2464  SwRect aSubRect( aStRect );
2465  if( bR2L )
2466  aRectFnSet.SetLeft( aSubRect, aRectFnSet.GetLeft(aStFrame));
2467  else
2468  aRectFnSet.SetRight( aSubRect, aRectFnSet.GetRight(aStFrame));
2469  Sub( aRegion, aSubRect );
2470  SwTwips nTmpTwips = aRectFnSet.GetBottom(aStRect);
2471  if( aRectFnSet.GetBottom(aStFrame) != nTmpTwips )
2472  {
2473  aSubRect = aStFrame;
2474  aRectFnSet.SetTop( aSubRect, nTmpTwips );
2475  Sub( aRegion, aSubRect );
2476  }
2477 
2478  //Now the frames between, if there are any
2479  bool const bBody = pStartFrame->IsInDocBody();
2480  const SwTableBox* pCellBox = pStartFrame->GetUpper()->IsCellFrame() ?
2481  static_cast<const SwCellFrame*>(pStartFrame->GetUpper())->GetTabBox() : nullptr;
2482  if (pSh->IsSelectAll())
2483  pCellBox = nullptr;
2484 
2485  const SwContentFrame *pContent = pStartFrame->GetNextContentFrame();
2486  SwRect aPrvRect;
2487 
2488  OSL_ENSURE( pContent,
2489  "<SwRootFrame::CalcFrameRects(..)> - no content frame. This is a serious defect" );
2490  while ( pContent && pContent != pEndFrame )
2491  {
2492  if ( pContent->IsInFly() )
2493  {
2494  const SwAnchoredObject* pObj = pContent->FindFlyFrame();
2495  if (!aSortObjs.Contains(*pObj))
2496  { // is this even possible, assuming valid cursor pos.?
2497  aSortObjs.Insert( *const_cast<SwAnchoredObject*>(pObj) );
2498  }
2499  }
2500 
2501  // Consider only frames which have the same IsInDocBody value like pStartFrame
2502  // If pStartFrame is inside a SwCellFrame, consider only frames which are inside the
2503  // same cell frame (or its follow cell)
2504  const SwTableBox* pTmpCellBox = pContent->GetUpper()->IsCellFrame() ?
2505  static_cast<const SwCellFrame*>(pContent->GetUpper())->GetTabBox() : nullptr;
2506  if (pSh->IsSelectAll())
2507  pTmpCellBox = nullptr;
2508  if ( bBody == pContent->IsInDocBody() &&
2509  ( !pCellBox || pCellBox == pTmpCellBox ) )
2510  {
2511  SwRect aCRect( pContent->UnionFrame( true ) );
2512  aCRect.Intersection( pContent->GetPaintArea() );
2513  if( aCRect.IsOver( aRegion.GetOrigin() ))
2514  {
2515  SwRect aTmp( aPrvRect );
2516  aTmp.Union( aCRect );
2517  if ( (aPrvRect.Height() * aPrvRect.Width() +
2518  aCRect.Height() * aCRect.Width()) ==
2519  (aTmp.Height() * aTmp.Width()) )
2520  {
2521  aPrvRect.Union( aCRect );
2522  }
2523  else
2524  {
2525  if ( aPrvRect.HasArea() )
2526  Sub( aRegion, aPrvRect );
2527  aPrvRect = aCRect;
2528  }
2529  }
2530  }
2531  pContent = pContent->GetNextContentFrame();
2532  OSL_ENSURE( pContent,
2533  "<SwRootFrame::CalcFrameRects(..)> - no content frame. This is a serious defect!" );
2534  }
2535  if ( aPrvRect.HasArea() )
2536  Sub( aRegion, aPrvRect );
2537 
2538  //At least the endframe...
2539  aRectFnSet.Refresh(pEndFrame);
2540  nTmpTwips = aRectFnSet.GetTop(aEndRect);
2541  if( aRectFnSet.GetTop(aEndFrame) != nTmpTwips )
2542  {
2543  aSubRect = aEndFrame;
2544  aRectFnSet.SetBottom( aSubRect, nTmpTwips );
2545  Sub( aRegion, aSubRect );
2546  }
2547  aSubRect = aEndRect;
2548  if( bEndR2L )
2549  aRectFnSet.SetRight(aSubRect, aRectFnSet.GetRight(aEndFrame));
2550  else
2551  aRectFnSet.SetLeft( aSubRect, aRectFnSet.GetLeft(aEndFrame) );
2552  Sub( aRegion, aSubRect );
2553  }
2554 
2555  aRegion.Invert();
2556  pSt2Pos.reset();
2557  pEnd2Pos.reset();
2558 
2559  // Cut out Flys during loop. We don't cut out Flys when:
2560  // - the Lower is StartFrame/EndFrame (FlyInCnt and all other Flys which again
2561  // sit in it)
2562  // - if in the Z-order we have Flys above those in which the StartFrame is
2563  // placed
2564  // - if they are anchored to inside the selection and thus part of it
2565  const SwPageFrame *pPage = pStartFrame->FindPageFrame();
2566  const SwPageFrame *pEndPage = pEndFrame->FindPageFrame();
2567 
2568  while ( pPage )
2569  {
2570  if ( pPage->GetSortedObjs() )
2571  {
2572  const SwSortedObjs &rObjs = *pPage->GetSortedObjs();
2573  for (SwAnchoredObject* pAnchoredObj : rObjs)
2574  {
2575  if ( dynamic_cast< const SwFlyFrame *>( pAnchoredObj ) == nullptr )
2576  continue;
2577  const SwFlyFrame* pFly = static_cast<const SwFlyFrame*>(pAnchoredObj);
2578  const SwVirtFlyDrawObj* pObj = pFly->GetVirtDrawObj();
2579  const SwFormatSurround &rSur = pFly->GetFormat()->GetSurround();
2580  SwFormatAnchor const& rAnchor(pAnchoredObj->GetFrameFormat().GetAnchor());
2581  const SwPosition* anchoredAt = rAnchor.GetContentAnchor();
2582  bool inSelection = (
2583  anchoredAt != nullptr
2584  && ( (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR
2585  && IsDestroyFrameAnchoredAtChar(*anchoredAt, *pStartPos, *pEndPos))
2586  || (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA
2587  && IsSelectFrameAnchoredAtPara(*anchoredAt, *pStartPos, *pEndPos))));
2588  if( inSelection )
2589  Add( aRegion, pFly->getFrameArea() );
2590  else if ( !pFly->IsAnLower( pStartFrame ) &&
2591  (rSur.GetSurround() != css::text::WrapTextMode_THROUGH &&
2592  !rSur.IsContour()) )
2593  {
2594  if ( aSortObjs.Contains( *pAnchoredObj ) )
2595  continue;
2596 
2597  bool bSub = true;
2598  const sal_uInt32 nPos = pObj->GetOrdNum();
2599  for ( size_t k = 0; bSub && k < aSortObjs.size(); ++k )
2600  {
2601  OSL_ENSURE( dynamic_cast< const SwFlyFrame *>( aSortObjs[k] ) != nullptr,
2602  "<SwRootFrame::CalcFrameRects(..)> - object in <aSortObjs> of unexpected type" );
2603  const SwFlyFrame* pTmp = static_cast<SwFlyFrame*>(aSortObjs[k]);
2604  do
2605  {
2606  if ( nPos < pTmp->GetVirtDrawObj()->GetOrdNumDirect() )
2607  {
2608  bSub = false;
2609  }
2610  else
2611  {
2612  pTmp = pTmp->GetAnchorFrame()->FindFlyFrame();
2613  }
2614  } while ( bSub && pTmp );
2615  }
2616  if ( bSub )
2617  Sub( aRegion, pFly->getFrameArea() );
2618  }
2619  }
2620  }
2621  if ( pPage == pEndPage )
2622  break;
2623  else
2624  pPage = static_cast<const SwPageFrame*>(pPage->GetNext());
2625  }
2626 
2627  //Because it looks better, we close the DropCaps.
2628  SwRect aDropRect;
2629  if ( pStartFrame->IsTextFrame() )
2630  {
2631  if ( static_cast<const SwTextFrame*>(pStartFrame)->GetDropRect( aDropRect ) )
2632  Sub( aRegion, aDropRect );
2633  }
2634  if ( pEndFrame != pStartFrame && pEndFrame->IsTextFrame() )
2635  {
2636  if ( static_cast<const SwTextFrame*>(pEndFrame)->GetDropRect( aDropRect ) )
2637  Sub( aRegion, aDropRect );
2638  }
2639 
2640  rCursor.assign( aRegion.begin(), aRegion.end() );
2641 }
2642 
2643 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual bool GetCursorOfst(SwPosition *, Point &, SwCursorMoveState *=nullptr, bool bTestBackground=false) const override
Primary passes the call to the first page.
Definition: trvlfrm.cxx:423
bool IsAnLower(const SwFrame *) const
Definition: findfrm.cxx:206
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:341
bool IsContour() const
Definition: fmtsrnd.hxx:53
const SwVirtFlyDrawObj * GetVirtDrawObj() const
Definition: fly.cxx:2721
Base class of the Writer layout elements.
Definition: frame.hxx:295
Base class that provides the general functionalities for frames that are allowed at page breaks (flow...
Definition: flowfrm.hxx:58
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:149
virtual sal_Int32 Len() const
Definition: node.cxx:1180
long BottomDist(const SwRect &rRect, long nPos) const
Definition: frame.hxx:1390
const SdrObject * Next()
Definition: frmtool.cxx:2520
sal_uLong GetIndex() const
Definition: node.hxx:282
SwNode & GetNode(bool bPoint=true) const
Definition: pam.hxx:223
bool IsFollow() const
Definition: flowfrm.hxx:166
virtual bool RightMargin(SwPaM *, bool bAPI=false) const override
Definition: trvlfrm.cxx:624
virtual const SwFlyFrameFormat * GetFormat() const override
Definition: fly.cxx:2810
void SetCallbackActionEnabled(bool b)
Definition: rootfrm.hxx:381
void GetContentPosition(const Point &rPt, SwPosition &rPos) const
Same as SwLayoutFrame::GetContentPos().
Definition: trvlfrm.cxx:1379
Marks a position in the document model.
Definition: pam.hxx:35
const SwRect & GetOrigin() const
Definition: swregion.hxx:47
SwContentFrame * GetNextContentFrame() const
Definition: cntfrm.hxx:98
const SwField * GetField() const
Definition: fmtfld.hxx:70
SwContentNode * GetNode(SwPaM &rPam, bool &rbFirst, SwMoveFnCollection const &fnMove, bool const bInReadOnly, SwRootFrame const *const i_pLayout)
This function returns the next node in direction of search.
Definition: pam.cxx:768
bool IsInDocBody() const
Definition: frame.hxx:919
static bool lcl_IsInRepeatedHeadline(const SwFrame *pFrame, const SwTabFrame **ppTFrame=nullptr)
Frame in repeated headline?
Definition: trvlfrm.cxx:646
const SwPageFrame * GetPageAtPos(const Point &rPt, const Size *pSize=nullptr, bool bExtend=false) const
Point rPt: The point that should be used to find the page Size pSize: If given, we return the (first)...
Definition: findfrm.cxx:572
bool IsInFly() const
Definition: frame.hxx:937
SwRect & Union(const SwRect &rRect)
Definition: swrect.cxx:39
Pagedescriptor Client of SwPageDesc that is "described" by the attribute.
Definition: fmtpdsc.hxx:35
SwPageDesc * GetPageDesc()
Definition: fmtpdsc.hxx:62
virtual bool get(DocumentSettingId id) const override
Return the specified document setting.
sal_uInt16 GetCurrPage(const SwPaM *) const
Query/set the current Page and the collective Page count We'll format as much as necessary.
Definition: trvlfrm.cxx:979
static bool more(const double &rfValA, const double &rfValB)
stay with the cursor inside text
Definition: crstate.hxx:127
const SwTable * GetTable() const
Definition: tabfrm.hxx:144
SwNodeIndex nNode
Definition: pam.hxx:37
void Refresh(const SwFrame *pFrame)
Definition: frame.hxx:1335
bool IsInFootnote() const
Definition: frame.hxx:925
sal_uInt16 char char * pDesc
SwFrameType GetType() const
Definition: frame.hxx:498
default
Definition: crstate.hxx:123
SwLayoutFrame * GetPrevFrame(const SwLayoutFrame *pFrame)
Definition: trvlfrm.cxx:1076
const SwRect & getFramePrintArea() const
Definition: frame.hxx:176
const StyleSettings & GetStyleSettings() const
const SwPosition * GetMark() const
Definition: pam.hxx:209
Base class of all fields.
Definition: fldbas.hxx:280
SwTabFrame is one table in the document layout, containing rows (which contain cells).
Definition: tabfrm.hxx:30
sal_uInt8 m_nCursorBidiLevel
Definition: crstate.hxx:139
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1147
Definition: doc.hxx:185
helper class to disable creation of an action by a callback event in particular, change event from a ...
Definition: rootfrm.hxx:440
static SwContentNode * GetContentNode(SwDoc *pDoc, SwNodeIndex &rIdx, bool bNext)
Definition: fltshell.cxx:53
bool m_bSetInReadOnly
ReadOnly areas may be entered.
Definition: crstate.hxx:148
void Height(long nNew)
Definition: swrect.hxx:189
long GetBottom(const SwRect &rRect) const
Definition: frame.hxx:1354
const Point & GetSttPos() const
Definition: viscrs.hxx:146
bool m_bExactOnly
let GetCursorOfst look for exact matches only, i.e.
Definition: crstate.hxx:145
SwNode & GetNode() const
Definition: ndindex.hxx:119
long SwTwips
Definition: swtypes.hxx:49
bool IsSelectFrameAnchoredAtPara(SwPosition const &rAnchorPos, SwPosition const &rStart, SwPosition const &rEnd, DelContentType const nDelContentType)
is a fly anchored at paragraph at rAnchorPos selected?
Definition: undobj.cxx:1583
This class is used as parameter for creation of a block cursor selection.
bool IsVert() const
Definition: frame.hxx:1343
sal_uInt16 GetRowsToRepeat() const
Definition: swtable.hxx:193
void Pos(const Point &rNew)
Definition: swrect.hxx:167
virtual void Calc(vcl::RenderContext *pRenderContext) const
Definition: trvlfrm.cxx:1791
bool IsCellFrame() const
Definition: frame.hxx:1202
bool IsFootnotePage() const
Foot note interface.
Definition: pagefrm.hxx:185
void Top()
Definition: frmtool.cxx:2467
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
SwContentFrame * FindFirstBodyContent()
Definition: pagefrm.hxx:333
const OUString & GetText() const
Returns the text portion we want to edit (for inline see underneath)
Definition: txtfrm.cxx:1280
virtual const SwFormatPageDesc & GetPageDescItem() const
Definition: findfrm.cxx:659
long GetPrtTop(const SwFrame &rFrame) const
Definition: frame.hxx:1385
bool IsDestroyFrameAnchoredAtChar(SwPosition const &rAnchorPos, SwPosition const &rStart, SwPosition const &rEnd, DelContentType const nDelContentType)
will DelContentIndex destroy a frame anchored at character at rAnchorPos?
Definition: undobj.cxx:1546
static SwFlowFrame * CastFlowFrame(SwFrame *pFrame)
Definition: flowfrm.cxx:2615
SwLayoutFrame * GetThisFrame(const SwLayoutFrame *pFrame)
Definition: trvlfrm.cxx:1071
The root element of a Writer document layout.
Definition: rootfrm.hxx:79
SwContact * GetUserCall(const SdrObject *pObj)
Returns the UserCall if applicable from the group object.
Definition: dcontact.cxx:170
virtual bool GetInfo(SfxPoolItem &) const override
Definition: calbck.cxx:206
bool IsFootnoteFrame() const
Definition: frame.hxx:1178
bool isFrameAreaDefinitionValid() const
Definition: frame.hxx:167
static void Sub(SwRegionRects &rRegion, const SwRect &rRect)
Definition: trvlfrm.cxx:1974
SwLayoutFrame * GetNextFrame(const SwLayoutFrame *pFrame)
Definition: trvlfrm.cxx:1059
bool m_bFillRet
only used temporary in FillMode
Definition: crstate.hxx:147
static SwCursorOszControl g_OszCtrl
Definition: trvlfrm.cxx:147
void PrepareMake(vcl::RenderContext *pRenderContext)
Prepares the Frame for "formatting" (MakeAll()).
Definition: calcmove.cxx:241
sal_uInt16 GetPhyPageNum() const
Definition: pagefrm.hxx:190
bool IsSelectAll() const
Definition: viewsh.hxx:568
SwContentNode * GetContentNode(bool bPoint=true) const
Definition: pam.hxx:229
SwTextAttr * GetTextAttrForCharAt(const sal_Int32 nIndex, const sal_uInt16 nWhich=RES_TXTATR_END) const
get the text attribute at position nIndex which owns the dummy character CH_TXTATR_* at that position...
Definition: ndtxt.cxx:3050
long YDiff(long n1, long n2) const
Definition: frame.hxx:1399
SwRect GetPaintArea() const
|* The paintarea is the area, in which the content of a frame is allowed |* to be displayed...
Definition: ssfrm.cxx:581
bool WannaRightPage() const
Decides if the page want to be a rightpage or not.
Definition: trvlfrm.cxx:1709
bool IsFlyFrame() const
Definition: frame.hxx:1186
wrapper class for the positioning of Writer fly frames and drawing objects
long GetPrtBottom(const SwFrame &rFrame) const
Definition: frame.hxx:1386
const SwPageFrame * GetPage() const
Definition: hints.hxx:271
void Top(const long nTop)
Definition: swrect.hxx:202
SwIndex nContent
Definition: pam.hxx:38
const SwRect & getFrameArea() const
Definition: frame.hxx:175
void setX(long nX)
SwFlyFrame * GetPrevLink() const
Definition: flyfrm.hxx:172
bool IsEmptyPage() const
Definition: pagefrm.hxx:143
bool IsInTab() const
Definition: frame.hxx:931
SwRect & Intersection(const SwRect &rRect)
Definition: swrect.cxx:54
virtual bool FillSelection(SwSelectionList &rList, const SwRect &rRect) const override
Definition: trvlfrm.cxx:379
void CalcFrameRects(SwShellCursor &)
Definition: trvlfrm.cxx:2011
bool IsTextFrame() const
Definition: frame.hxx:1210
virtual bool UnitUp(SwPaM *, const SwTwips nOffset, bool bSetInReadOnly) const
Definition: trvlfrm.cxx:964
oslFileHandle & pOut
const SwContentFrame *(* GetNxtPrvCnt)(const SwContentFrame *)
Definition: trvlfrm.cxx:643
bool OnRightPage() const
Definition: frame.hxx:711
const SwFormatSurround & GetSurround(bool=true) const
Definition: fmtsrnd.hxx:66
static const SwContentFrame * lcl_GetNxtCnt(const SwContentFrame *pCnt)
Definition: trvlfrm.cxx:633
bool IsPageBodyFrame() const
Definition: layfrm.hxx:214
const SwFormatField & GetFormatField() const
Definition: txatbase.hxx:191
virtual bool FillSelection(SwSelectionList &rList, const SwRect &rRect) const
Definition: unusedf.cxx:40
SwContentFrame * GetPrevContentFrame() const
Definition: cntfrm.hxx:106
SwFlyFrame * FindFlyFrame()
Definition: frame.hxx:1087
long GetLeft(const SwRect &rRect) const
Definition: frame.hxx:1355
long GetRight(const SwRect &rRect) const
Definition: frame.hxx:1356
void Right(const long nRight)
Definition: swrect.hxx:198
void setY(long nY)
virtual bool UnitDown(SwPaM *, const SwTwips nOffset, bool bSetInReadOnly) const
Definition: trvlfrm.cxx:969
virtual bool LeftMargin(SwPaM *) const override
Layout dependent cursor travelling.
Definition: trvlfrm.cxx:615
SwPageFrame * GetPageByPageNum(sal_uInt16 _nPageNum) const
Get page frame by physical page number looping through the lowers, which are page frame...
Definition: trvlfrm.cxx:1589
void SetBottom(SwRect &rRect, long nNew) const
Definition: frame.hxx:1363
virtual bool GetCharRect(SwRect &, const SwPosition &, SwCursorMoveState *=nullptr, bool bAllowFarAway=true) const
Definition: unusedf.cxx:71
sal_uInt16 GetVirtPageNum() const
Definition: trvlfrm.cxx:1809
bool IsContentNode() const
Definition: node.hxx:628
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
bool FrameContainsNode(SwContentFrame const &rFrame, sal_uLong nNodeIndex)
Definition: txtfrm.cxx:284
Point GetRelPos() const
Definition: trvlfrm.cxx:1799
virtual bool FillSelection(SwSelectionList &rList, const SwRect &rRect) const override
Definition: trvlfrm.cxx:401
void SetWidth(SwRect &rRect, long nNew) const
Definition: frame.hxx:1366
bool IsContentFrame() const
Definition: frame.hxx:1206
void SetTop(SwRect &rRect, long nNew) const
Definition: frame.hxx:1362
double GetLength() const
const SwSortedObjs * GetSortedObjs() const
Definition: pagefrm.hxx:118
#define SAL_MAX_UINT64
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:81
long XInc(long n1, long n2) const
Definition: frame.hxx:1400
const SwRect & VisArea() const
Definition: viewsh.cxx:558
#define FRM_HEADFOOT
Definition: frame.hxx:106
uno_Any a
SwContentFrame * GetLastSub(const SwLayoutFrame *pLayout)
Definition: trvlfrm.cxx:1054
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:131
const SwPosition * GetPoint() const
Definition: pam.hxx:207
long XDiff(long n1, long n2) const
Definition: frame.hxx:1398
SwFrameType
Definition: frame.hxx:72
bool Insert(SwAnchoredObject &_rAnchoredObj)
Definition: sortedobjs.cxx:207
virtual bool IsCoveredCell() const
Definition: tabfrm.cxx:5725
const SwPageDesc & GetPageDesc(const size_t i) const
Definition: doc.hxx:878
static bool lcl_UpDown(SwPaM *pPam, const SwContentFrame *pStart, GetNxtPrvCnt fnNxtPrv, bool bInReadOnly)
Definition: trvlfrm.cxx:689
size_t size() const
Definition: sortedobjs.cxx:42
SwPageFrame * FindPageFrame()
Definition: frame.hxx:658
SwLayoutFrame *(* SwWhichPage)(const SwLayoutFrame *)
Definition: cshtyp.hxx:34
SwFrameFormat * GetLeftFormat(bool const bFirst=false)
Definition: pagedesc.cxx:362
bool IsDummyPage(sal_uInt16 nPageNum) const
Definition: trvlfrm.cxx:1610
bool isEmpty() const
Reports if the list does not contain any text portion.
const SwFrame * Lower() const
Definition: layfrm.hxx:101
SwPageDesc * GetPageDesc()
Definition: pagefrm.hxx:129
SwContentNode * GetContentNode()
Definition: node.hxx:615
FlyAnchors.
Definition: fmtanchr.hxx:34
SwLayoutFrame * GetUpper()
Definition: frame.hxx:656
bool HasArea() const
Definition: swrect.hxx:290
static const SwContentFrame * lcl_MissProtectedFrames(const SwContentFrame *pCnt, GetNxtPrvCnt fnNxtPrv, bool bMissHeadline, bool bInReadOnly, bool bMissFollowFlowLine)
Skip protected table cells. Optionally also skip repeated headlines.
Definition: trvlfrm.cxx:658
bool isFramePrintAreaValid() const
Definition: frame.hxx:164
Marks a character position inside a document model node.
Definition: index.hxx:37
::rtl::Reference< Content > pContent
bool IsRowFrame() const
Definition: frame.hxx:1198
sal_uInt32 GetOrdNum() const
static const SwLayoutFrame * lcl_Inside(const SwContentFrame *pCnt, Point const &rPt)
Check if the point lies inside the page part in which also the ContentFrame lies. ...
Definition: trvlfrm.cxx:1158
not in repeated headlines
Definition: crstate.hxx:128
css::text::WrapTextMode GetSurround() const
Definition: fmtsrnd.hxx:51
SwFrame * GetPrev()
Definition: frame.hxx:655
const Point & GetMkPos() const
Definition: viscrs.hxx:144
bool IsContentProtected() const
const SwRowFrame * IsInFollowFlowRow() const
Definition: findfrm.cxx:1774
void MakeSelUnions(SwSelUnions &rUnions, const SwLayoutFrame *pStart, const SwLayoutFrame *pEnd, const SwTableSearchType eSearchType)
Definition: tblsel.cxx:1763
bool IsPDFExport() const
Definition: viewopt.hxx:378
const AllSettings & GetSettings() const
bool isFrameAreaPositionValid() const
Definition: frame.hxx:162
virtual bool GetCursorOfst(SwPosition *, Point &, SwCursorMoveState *=nullptr, bool bTestBackground=false) const override
Searches the ContentFrame owning the PrtArea containing the point.
Definition: trvlfrm.cxx:150
static sal_uInt64 CalcDiff(const Point &rPt1, const Point &rPt2)
Definition: trvlfrm.cxx:1141
const SwDoc * GetDoc() const
The document is set in SwAttrPool now, therefore you always can access it.
Definition: format.hxx:119
void SSize(const Size &rNew)
Definition: swrect.hxx:176
SwRect UnionFrame(bool bBorder=false) const
|* The unionframe is the framearea (getFrameArea()) of a frame expanded by the |* printarea...
Definition: ssfrm.cxx:676
bool isFrameAreaSizeValid() const
Definition: frame.hxx:163
virtual const SwAnchoredObject * GetAnchoredObj(const SdrObject *_pSdrObj) const =0
virtual bool GetCursorOfst(SwPosition *, Point &, SwCursorMoveState *=nullptr, bool bTestBackground=false) const override
Searches the page containing the searched point.
Definition: trvlfrm.cxx:179
A page of the document layout.
Definition: pagefrm.hxx:40
bool m_bNoScroll
No scrolling of undersized textframes.
Definition: crstate.hxx:151
virtual bool GetCursorOfst(SwPosition *, Point &, SwCursorMoveState *=nullptr, bool bTestBackground=false) const
Definition: unusedf.cxx:46
bool m_b2Lines
Check 2line portions and fill p2Lines.
Definition: crstate.hxx:150
long GetPrtRight(const SwFrame &rFrame) const
Definition: frame.hxx:1388
long X() const
const SwModify * GetDefinedIn() const
Query / set where attribute is anchored.
Definition: fmtpdsc.hxx:69
bool MakeTableCursors(SwTableCursor &)
Calculates the cells included from the current selection.
Definition: trvlfrm.cxx:1863
SwContentFrame * GetFirstSub(const SwLayoutFrame *pLayout)
Definition: trvlfrm.cxx:1049
const SwPosition * Start() const
Definition: pam.hxx:212
std::unique_ptr< Sw2LinesPos > m_p2Lines
for selections inside/around 2line portions
Definition: crstate.hxx:135
Point Center() const
Definition: swrect.cxx:33
bool IsInProtectSect() const
Is node in a protected area?
Definition: node.cxx:408
const SwPageDesc * GetFollow() const
Definition: pagedesc.hxx:246
const SwFrame * GetFrame() const
Definition: hints.hxx:273
const SwCellFrame * FirstCell() const
Calls ContainsAny first to reach the innermost cell.
Definition: findfrm.cxx:112
Point PixelToLogic(const Point &rDevicePt) const
void SetLeft(SwRect &rRect, long nNew) const
Definition: frame.hxx:1364
long GetPrtLeft(const SwFrame &rFrame) const
Definition: frame.hxx:1387
SwFillCursorPos * m_pFill
for automatic filling with tabs etc
Definition: crstate.hxx:134
long GetWidth(const SwRect &rRect) const
Definition: frame.hxx:1357
virtual bool IsReadOnlyAvailable() const
Definition: swcrsr.cxx:147
bool IsLayoutFrame() const
Definition: frame.hxx:1146
void Left(const long nLeft)
Definition: swrect.hxx:193
static void Add(SwRegionRects &rRegion, const SwRect &rRect)
Definition: trvlfrm.cxx:1981
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
void Bottom(const long nBottom)
Definition: swrect.hxx:207
const SwContentNode * GetNode() const
Definition: notxtfrm.hxx:60
SwFlyFrame * GetFlyFrame()
Definition: dflyobj.hxx:130
#define RES_TXTATR_FIELD
Definition: hintids.hxx:244
SwContentFrame * FindLastBodyContent()
Searches the last ContentFrame in BodyText below the page.
Definition: findfrm.cxx:51
SwRowFrame * GetFirstNonHeadlineRow() const
Definition: tabfrm.cxx:5380
SwContentFrame *(* SwPosPage)(const SwLayoutFrame *)
Definition: cshtyp.hxx:38
const SvxOpaqueItem & GetOpaque(bool=true) const
Definition: frmatr.hxx:80
general base class for all free-flowing frames
Definition: flyfrm.hxx:60
bool IsFrameInTableSel(const SwRect &rUnion, const SwFrame *pCell)
Definition: tblsel.cxx:667
sal_uInt16 SetCurrPage(SwCursor *, sal_uInt16 nPageNum)
Returns a PaM which sits at the beginning of the requested page.
Definition: trvlfrm.cxx:995
virtual SwFrameFormat & GetFrameFormat()=0
bool GetFrameInPage(const SwContentFrame *pCnt, SwWhichPage fnWhichPage, SwPosPage fnPosPage, SwPaM *pPam)
Returns the first/last Contentframe (controlled using the parameter fnPosPage) of the current/previou...
Definition: trvlfrm.cxx:1092
sal_uInt16 GetPhyPageNum() const
Definition: trvlfrm.cxx:1692
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:426
void Width(long nNew)
Definition: swrect.hxx:185
std::vector< SwSelUnion > SwSelUnions
Definition: tblsel.hxx:138
virtual bool GetCursorOfst(SwPosition *, Point &, SwCursorMoveState *=nullptr, bool bTestBackground=false) const override
If this is about a Content-carrying cell the Cursor will be force inserted into one of the ContentFra...
Definition: trvlfrm.cxx:470
sal_Int32 GetIndex() const
Definition: index.hxx:95
bool IsInside(const Point &rPOINT) const
Definition: swrect.cxx:107
SwFrameFormat * GetRightFormat(bool const bFirst=false)
Layout uses the following methods to obtain a format in order to be able to create a page...
Definition: pagedesc.cxx:369
bool IsNoTextFrame() const
Definition: frame.hxx:1214
Item2Range GetItemSurrogates(sal_uInt16 nWhich) const
bool IsRightToLeft() const
Definition: frame.hxx:963
::sw::DocumentSettingManager & GetDocumentSettingManager()
Definition: doc.cxx:185
SwTableBox is one table cell in the document model.
Definition: swtable.hxx:386
SwFrame * GetLower()
Definition: findfrm.cxx:169
bool IsPageFrame() const
Definition: frame.hxx:1154
const Point & GetPtPos() const
Definition: viscrs.hxx:142
void SetRight(SwRect &rRect, long nNew) const
Definition: frame.hxx:1365
CursorMoveState m_eState
Definition: crstate.hxx:138
bool m_bPosMatchesBounds
GetCursorOfst should not return the next position if screen position is inside second have of bound r...
Definition: crstate.hxx:152
bool OnFirstPage() const
Definition: trvlfrm.cxx:1763
const SwTabFrame * GetFollow() const
Definition: tabfrm.hxx:243
virtual bool GetCursorOfst(SwPosition *, Point &, SwCursorMoveState *=nullptr, bool bTestBackground=false) const override
Searches the ContentFrame owning the PrtArea containing the point.
Definition: trvlfrm.cxx:538
bool Contains(const SwAnchoredObject &_rAnchoredObj) const
Definition: sortedobjs.cxx:244
const Point & GetEndPos() const
Definition: viscrs.hxx:148
virtual void Calc(vcl::RenderContext *pRenderContext) const override
Definition: fly.cxx:2820
long GetTop(const SwRect &rRect) const
Definition: frame.hxx:1353
void ActualizeSelection(const SwSelBoxes &rBoxes)
Definition: swcrsr.cxx:2452
const SvxProtectItem & GetProtect(bool=true) const
Definition: frmatr.hxx:82
A layout frame is a frame that contains other frames (m_pLower), e.g. SwPageFrame or SwTabFrame...
Definition: layfrm.hxx:35
const SwFrame * GetAnchorFrame() const
const SwLayoutFrame * GetNextLayoutLeaf() const
Definition: frame.hxx:996
Point GetPagePos(sal_uInt16 nPageNum) const
Returns the absolute document position of the desired page.
Definition: trvlfrm.cxx:1571
std::pair< const_iterator, bool > insert(Value &&x)
bool IsFootnoteContFrame() const
Definition: frame.hxx:1174
#define RES_PAGEDESC
Definition: hintids.hxx:293
bool IsOver(const SwRect &rRect) const
Definition: swrect.cxx:125
const SwContentFrame * ContainsContent() const
Checks if the frame contains one or more ContentFrame's anywhere in his subsidiary structure; if so t...
Definition: findfrm.cxx:66
Point GetNextPrevContentPos(const Point &rPoint, bool bNext) const
Search the nearest Content to the passed point.
Definition: trvlfrm.cxx:1472
SwTableLine * GetUpper()
Definition: swtable.hxx:421
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:204
o3tl::strong_int< sal_Int32, struct Tag_TextFrameIndex > TextFrameIndex
Denotes a character index in a text frame at a layout level, after extent mapping from a text node at...
class for collecting anchored objects
Definition: sortedobjs.hxx:48
bool NewTableSelection()
Definition: swcrsr.cxx:2431
const SwContentFrame * GetContentPos(Point &rPoint, const bool bDontLeave, const bool bBodyOnly=false, SwCursorMoveState *pCMS=nullptr, const bool bDefaultExpand=true) const
Finds the closest Content for the SPoint Is used for Pages, Flys and Cells if GetCursorOfst failed...
Definition: trvlfrm.cxx:1183
bool IsTextNode() const
Definition: node.hxx:636
SwPosition MapViewToModelPos(TextFrameIndex nIndex) const
Definition: txtfrm.cxx:1235
bool IsClickable() const
Is this field clickable?
Definition: fldbas.cxx:758
sal_uInt16 GetPageNum() const
Definition: rootfrm.hxx:307
bool IsFooterFrame() const
Definition: frame.hxx:1170
static const SwContentFrame * lcl_GetPrvCnt(const SwContentFrame *pCnt)
Definition: trvlfrm.cxx:638
SwRootFrame * getRootFrame()
Definition: frame.hxx:657
SwCellFrame is one table cell in the document layout.
Definition: cellfrm.hxx:30
bool IsCallbackActionEnabled() const
Definition: rootfrm.hxx:382
long Y() const
const ::o3tl::optional< sal_uInt16 > & GetNumOffset() const
Definition: fmtpdsc.hxx:65
sal_uInt16 nPos
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1313
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:842
bool IsHeaderFrame() const
Definition: frame.hxx:1166
virtual bool FillSelection(SwSelectionList &rList, const SwRect &rRect) const override
Definition: trvlfrm.cxx:365
bool IsInHeadline(const SwFrame &rFrame) const
Definition: tabfrm.cxx:5361
virtual const SwFrameFormat * GetFormat() const
Definition: ssfrm.cxx:393
bool IsProtected() const
Is the Frame or rather the Section in which it lies protected?
Definition: trvlfrm.cxx:1625
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1075
SwFrame * GetNext()
Definition: frame.hxx:654
void setHeight(long nHeight)