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