LibreOffice Module sw (master)  1
frmcrsr.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 <ndtxt.hxx>
21 #include <pam.hxx>
22 #include <frmatr.hxx>
23 #include <frmtool.hxx>
24 #include <viewopt.hxx>
25 #include <paratr.hxx>
26 #include <rootfrm.hxx>
27 #include <pagefrm.hxx>
28 #include <colfrm.hxx>
29 #include <swtypes.hxx>
30 #include <sfx2/printer.hxx>
31 #include <editeng/lrspitem.hxx>
32 #include <editeng/tstpitem.hxx>
33 #include <editeng/ulspitem.hxx>
34 #include <editeng/lspcitem.hxx>
35 #include "pormulti.hxx"
36 #include <doc.hxx>
38 #include <sortedobjs.hxx>
39 
40 #include <unicode/ubidi.h>
41 
42 #include <txtfrm.hxx>
43 #include "inftxt.hxx"
44 #include "itrtxt.hxx"
45 #include <crstate.hxx>
46 #include <viewsh.hxx>
47 #include <swfntcch.hxx>
48 #include <flyfrm.hxx>
49 
50 #define MIN_OFFSET_STEP 10
51 
52 using namespace ::com::sun::star;
53 
54 /*
55  * - SurvivalKit: For how long do we get past the last char of the line.
56  * - RightMargin abstains from adjusting position with -1
57  * - GetCharRect returns a GetEndCharRect for MV_RIGHTMARGIN
58  * - GetEndCharRect sets bRightMargin to true
59  * - SwTextCursor::bRightMargin is set to false by CharCursorToLine
60  */
61 
62 namespace
63 {
64 
65 SwTextFrame *GetAdjFrameAtPos( SwTextFrame *pFrame, const SwPosition &rPos,
66  const bool bRightMargin, const bool bNoScroll = true )
67 {
68  // RightMargin in the last master line
69  TextFrameIndex const nOffset = pFrame->MapModelToViewPos(rPos);
70  SwTextFrame *pFrameAtPos = pFrame;
71  if( !bNoScroll || pFrame->GetFollow() )
72  {
73  pFrameAtPos = pFrame->GetFrameAtPos( rPos );
74  if (nOffset < pFrameAtPos->GetOfst() &&
75  !pFrameAtPos->IsFollow() )
76  {
77  assert(pFrameAtPos->MapModelToViewPos(rPos) == nOffset);
78  TextFrameIndex nNew(nOffset);
79  if (nNew < TextFrameIndex(MIN_OFFSET_STEP))
80  nNew = TextFrameIndex(0);
81  else
83  sw_ChangeOffset( pFrameAtPos, nNew );
84  }
85  }
86  while( pFrame != pFrameAtPos )
87  {
88  pFrame = pFrameAtPos;
89  pFrame->GetFormatted();
90  pFrameAtPos = pFrame->GetFrameAtPos( rPos );
91  }
92 
93  if( nOffset && bRightMargin )
94  {
95  while (pFrameAtPos &&
96  pFrameAtPos->MapViewToModelPos(pFrameAtPos->GetOfst()) == rPos &&
97  pFrameAtPos->IsFollow() )
98  {
99  pFrameAtPos->GetFormatted();
100  pFrameAtPos = pFrameAtPos->FindMaster();
101  }
102  OSL_ENSURE( pFrameAtPos, "+GetCharRect: no frame with my rightmargin" );
103  }
104  return pFrameAtPos ? pFrameAtPos : pFrame;
105 }
106 
107 }
108 
110 {
111  // Do not scroll in areas and outside of flies
112  OSL_ENSURE( !pFrame->IsFollow(), "Illegal Scrolling by Follow!" );
113  if( pFrame->GetOfst() != nNew && !pFrame->IsInSct() )
114  {
115  SwFlyFrame *pFly = pFrame->FindFlyFrame();
116  // Attention: if e.g. in a column frame the size is still invalid
117  // we must not scroll around just like that
118  if ( ( pFly && pFly->isFrameAreaDefinitionValid() &&
119  !pFly->GetNextLink() && !pFly->GetPrevLink() ) ||
120  ( !pFly && pFrame->IsInTab() ) )
121  {
122  SwViewShell* pVsh = pFrame->getRootFrame()->GetCurrShell();
123  if( pVsh )
124  {
125  if( pVsh->GetRingContainer().size() > 1 ||
126  ( pFrame->GetDrawObjs() && pFrame->GetDrawObjs()->size() ) )
127  {
128  if( !pFrame->GetOfst() )
129  return false;
130  nNew = TextFrameIndex(0);
131  }
132  pFrame->SetOfst( nNew );
133  pFrame->SetPara( nullptr );
134  pFrame->GetFormatted();
135  if( pFrame->getFrameArea().HasArea() )
136  pFrame->getRootFrame()->GetCurrShell()->InvalidateWindows( pFrame->getFrameArea() );
137  return true;
138  }
139  }
140  }
141  return false;
142 }
143 
145 {
146  SwTextFrame* pRet = this;
147  while( pRet->HasFollow() && nWhere >= pRet->GetFollow()->GetOfst() )
148  pRet = pRet->GetFollow();
149  return *pRet;
150 }
151 
153 {
155  SwTextFrame *pFoll = this;
156  while( pFoll->GetFollow() )
157  {
158  if (nPos > pFoll->GetFollow()->GetOfst())
159  pFoll = pFoll->GetFollow();
160  else
161  {
162  if (nPos == pFoll->GetFollow()->GetOfst()
164  pFoll = pFoll->GetFollow();
165  else
166  break;
167  }
168  }
169  return pFoll;
170 }
171 
172 /*
173  * GetCharRect() returns the char's char line described by aPos.
174  * GetCursorOfst() does the reverse: It goes from a document coordinate to
175  * a Pam.
176  * Both are virtual in the frame base class and thus are redefined here.
177  */
178 
179 bool SwTextFrame::GetCharRect( SwRect& rOrig, const SwPosition &rPos,
180  SwCursorMoveState *pCMS, bool bAllowFarAway ) const
181 {
182  OSL_ENSURE( ! IsVertical() || ! IsSwapped(),"SwTextFrame::GetCharRect with swapped frame" );
183 
184  if( IsLocked() || IsHiddenNow() )
185  return false;
186 
187  // Find the right frame first. We need to keep in mind that:
188  // - the cached information could be invalid (GetPara() == 0)
189  // - we could have a Follow
190  // - the Follow chain grows dynamically; the one we end up in
191  // needs to be formatted
192 
193  // Optimisation: reading ahead saves us a GetAdjFrameAtPos
194  const bool bRightMargin = pCMS && ( MV_RIGHTMARGIN == pCMS->m_eState );
195  const bool bNoScroll = pCMS && pCMS->m_bNoScroll;
196  SwTextFrame *pFrame = GetAdjFrameAtPos( const_cast<SwTextFrame*>(this), rPos, bRightMargin,
197  bNoScroll );
198  pFrame->GetFormatted();
199 
200  const SwFrame* pTmpFrame = static_cast<SwFrame*>(pFrame->GetUpper());
201  if (pTmpFrame->getFrameArea().Top() == FAR_AWAY && !bAllowFarAway)
202  return false;
203 
204  SwRectFnSet aRectFnSet(pFrame);
205  const SwTwips nUpperMaxY = aRectFnSet.GetPrtBottom(*pTmpFrame);
206  const SwTwips nFrameMaxY = aRectFnSet.GetPrtBottom(*pFrame);
207 
208  // nMaxY is an absolute value
209  SwTwips nMaxY = aRectFnSet.IsVert() ?
210  ( aRectFnSet.IsVertL2R() ? std::min( nFrameMaxY, nUpperMaxY ) : std::max( nFrameMaxY, nUpperMaxY ) ) :
211  std::min( nFrameMaxY, nUpperMaxY );
212 
213  bool bRet = false;
214 
215  if ( pFrame->IsEmpty() || ! aRectFnSet.GetHeight(pFrame->getFramePrintArea()) )
216  {
217  Point aPnt1 = pFrame->getFrameArea().Pos() + pFrame->getFramePrintArea().Pos();
218  SwTextNode const*const pTextNd(GetTextNodeForParaProps());
219  short nFirstOffset;
220  pTextNd->GetFirstLineOfsWithNum( nFirstOffset );
221 
222  Point aPnt2;
223  if ( aRectFnSet.IsVert() )
224  {
225  if( nFirstOffset > 0 )
226  aPnt1.AdjustY(nFirstOffset );
227  if ( aPnt1.X() < nMaxY && !aRectFnSet.IsVertL2R() )
228  aPnt1.setX( nMaxY );
229  aPnt2.setX( aPnt1.X() + pFrame->getFramePrintArea().Width() );
230  aPnt2.setY( aPnt1.Y() );
231  if( aPnt2.X() < nMaxY )
232  aPnt2.setX( nMaxY );
233  }
234  else
235  {
236  if( nFirstOffset > 0 )
237  aPnt1.AdjustX(nFirstOffset );
238 
239  if( aPnt1.Y() > nMaxY )
240  aPnt1.setY( nMaxY );
241  aPnt2.setX( aPnt1.X() );
242  aPnt2.setY( aPnt1.Y() + pFrame->getFramePrintArea().Height() );
243  if( aPnt2.Y() > nMaxY )
244  aPnt2.setY( nMaxY );
245  }
246 
247  rOrig = SwRect( aPnt1, aPnt2 );
248 
249  if ( pCMS )
250  {
251  pCMS->m_aRealHeight.setX( 0 );
252  pCMS->m_aRealHeight.setY( aRectFnSet.IsVert() ? -rOrig.Width() : rOrig.Height() );
253  }
254 
255  if ( pFrame->IsRightToLeft() )
256  pFrame->SwitchLTRtoRTL( rOrig );
257 
258  bRet = true;
259  }
260  else
261  {
262  if( !pFrame->HasPara() )
263  return false;
264 
265  SwFrameSwapper aSwapper( pFrame, true );
266  if ( aRectFnSet.IsVert() )
267  nMaxY = pFrame->SwitchVerticalToHorizontal( nMaxY );
268 
269  bool bGoOn = true;
270  TextFrameIndex const nOffset = MapModelToViewPos(rPos);
271  assert(nOffset != TextFrameIndex(COMPLETE_STRING)); // not going to end well
272  TextFrameIndex nNextOfst;
273 
274  do
275  {
276  {
277  SwTextSizeInfo aInf( pFrame );
278  SwTextCursor aLine( pFrame, &aInf );
279  nNextOfst = aLine.GetEnd();
280  // See comment in AdjustFrame
281  // Include the line's last char?
282  if (bRightMargin)
283  aLine.GetEndCharRect( &rOrig, nOffset, pCMS, nMaxY );
284  else
285  aLine.GetCharRect( &rOrig, nOffset, pCMS, nMaxY );
286  bRet = true;
287  }
288 
289  if ( pFrame->IsRightToLeft() )
290  pFrame->SwitchLTRtoRTL( rOrig );
291 
292  if ( aRectFnSet.IsVert() )
293  pFrame->SwitchHorizontalToVertical( rOrig );
294 
295  if( pFrame->IsUndersized() && pCMS && !pFrame->GetNext() &&
296  aRectFnSet.GetBottom(rOrig) == nUpperMaxY &&
297  pFrame->GetOfst() < nOffset &&
298  !pFrame->IsFollow() && !bNoScroll &&
299  TextFrameIndex(pFrame->GetText().getLength()) != nNextOfst)
300  {
301  bGoOn = sw_ChangeOffset( pFrame, nNextOfst );
302  }
303  else
304  bGoOn = false;
305  } while ( bGoOn );
306 
307  if ( pCMS )
308  {
309  if ( pFrame->IsRightToLeft() )
310  {
311  if( pCMS->m_b2Lines && pCMS->m_p2Lines)
312  {
313  pFrame->SwitchLTRtoRTL( pCMS->m_p2Lines->aLine );
314  pFrame->SwitchLTRtoRTL( pCMS->m_p2Lines->aPortion );
315  }
316  }
317 
318  if ( aRectFnSet.IsVert() )
319  {
320  if ( pCMS->m_bRealHeight )
321  {
322  pCMS->m_aRealHeight.setY( -pCMS->m_aRealHeight.Y() );
323  if ( pCMS->m_aRealHeight.Y() < 0 )
324  {
325  // writing direction is from top to bottom
326  pCMS->m_aRealHeight.setX( rOrig.Width() -
327  pCMS->m_aRealHeight.X() +
328  pCMS->m_aRealHeight.Y() );
329  }
330  }
331  if( pCMS->m_b2Lines && pCMS->m_p2Lines)
332  {
333  pFrame->SwitchHorizontalToVertical( pCMS->m_p2Lines->aLine );
334  pFrame->SwitchHorizontalToVertical( pCMS->m_p2Lines->aPortion );
335  }
336  }
337 
338  }
339  }
340  if( bRet )
341  {
342  SwPageFrame *pPage = pFrame->FindPageFrame();
343  OSL_ENSURE( pPage, "Text escaped from page?" );
344  const SwTwips nOrigTop = aRectFnSet.GetTop(rOrig);
345  const SwTwips nPageTop = aRectFnSet.GetTop(pPage->getFrameArea());
346  const SwTwips nPageBott = aRectFnSet.GetBottom(pPage->getFrameArea());
347 
348  // We have the following situation: if the frame is in an invalid
349  // sectionframe, it's possible that the frame is outside the page.
350  // If we restrict the cursor position to the page area, we enforce
351  // the formatting of the page, of the section frame and the frame itself.
352  if( aRectFnSet.YDiff( nPageTop, nOrigTop ) > 0 )
353  aRectFnSet.SetTop( rOrig, nPageTop );
354 
355  if ( aRectFnSet.YDiff( nOrigTop, nPageBott ) > 0 )
356  aRectFnSet.SetTop( rOrig, nPageBott );
357  }
358 
359  return bRet;
360 }
361 
362 /*
363  * GetAutoPos() looks up the char's char line which is described by rPos
364  * and is used by the auto-positioned frame.
365  */
366 
367 bool SwTextFrame::GetAutoPos( SwRect& rOrig, const SwPosition &rPos ) const
368 {
369  if( IsHiddenNow() )
370  return false;
371 
372  TextFrameIndex const nOffset = MapModelToViewPos(rPos);
373  SwTextFrame* pFrame = &(const_cast<SwTextFrame*>(this)->GetFrameAtOfst( nOffset ));
374 
375  pFrame->GetFormatted();
376  const SwFrame* pTmpFrame = static_cast<SwFrame*>(pFrame->GetUpper());
377 
378  SwRectFnSet aRectFnSet(pTmpFrame);
379  SwTwips nUpperMaxY = aRectFnSet.GetPrtBottom(*pTmpFrame);
380 
381  // nMaxY is in absolute value
382  SwTwips nMaxY;
383  if ( aRectFnSet.IsVert() )
384  {
385  if ( aRectFnSet.IsVertL2R() )
386  nMaxY = std::min( aRectFnSet.GetPrtBottom(*pFrame), nUpperMaxY );
387  else
388  nMaxY = std::max( aRectFnSet.GetPrtBottom(*pFrame), nUpperMaxY );
389  }
390  else
391  nMaxY = std::min( aRectFnSet.GetPrtBottom(*pFrame), nUpperMaxY );
392  if ( pFrame->IsEmpty() || ! aRectFnSet.GetHeight(pFrame->getFramePrintArea()) )
393  {
394  Point aPnt1 = pFrame->getFrameArea().Pos() + pFrame->getFramePrintArea().Pos();
395  Point aPnt2;
396  if ( aRectFnSet.IsVert() )
397  {
398  if ( aPnt1.X() < nMaxY && !aRectFnSet.IsVertL2R() )
399  aPnt1.setX( nMaxY );
400 
401  aPnt2.setX( aPnt1.X() + pFrame->getFramePrintArea().Width() );
402  aPnt2.setY( aPnt1.Y() );
403  if( aPnt2.X() < nMaxY )
404  aPnt2.setX( nMaxY );
405  }
406  else
407  {
408  if( aPnt1.Y() > nMaxY )
409  aPnt1.setY( nMaxY );
410  aPnt2.setX( aPnt1.X() );
411  aPnt2.setY( aPnt1.Y() + pFrame->getFramePrintArea().Height() );
412  if( aPnt2.Y() > nMaxY )
413  aPnt2.setY( nMaxY );
414  }
415  rOrig = SwRect( aPnt1, aPnt2 );
416  return true;
417  }
418  else
419  {
420  if( !pFrame->HasPara() )
421  return false;
422 
423  SwFrameSwapper aSwapper( pFrame, true );
424  if ( aRectFnSet.IsVert() )
425  nMaxY = pFrame->SwitchVerticalToHorizontal( nMaxY );
426 
427  SwTextSizeInfo aInf( pFrame );
428  SwTextCursor aLine( pFrame, &aInf );
429  SwCursorMoveState aTmpState( MV_SETONLYTEXT );
430  aTmpState.m_bRealHeight = true;
431  aLine.GetCharRect( &rOrig, nOffset, &aTmpState, nMaxY );
432  if( aTmpState.m_aRealHeight.X() >= 0 )
433  {
434  rOrig.Pos().AdjustY(aTmpState.m_aRealHeight.X() );
435  rOrig.Height( aTmpState.m_aRealHeight.Y() );
436  }
437 
438  if ( pFrame->IsRightToLeft() )
439  pFrame->SwitchLTRtoRTL( rOrig );
440 
441  if ( aRectFnSet.IsVert() )
442  pFrame->SwitchHorizontalToVertical( rOrig );
443 
444  return true;
445  }
446 }
447 
454 bool SwTextFrame::GetTopOfLine( SwTwips& _onTopOfLine,
455  const SwPosition& _rPos ) const
456 {
457  bool bRet = true;
458 
459  // get position offset
460  TextFrameIndex const nOffset = MapModelToViewPos(_rPos);
461 
462  if (TextFrameIndex(GetText().getLength()) < nOffset)
463  {
464  bRet = false;
465  }
466  else
467  {
468  SwRectFnSet aRectFnSet(this);
469  if ( IsEmpty() || !aRectFnSet.GetHeight(getFramePrintArea()) )
470  {
471  // consider upper space amount considered
472  // for previous frame and the page grid.
473  _onTopOfLine = aRectFnSet.GetPrtTop(*this);
474  }
475  else
476  {
477  // determine formatted text frame that contains the requested position
478  SwTextFrame* pFrame = &(const_cast<SwTextFrame*>(this)->GetFrameAtOfst( nOffset ));
479  pFrame->GetFormatted();
480  aRectFnSet.Refresh(pFrame);
481  // If proportional line spacing is applied
482  // to the text frame, the top of the anchor character is also the
483  // top of the line.
484  // Otherwise the line layout determines the top of the line
485  const SvxLineSpacingItem& rSpace = GetAttrSet()->GetLineSpacing();
486  if ( rSpace.GetInterLineSpaceRule() == SvxInterLineSpaceRule::Prop )
487  {
488  SwRect aCharRect;
489  if ( GetAutoPos( aCharRect, _rPos ) )
490  {
491  _onTopOfLine = aRectFnSet.GetTop(aCharRect);
492  }
493  else
494  {
495  bRet = false;
496  }
497  }
498  else
499  {
500  // assure that text frame is in a horizontal layout
501  SwFrameSwapper aSwapper( pFrame, true );
502  // determine text line that contains the requested position
503  SwTextSizeInfo aInf( pFrame );
504  SwTextCursor aLine( pFrame, &aInf );
505  aLine.CharCursorToLine( nOffset );
506  // determine top of line
507  _onTopOfLine = aLine.Y();
508  if ( aRectFnSet.IsVert() )
509  {
510  _onTopOfLine = pFrame->SwitchHorizontalToVertical( _onTopOfLine );
511  }
512  }
513  }
514  }
515 
516  return bRet;
517 }
518 
519 // Minimum distance of non-empty lines is a little less than 2 cm
520 #define FILL_MIN_DIST 1100
521 
523 {
527  const Point& rPoint;
529  bool bFirstLine : 1;
530  bool bInner : 1;
531  bool bColumn : 1;
532  bool bEmpty : 1;
533  SwFillData( const SwCursorMoveState *pC, SwPosition* pP, const SwRect& rR,
534  const Point& rPt ) : aFrame( rR ), pCMS( pC ), pPos( pP ), rPoint( rPt ),
535  nLineWidth( 0 ), bFirstLine( true ), bInner( false ), bColumn( false ),
536  bEmpty( true ){}
537  SwFillMode Mode() const { return pCMS->m_pFill->eMode; }
538  long X() const { return rPoint.X(); }
539  long Y() const { return rPoint.Y(); }
540  long Left() const { return aFrame.Left(); }
541  long Right() const { return aFrame.Right(); }
542  long Bottom() const { return aFrame.Bottom(); }
543  SwFillCursorPos &Fill() const { return *pCMS->m_pFill; }
544  void SetTab( sal_uInt16 nNew ) { pCMS->m_pFill->nTabCnt = nNew; }
545  void SetSpace( sal_uInt16 nNew ) { pCMS->m_pFill->nSpaceCnt = nNew; }
546  void SetSpaceOnly( sal_uInt16 nNew ) { pCMS->m_pFill->nSpaceOnlyCnt = nNew; }
547  void SetOrient( const sal_Int16 eNew ){ pCMS->m_pFill->eOrient = eNew; }
548 };
549 
550 bool SwTextFrame::GetCursorOfst_(SwPosition* pPos, const Point& rPoint,
551  const bool bChgFrame, SwCursorMoveState* pCMS ) const
552 {
553  // GetCursorOfst_ is called by GetCursorOfst and GetKeyCursorOfst.
554  // Never just a return false.
555 
556  if( IsLocked() || IsHiddenNow() )
557  return false;
558 
559  const_cast<SwTextFrame*>(this)->GetFormatted();
560 
561  Point aOldPoint( rPoint );
562 
563  if ( IsVertical() )
564  {
565  SwitchVerticalToHorizontal( const_cast<Point&>(rPoint) );
566  const_cast<SwTextFrame*>(this)->SwapWidthAndHeight();
567  }
568 
569  if ( IsRightToLeft() )
570  SwitchRTLtoLTR( const_cast<Point&>(rPoint) );
571 
572  std::unique_ptr<SwFillData> pFillData;
573  if ( pCMS && pCMS->m_pFill )
574  pFillData.reset(new SwFillData( pCMS, pPos, getFrameArea(), rPoint ));
575 
576  if ( IsEmpty() )
577  {
578  *pPos = MapViewToModelPos(TextFrameIndex(0));
579  if( pCMS && pCMS->m_bFieldInfo )
580  {
581  SwTwips nDiff = rPoint.X() - getFrameArea().Left() - getFramePrintArea().Left();
582  if( nDiff > 50 || nDiff < 0 )
583  pCMS->m_bPosCorr = true;
584  }
585  }
586  else
587  {
588  SwTextSizeInfo aInf( const_cast<SwTextFrame*>(this) );
589  SwTextCursor aLine( const_cast<SwTextFrame*>(this), &aInf );
590 
591  // See comment in AdjustFrame()
593  aLine.TwipsToLine( rPoint.Y() );
594  while( aLine.Y() + aLine.GetLineHeight() > nMaxY )
595  {
596  if( !aLine.Prev() )
597  break;
598  }
599 
600  if( aLine.GetDropLines() >= aLine.GetLineNr() && 1 != aLine.GetLineNr()
601  && rPoint.X() < aLine.FirstLeft() + aLine.GetDropLeft() )
602  while( aLine.GetLineNr() > 1 )
603  aLine.Prev();
604 
605  TextFrameIndex nOffset = aLine.GetCursorOfst(pPos, rPoint, bChgFrame, pCMS);
606 
607  if( pCMS && pCMS->m_eState == MV_NONE && aLine.GetEnd() == nOffset )
608  pCMS->m_eState = MV_RIGHTMARGIN;
609 
610  // pPos is a pure IN parameter and must not be evaluated.
611  // pIter->GetCursorOfst returns from a nesting with COMPLETE_STRING.
612  // If SwTextIter::GetCursorOfst calls GetCursorOfst further by itself
613  // nNode changes the position.
614  // In such cases, pPos must not be calculated.
615  if (TextFrameIndex(COMPLETE_STRING) != nOffset)
616  {
617  *pPos = MapViewToModelPos(nOffset);
618  if( pFillData )
619  {
620  if (TextFrameIndex(GetText().getLength()) > nOffset ||
621  rPoint.Y() < getFrameArea().Top() )
622  pFillData->bInner = true;
623  pFillData->bFirstLine = aLine.GetLineNr() < 2;
624  if (GetText().getLength())
625  {
626  pFillData->bEmpty = false;
627  pFillData->nLineWidth = aLine.GetCurr()->Width();
628  }
629  }
630  }
631  }
632  bool bChgFillData = false;
633  if( pFillData && FindPageFrame()->getFrameArea().IsInside( aOldPoint ) )
634  {
635  FillCursorPos( *pFillData );
636  bChgFillData = true;
637  }
638 
639  if ( IsVertical() )
640  {
641  if ( bChgFillData )
642  SwitchHorizontalToVertical( pFillData->Fill().aCursor.Pos() );
643  const_cast<SwTextFrame*>(this)->SwapWidthAndHeight();
644  }
645 
646  if ( IsRightToLeft() && bChgFillData )
647  {
648  SwitchLTRtoRTL( pFillData->Fill().aCursor.Pos() );
649  const sal_Int16 eOrient = pFillData->pCMS->m_pFill->eOrient;
650 
651  if ( text::HoriOrientation::LEFT == eOrient )
652  pFillData->SetOrient( text::HoriOrientation::RIGHT );
653  else if ( text::HoriOrientation::RIGHT == eOrient )
654  pFillData->SetOrient( text::HoriOrientation::LEFT );
655  }
656 
657  const_cast<Point&>(rPoint) = aOldPoint;
658 
659  return true;
660 }
661 
663  SwCursorMoveState* pCMS, bool ) const
664 {
665  const bool bChgFrame = !(pCMS && MV_UPDOWN == pCMS->m_eState);
666  return GetCursorOfst_( pPos, rPoint, bChgFrame, pCMS );
667 }
668 
669 /*
670  * Layout-oriented cursor movement to the line start.
671  */
672 
674 {
675  assert(GetMergedPara() || &pPam->GetNode() == static_cast<SwContentNode const*>(GetDep()));
676 
677  SwTextFrame *pFrame = GetAdjFrameAtPos( const_cast<SwTextFrame*>(this), *pPam->GetPoint(),
679  pFrame->GetFormatted();
680  TextFrameIndex nIndx;
681  if ( pFrame->IsEmpty() )
682  nIndx = TextFrameIndex(0);
683  else
684  {
685  SwTextSizeInfo aInf( pFrame );
686  SwTextCursor aLine( pFrame, &aInf );
687 
688  aLine.CharCursorToLine(pFrame->MapModelToViewPos(*pPam->GetPoint()));
689  nIndx = aLine.GetStart();
690  if( pFrame->GetOfst() && !pFrame->IsFollow() && !aLine.GetPrev() )
691  {
692  sw_ChangeOffset(pFrame, TextFrameIndex(0));
693  nIndx = TextFrameIndex(0);
694  }
695  }
696  *pPam->GetPoint() = pFrame->MapViewToModelPos(nIndx);
698  return true;
699 }
700 
701 /*
702  * To the line end: That's the position before the last char of the line.
703  * Exception: In the last line, it should be able to place the cursor after
704  * the last char in order to append text.
705  */
706 
707 bool SwTextFrame::RightMargin(SwPaM *pPam, bool bAPI) const
708 {
709  assert(GetMergedPara() || &pPam->GetNode() == static_cast<SwContentNode const*>(GetDep()));
710 
711  SwTextFrame *pFrame = GetAdjFrameAtPos( const_cast<SwTextFrame*>(this), *pPam->GetPoint(),
713  pFrame->GetFormatted();
715  if (!IsEmpty())
716  {
717  SwTextSizeInfo aInf( pFrame );
718  SwTextCursor aLine( pFrame, &aInf );
719 
721  nRightMargin = aLine.GetStart() + aLine.GetCurr()->GetLen();
722 
723  // We skip hard line brakes
724  if( aLine.GetCurr()->GetLen() &&
725  CH_BREAK == aInf.GetText()[sal_Int32(nRightMargin) - 1])
726  --nRightMargin;
727  else if( !bAPI && (aLine.GetNext() || pFrame->GetFollow()) )
728  {
729  while( nRightMargin > aLine.GetStart() &&
730  ' ' == aInf.GetText()[sal_Int32(nRightMargin) - 1])
731  --nRightMargin;
732  }
733  }
734  *pPam->GetPoint() = pFrame->MapViewToModelPos(nRightMargin);
736  return true;
737 }
738 
739 // The following two methods try to put the Cursor into the next/successive
740 // line. If we do not have a preceding/successive line we forward the call
741 // to the base class.
742 // The Cursor's horizontal justification is done afterwards by the CursorShell.
743 
745 {
746  bool bRight;
747 public:
748  SwSetToRightMargin() : bRight( false ) { }
750  void SetRight( const bool bNew ) { bRight = bNew; }
751 };
752 
753 bool SwTextFrame::UnitUp_( SwPaM *pPam, const SwTwips nOffset,
754  bool bSetInReadOnly ) const
755 {
756  // Set the RightMargin if needed
757  SwSetToRightMargin aSet;
758 
759  if( IsInTab() &&
760  pPam->GetNode().StartOfSectionNode() !=
761  pPam->GetNode( false ).StartOfSectionNode() )
762  {
763  // If the PaM is located within different boxes, we have a table selection,
764  // which is handled by the base class.
765  return SwContentFrame::UnitUp( pPam, nOffset, bSetInReadOnly );
766  }
767 
768  const_cast<SwTextFrame*>(this)->GetFormatted();
769  const TextFrameIndex nPos = MapModelToViewPos(*pPam->GetPoint());
770  SwRect aCharBox;
771 
772  if( !IsEmpty() && !IsHiddenNow() )
773  {
775  do
776  {
777  if (nFormat != TextFrameIndex(COMPLETE_STRING) && !IsFollow())
778  sw_ChangeOffset( const_cast<SwTextFrame*>(this), nFormat );
779 
780  SwTextSizeInfo aInf( const_cast<SwTextFrame*>(this) );
781  SwTextCursor aLine( const_cast<SwTextFrame*>(this), &aInf );
782 
783  // Optimize away flys with no flow and IsDummy()
784  if( nPos )
785  aLine.CharCursorToLine( nPos );
786  else
787  aLine.Top();
788 
789  const SwLineLayout *pPrevLine = aLine.GetPrevLine();
790  const TextFrameIndex nStart = aLine.GetStart();
791  aLine.GetCharRect( &aCharBox, nPos );
792 
793  bool bSecondOfDouble = ( aInf.IsMulti() && ! aInf.IsFirstMulti() );
794  bool bPrevLine = ( pPrevLine && pPrevLine != aLine.GetCurr() );
795 
796  if( !pPrevLine && !bSecondOfDouble && GetOfst() && !IsFollow() )
797  {
798  nFormat = GetOfst();
799  TextFrameIndex nDiff = aLine.GetLength();
800  if( !nDiff )
802  if( nFormat > nDiff )
803  nFormat = nFormat - nDiff;
804  else
805  nFormat = TextFrameIndex(0);
806  continue;
807  }
808 
809  // We select the target line for the cursor, in case we are in a
810  // double line portion, prev line = curr line
811  if( bPrevLine && !bSecondOfDouble )
812  {
813  aLine.PrevLine();
814  while ( aLine.GetStart() == nStart &&
815  nullptr != ( pPrevLine = aLine.GetPrevLine() ) &&
816  pPrevLine != aLine.GetCurr() )
817  aLine.PrevLine();
818  }
819 
820  if ( bPrevLine || bSecondOfDouble )
821  {
822  aCharBox.SSize().setWidth( aCharBox.SSize().Width() / 2 );
823  aCharBox.Pos().setX( aCharBox.Pos().X() - 150 );
824 
825  // See comment in SwTextFrame::GetCursorOfst()
826 #if OSL_DEBUG_LEVEL > 0
827  const sal_uLong nOldNode = pPam->GetPoint()->nNode.GetIndex();
828 #endif
829  // The node should not be changed
830  TextFrameIndex nTmpOfst = aLine.GetCursorOfst(pPam->GetPoint(),
831  aCharBox.Pos(), false );
832 #if OSL_DEBUG_LEVEL > 0
833  OSL_ENSURE( nOldNode == pPam->GetPoint()->nNode.GetIndex(),
834  "SwTextFrame::UnitUp: illegal node change" );
835 #endif
836 
837  // We make sure that we move up.
838  if( nTmpOfst >= nStart && nStart && !bSecondOfDouble )
839  {
840  nTmpOfst = nStart;
841  aSet.SetRight( true );
842  }
843  *pPam->GetPoint() = MapViewToModelPos(nTmpOfst);
844  return true;
845  }
846 
847  if ( IsFollow() )
848  {
849  aLine.GetCharRect( &aCharBox, nPos );
850  aCharBox.SSize().setWidth( aCharBox.SSize().Width() / 2 );
851  }
852  break;
853  } while ( true );
854  }
855  /* If 'this' is a follow and a prev failed, we need to go to the
856  * last line of the master, which is us.
857  * Or: If we are a follow with follow, we need to get the master.
858  */
859  if ( IsFollow() )
860  {
861  const SwTextFrame *pTmpPrev = FindMaster();
862  TextFrameIndex nOffs = GetOfst();
863  if( pTmpPrev )
864  {
866  const bool bProtectedAllowed = pSh && pSh->GetViewOptions()->IsCursorInProtectedArea();
867  const SwTextFrame *pPrevPrev = pTmpPrev;
868  // We skip protected frames and frames without content here
869  while( pPrevPrev && ( pPrevPrev->GetOfst() == nOffs ||
870  ( !bProtectedAllowed && pPrevPrev->IsProtected() ) ) )
871  {
872  pTmpPrev = pPrevPrev;
873  nOffs = pTmpPrev->GetOfst();
874  if ( pPrevPrev->IsFollow() )
875  pPrevPrev = pTmpPrev->FindMaster();
876  else
877  pPrevPrev = nullptr;
878  }
879  if ( !pPrevPrev )
880  return pTmpPrev->SwContentFrame::UnitUp( pPam, nOffset, bSetInReadOnly );
881  aCharBox.Pos().setY( pPrevPrev->getFrameArea().Bottom() - 1 );
882  return pPrevPrev->GetKeyCursorOfst( pPam->GetPoint(), aCharBox.Pos() );
883  }
884  }
885  return SwContentFrame::UnitUp( pPam, nOffset, bSetInReadOnly );
886 }
887 
888 // Used for Bidi. nPos is the logical position in the string, bLeft indicates
889 // if left arrow or right arrow was pressed. The return values are:
890 // nPos: the new visual position
891 // bLeft: whether the break iterator has to add or subtract from the
892 // current position
893 static void lcl_VisualMoveRecursion(const SwLineLayout& rCurrLine, TextFrameIndex nIdx,
894  TextFrameIndex & nPos, bool& bRight,
895  sal_uInt8& nCursorLevel, sal_uInt8 nDefaultDir )
896 {
897  const SwLinePortion* pPor = rCurrLine.GetFirstPortion();
898  const SwLinePortion* pLast = nullptr;
899 
900  // What's the current portion?
901  while ( pPor && nIdx + pPor->GetLen() <= nPos )
902  {
903  nIdx = nIdx + pPor->GetLen();
904  pLast = pPor;
905  pPor = pPor->GetNextPortion();
906  }
907 
908  if ( bRight )
909  {
910  bool bRecurse = pPor && pPor->IsMultiPortion() &&
911  static_cast<const SwMultiPortion*>(pPor)->IsBidi();
912 
913  // 1. special case: at beginning of bidi portion
914  if ( bRecurse && nIdx == nPos )
915  {
916  nPos = nPos + pPor->GetLen();
917 
918  // leave bidi portion
919  if ( nCursorLevel != nDefaultDir )
920  {
921  bRecurse = false;
922  }
923  else
924  // special case:
925  // buffer: abcXYZ123 in LTR paragraph
926  // view: abc123ZYX
927  // cursor is between c and X in the buffer and cursor level = 0
928  nCursorLevel++;
929  }
930 
931  // 2. special case: at beginning of portion after bidi portion
932  else if ( pLast && pLast->IsMultiPortion() &&
933  static_cast<const SwMultiPortion*>(pLast)->IsBidi() && nIdx == nPos )
934  {
935  // enter bidi portion
936  if ( nCursorLevel != nDefaultDir )
937  {
938  bRecurse = true;
939  nIdx = nIdx - pLast->GetLen();
940  pPor = pLast;
941  }
942  }
943 
944  // Recursion
945  if ( bRecurse )
946  {
947  const SwLineLayout& rLine = static_cast<const SwMultiPortion*>(pPor)->GetRoot();
948  TextFrameIndex nTmpPos = nPos - nIdx;
949  bool bTmpForward = ! bRight;
950  sal_uInt8 nTmpCursorLevel = nCursorLevel;
951  lcl_VisualMoveRecursion(rLine, TextFrameIndex(0), nTmpPos, bTmpForward,
952  nTmpCursorLevel, nDefaultDir + 1 );
953 
954  nPos = nTmpPos + nIdx;
955  bRight = bTmpForward;
956  nCursorLevel = nTmpCursorLevel;
957  }
958 
959  // go forward
960  else
961  {
962  bRight = true;
963  nCursorLevel = nDefaultDir;
964  }
965 
966  }
967  else
968  {
969  bool bRecurse = pPor && pPor->IsMultiPortion() && static_cast<const SwMultiPortion*>(pPor)->IsBidi();
970 
971  // 1. special case: at beginning of bidi portion
972  if ( bRecurse && nIdx == nPos )
973  {
974  // leave bidi portion
975  if ( nCursorLevel == nDefaultDir )
976  {
977  bRecurse = false;
978  }
979  }
980 
981  // 2. special case: at beginning of portion after bidi portion
982  else if ( pLast && pLast->IsMultiPortion() &&
983  static_cast<const SwMultiPortion*>(pLast)->IsBidi() && nIdx == nPos )
984  {
985  nPos = nPos - pLast->GetLen();
986 
987  // enter bidi portion
988  if ( nCursorLevel % 2 == nDefaultDir % 2 )
989  {
990  bRecurse = true;
991  nIdx = nIdx - pLast->GetLen();
992  pPor = pLast;
993 
994  // special case:
995  // buffer: abcXYZ123 in LTR paragraph
996  // view: abc123ZYX
997  // cursor is behind 3 in the buffer and cursor level = 2
998  if ( nDefaultDir + 2 == nCursorLevel )
999  nPos = nPos + pLast->GetLen();
1000  }
1001  }
1002 
1003  // go forward
1004  if ( bRecurse )
1005  {
1006  const SwLineLayout& rLine = static_cast<const SwMultiPortion*>(pPor)->GetRoot();
1007  TextFrameIndex nTmpPos = nPos - nIdx;
1008  bool bTmpForward = ! bRight;
1009  sal_uInt8 nTmpCursorLevel = nCursorLevel;
1010  lcl_VisualMoveRecursion(rLine, TextFrameIndex(0), nTmpPos, bTmpForward,
1011  nTmpCursorLevel, nDefaultDir + 1 );
1012 
1013  // special case:
1014  // buffer: abcXYZ123 in LTR paragraph
1015  // view: abc123ZYX
1016  // cursor is between Z and 1 in the buffer and cursor level = 2
1017  if ( nTmpPos == pPor->GetLen() && nTmpCursorLevel == nDefaultDir + 1 )
1018  {
1019  nTmpPos = nTmpPos - pPor->GetLen();
1020  nTmpCursorLevel = nDefaultDir;
1021  bTmpForward = ! bTmpForward;
1022  }
1023 
1024  nPos = nTmpPos + nIdx;
1025  bRight = bTmpForward;
1026  nCursorLevel = nTmpCursorLevel;
1027  }
1028 
1029  // go backward
1030  else
1031  {
1032  bRight = false;
1033  nCursorLevel = nDefaultDir;
1034  }
1035  }
1036 }
1037 
1039  bool& bForward, bool bInsertCursor )
1040 {
1041  if( IsEmpty() || IsHiddenNow() )
1042  return;
1043 
1044  GetFormatted();
1045 
1046  SwTextSizeInfo aInf(this);
1047  SwTextCursor aLine(this, &aInf);
1048 
1049  if( nPos )
1050  aLine.CharCursorToLine( nPos );
1051  else
1052  aLine.Top();
1053 
1054  const SwLineLayout* pLine = aLine.GetCurr();
1055  const TextFrameIndex nStt = aLine.GetStart();
1056  const TextFrameIndex nLen = pLine->GetLen();
1057 
1058  // We have to distinguish between an insert and overwrite cursor:
1059  // The insert cursor position depends on the cursor level:
1060  // buffer: abcXYZdef in LTR paragraph
1061  // display: abcZYXdef
1062  // If cursor is between c and X in the buffer and cursor level is 0,
1063  // the cursor blinks between c and Z and -> sets the cursor between Z and Y.
1064  // If the cursor level is 1, the cursor blinks between X and d and
1065  // -> sets the cursor between d and e.
1066  // The overwrite cursor simply travels to the next visual character.
1067  if ( bInsertCursor )
1068  {
1069  lcl_VisualMoveRecursion( *pLine, nStt, nPos, bForward,
1070  nCursorLevel, IsRightToLeft() ? 1 : 0 );
1071  return;
1072  }
1073 
1074  const sal_uInt8 nDefaultDir = static_cast<sal_uInt8>(IsRightToLeft() ? UBIDI_RTL : UBIDI_LTR);
1075  const bool bVisualRight = ( nDefaultDir == UBIDI_LTR && bForward ) ||
1076  ( nDefaultDir == UBIDI_RTL && ! bForward );
1077 
1078  // Bidi functions from icu 2.0
1079 
1080  const sal_Unicode* pLineString = GetText().getStr();
1081 
1082  UErrorCode nError = U_ZERO_ERROR;
1083  UBiDi* pBidi = ubidi_openSized( sal_Int32(nLen), 0, &nError );
1084  ubidi_setPara( pBidi, reinterpret_cast<const UChar *>(pLineString),
1085  sal_Int32(nLen), nDefaultDir, nullptr, &nError );
1086 
1087  TextFrameIndex nTmpPos(0);
1088  bool bOutOfBounds = false;
1089 
1090  if ( nPos < nStt + nLen )
1091  {
1092  nTmpPos = TextFrameIndex(ubidi_getVisualIndex( pBidi, sal_Int32(nPos), &nError ));
1093 
1094  // visual indices are always LTR aligned
1095  if ( bVisualRight )
1096  {
1097  if (nTmpPos + TextFrameIndex(1) < nStt + nLen)
1098  ++nTmpPos;
1099  else
1100  {
1101  nPos = nDefaultDir == UBIDI_RTL ? TextFrameIndex(0) : nStt + nLen;
1102  bOutOfBounds = true;
1103  }
1104  }
1105  else
1106  {
1107  if ( nTmpPos )
1108  --nTmpPos;
1109  else
1110  {
1111  nPos = nDefaultDir == UBIDI_RTL ? nStt + nLen : TextFrameIndex(0);
1112  bOutOfBounds = true;
1113  }
1114  }
1115  }
1116  else
1117  {
1118  nTmpPos = nDefaultDir == UBIDI_LTR ? nPos - TextFrameIndex(1) : TextFrameIndex(0);
1119  }
1120 
1121  if ( ! bOutOfBounds )
1122  {
1123  nPos = TextFrameIndex(ubidi_getLogicalIndex( pBidi, sal_Int32(nTmpPos), &nError ));
1124 
1125  if ( bForward )
1126  {
1127  if ( nPos )
1128  --nPos;
1129  else
1130  {
1131  ++nPos;
1132  bForward = ! bForward;
1133  }
1134  }
1135  else
1136  ++nPos;
1137  }
1138 
1139  ubidi_close( pBidi );
1140 }
1141 
1142 bool SwTextFrame::UnitDown_(SwPaM *pPam, const SwTwips nOffset,
1143  bool bSetInReadOnly ) const
1144 {
1145 
1146  if ( IsInTab() &&
1147  pPam->GetNode().StartOfSectionNode() !=
1148  pPam->GetNode( false ).StartOfSectionNode() )
1149  {
1150  // If the PaM is located within different boxes, we have a table selection,
1151  // which is handled by the base class.
1152  return SwContentFrame::UnitDown( pPam, nOffset, bSetInReadOnly );
1153  }
1154  const_cast<SwTextFrame*>(this)->GetFormatted();
1155  const TextFrameIndex nPos = MapModelToViewPos(*pPam->GetPoint());
1156  SwRect aCharBox;
1157  const SwContentFrame *pTmpFollow = nullptr;
1158 
1159  if ( IsVertical() )
1160  const_cast<SwTextFrame*>(this)->SwapWidthAndHeight();
1161 
1162  if ( !IsEmpty() && !IsHiddenNow() )
1163  {
1165  do
1166  {
1167  if (nFormat != TextFrameIndex(COMPLETE_STRING) && !IsFollow() &&
1168  !sw_ChangeOffset( const_cast<SwTextFrame*>(this), nFormat ) )
1169  break;
1170 
1171  SwTextSizeInfo aInf( const_cast<SwTextFrame*>(this) );
1172  SwTextCursor aLine( const_cast<SwTextFrame*>(this), &aInf );
1173  nFormat = aLine.GetEnd();
1174 
1175  aLine.CharCursorToLine( nPos );
1176 
1177  const SwLineLayout* pNextLine = aLine.GetNextLine();
1178  const TextFrameIndex nStart = aLine.GetStart();
1179  aLine.GetCharRect( &aCharBox, nPos );
1180 
1181  bool bFirstOfDouble = ( aInf.IsMulti() && aInf.IsFirstMulti() );
1182 
1183  if( pNextLine || bFirstOfDouble )
1184  {
1185  aCharBox.SSize().setWidth( aCharBox.SSize().Width() / 2 );
1186 #if OSL_DEBUG_LEVEL > 0
1187  // See comment in SwTextFrame::GetCursorOfst()
1188  const sal_uLong nOldNode = pPam->GetPoint()->nNode.GetIndex();
1189 #endif
1190  if ( pNextLine && ! bFirstOfDouble )
1191  aLine.NextLine();
1192 
1193  TextFrameIndex nTmpOfst = aLine.GetCursorOfst( pPam->GetPoint(),
1194  aCharBox.Pos(), false );
1195 #if OSL_DEBUG_LEVEL > 0
1196  OSL_ENSURE( nOldNode == pPam->GetPoint()->nNode.GetIndex(),
1197  "SwTextFrame::UnitDown: illegal node change" );
1198 #endif
1199 
1200  // We make sure that we move down.
1201  if( nTmpOfst <= nStart && ! bFirstOfDouble )
1202  nTmpOfst = nStart + TextFrameIndex(1);
1203  *pPam->GetPoint() = MapViewToModelPos(nTmpOfst);
1204 
1205  if ( IsVertical() )
1206  const_cast<SwTextFrame*>(this)->SwapWidthAndHeight();
1207 
1208  return true;
1209  }
1210  if( nullptr != ( pTmpFollow = GetFollow() ) )
1211  { // Skip protected follows
1212  const SwContentFrame* pTmp = pTmpFollow;
1214  if( !pSh || !pSh->GetViewOptions()->IsCursorInProtectedArea() )
1215  {
1216  while( pTmpFollow && pTmpFollow->IsProtected() )
1217  {
1218  pTmp = pTmpFollow;
1219  pTmpFollow = pTmpFollow->GetFollow();
1220  }
1221  }
1222  if( !pTmpFollow ) // Only protected ones left
1223  {
1224  if ( IsVertical() )
1225  const_cast<SwTextFrame*>(this)->SwapWidthAndHeight();
1226  return pTmp->SwContentFrame::UnitDown( pPam, nOffset, bSetInReadOnly );
1227  }
1228 
1229  aLine.GetCharRect( &aCharBox, nPos );
1230  aCharBox.SSize().setWidth( aCharBox.SSize().Width() / 2 );
1231  }
1232  else if( !IsFollow() )
1233  {
1234  TextFrameIndex nTmpLen(aInf.GetText().getLength());
1235  if( aLine.GetEnd() < nTmpLen )
1236  {
1237  if( nFormat <= GetOfst() )
1238  {
1239  nFormat = std::min(GetOfst() + TextFrameIndex(MIN_OFFSET_STEP),
1240  nTmpLen );
1241  if( nFormat <= GetOfst() )
1242  break;
1243  }
1244  continue;
1245  }
1246  }
1247  break;
1248  } while( true );
1249  }
1250  else
1251  pTmpFollow = GetFollow();
1252 
1253  if ( IsVertical() )
1254  const_cast<SwTextFrame*>(this)->SwapWidthAndHeight();
1255 
1256  // We take a shortcut for follows
1257  if( pTmpFollow )
1258  {
1259  aCharBox.Pos().setY( pTmpFollow->getFrameArea().Top() + 1 );
1260  return static_cast<const SwTextFrame*>(pTmpFollow)->GetKeyCursorOfst( pPam->GetPoint(),
1261  aCharBox.Pos() );
1262  }
1263  return SwContentFrame::UnitDown( pPam, nOffset, bSetInReadOnly );
1264 }
1265 
1266 bool SwTextFrame::UnitUp(SwPaM *pPam, const SwTwips nOffset,
1267  bool bSetInReadOnly ) const
1268 {
1269  /* We call ContentNode::GertFrame() in CursorSh::Up().
1270  * This _always returns the master.
1271  * In order to not mess with cursor travelling, we correct here
1272  * in SwTextFrame.
1273  * We calculate UnitUp for pFrame. pFrame is either a master (= this) or a
1274  * follow (!= this).
1275  */
1276  const SwTextFrame *pFrame = GetAdjFrameAtPos( const_cast<SwTextFrame*>(this), *(pPam->GetPoint()),
1278  const bool bRet = pFrame->UnitUp_( pPam, nOffset, bSetInReadOnly );
1279 
1280  // No SwTextCursor::SetRightMargin( false );
1281  // Instead we have a SwSetToRightMargin in UnitUp_
1282  return bRet;
1283 }
1284 
1285 bool SwTextFrame::UnitDown(SwPaM *pPam, const SwTwips nOffset,
1286  bool bSetInReadOnly ) const
1287 {
1288  const SwTextFrame *pFrame = GetAdjFrameAtPos(const_cast<SwTextFrame*>(this), *(pPam->GetPoint()),
1290  const bool bRet = pFrame->UnitDown_( pPam, nOffset, bSetInReadOnly );
1292  return bRet;
1293 }
1294 
1296 {
1297  if( !rFill.bColumn && GetUpper()->IsColBodyFrame() ) // ColumnFrames now with BodyFrame
1298  {
1299  const SwColumnFrame* pTmp =
1300  static_cast<const SwColumnFrame*>(GetUpper()->GetUpper()->GetUpper()->Lower()); // The 1st column
1301  // The first SwFrame in BodyFrame of the first column
1302  const SwFrame* pFrame = static_cast<const SwLayoutFrame*>(pTmp->Lower())->Lower();
1303  sal_uInt16 nNextCol = 0;
1304  // In which column do we end up in?
1305  while( rFill.X() > pTmp->getFrameArea().Right() && pTmp->GetNext() )
1306  {
1307  pTmp = static_cast<const SwColumnFrame*>(pTmp->GetNext());
1308  if( static_cast<const SwLayoutFrame*>(pTmp->Lower())->Lower() ) // ColumnFrames now with BodyFrame
1309  {
1310  pFrame = static_cast<const SwLayoutFrame*>(pTmp->Lower())->Lower();
1311  nNextCol = 0;
1312  }
1313  else
1314  ++nNextCol; // Empty columns require column brakes
1315  }
1316  if( pTmp != GetUpper()->GetUpper() ) // Did we end up in another column?
1317  {
1318  if( !pFrame )
1319  return;
1320  if( nNextCol )
1321  {
1322  while( pFrame->GetNext() )
1323  pFrame = pFrame->GetNext();
1324  }
1325  else
1326  {
1327  while( pFrame->GetNext() && pFrame->getFrameArea().Bottom() < rFill.Y() )
1328  pFrame = pFrame->GetNext();
1329  }
1330  // No filling, if the last frame in the targeted column does
1331  // not contain a paragraph, but e.g. a table
1332  if( pFrame->IsTextFrame() )
1333  {
1334  rFill.Fill().nColumnCnt = nNextCol;
1335  rFill.bColumn = true;
1336  if( rFill.pPos )
1337  {
1338  SwTextFrame const*const pTextFrame(static_cast<const SwTextFrame*>(pFrame));
1339  *rFill.pPos = pTextFrame->MapViewToModelPos(
1340  TextFrameIndex(pTextFrame->GetText().getLength()));
1341  }
1342  if( nNextCol )
1343  {
1344  rFill.aFrame = pTmp->getFramePrintArea();
1345  rFill.aFrame += pTmp->getFrameArea().Pos();
1346  }
1347  else
1348  rFill.aFrame = pFrame->getFrameArea();
1349  static_cast<const SwTextFrame*>(pFrame)->FillCursorPos( rFill );
1350  }
1351  return;
1352  }
1353  }
1354  std::unique_ptr<SwFont> pFnt;
1357  SwTwips nDiff = rFill.Y() - getFrameArea().Bottom();
1358  if( nDiff < nFirst )
1359  nDiff = -1;
1360  else
1361  pColl = &pColl->GetNextTextFormatColl();
1362  SwAttrSet aSet(const_cast<SwDoc&>(GetDoc()).GetAttrPool(), aTextFormatCollSetRange );
1363  const SwAttrSet* pSet = &pColl->GetAttrSet();
1365  if (GetTextNodeForParaProps()->HasSwAttrSet())
1366  {
1367  // sw_redlinehide: pSet is mostly used for para props, but there are
1368  // accesses to char props via pFnt - why does it use only the node's
1369  // props for this, and not hints?
1370  aSet.Put( *GetTextNodeForParaProps()->GetpSwAttrSet() );
1371  aSet.SetParent( pSet );
1372  pSet = &aSet;
1373  pFnt.reset(new SwFont( pSet, &GetDoc().getIDocumentSettingAccess() ));
1374  }
1375  else
1376  {
1377  SwFontAccess aFontAccess( pColl, pSh );
1378  pFnt.reset(new SwFont( aFontAccess.Get()->GetFont() ));
1379  pFnt->CheckFontCacheId( pSh, pFnt->GetActual() );
1380  }
1381  OutputDevice* pOut = pSh->GetOut();
1382  if( !pSh->GetViewOptions()->getBrowseMode() || pSh->GetViewOptions()->IsPrtFormat() )
1384 
1385  pFnt->SetFntChg( true );
1386  pFnt->ChgPhysFnt( pSh, *pOut );
1387 
1388  SwTwips nLineHeight = pFnt->GetHeight( pSh, *pOut );
1389 
1390  bool bFill = false;
1391  if( nLineHeight )
1392  {
1393  bFill = true;
1394  const SvxULSpaceItem &rUL = pSet->GetULSpace();
1395  SwTwips nDist = std::max( rUL.GetLower(), rUL.GetUpper() );
1396  if( rFill.Fill().nColumnCnt )
1397  {
1398  rFill.aFrame.Height( nLineHeight );
1399  nDiff = rFill.Y() - rFill.Bottom();
1400  nFirst = 0;
1401  }
1402  else if( nDist < nFirst )
1403  nFirst = nFirst - nDist;
1404  else
1405  nFirst = 0;
1406  nDist = std::max( nDist, GetLineSpace() );
1407  nDist += nLineHeight;
1408  nDiff -= nFirst;
1409 
1410  if( nDiff > 0 )
1411  {
1412  nDiff /= nDist;
1413  rFill.Fill().nParaCnt = static_cast<sal_uInt16>(nDiff + 1);
1414  rFill.nLineWidth = 0;
1415  rFill.bInner = false;
1416  rFill.bEmpty = true;
1418  }
1419  else
1420  nDiff = -1;
1421  if( rFill.bInner )
1422  bFill = false;
1423  else
1424  {
1425  const SvxTabStopItem &rRuler = pSet->GetTabStops();
1426  const SvxLRSpaceItem &rLRSpace = pSet->GetLRSpace();
1427 
1428  SwRect &rRect = rFill.Fill().aCursor;
1429  rRect.Top( rFill.Bottom() + (nDiff+1) * nDist - nLineHeight );
1430  if( nFirst && nDiff > -1 )
1431  rRect.Top( rRect.Top() + nFirst );
1432  rRect.Height( nLineHeight );
1433  SwTwips nLeft = rFill.Left() + rLRSpace.GetLeft() +
1435  SwTwips nRight = rFill.Right() - rLRSpace.GetRight();
1436  SwTwips nCenter = ( nLeft + nRight ) / 2;
1437  rRect.Left( nLeft );
1438  if( FILL_MARGIN == rFill.Mode() )
1439  {
1440  if( rFill.bEmpty )
1441  {
1443  if( rFill.X() < nCenter )
1444  {
1445  if( rFill.X() > ( nLeft + 2 * nCenter ) / 3 )
1446  {
1447  rFill.SetOrient( text::HoriOrientation::CENTER );
1448  rRect.Left( nCenter );
1449  }
1450  }
1451  else if( rFill.X() > ( nRight + 2 * nCenter ) / 3 )
1452  {
1454  rRect.Left( nRight );
1455  }
1456  else
1457  {
1458  rFill.SetOrient( text::HoriOrientation::CENTER );
1459  rRect.Left( nCenter );
1460  }
1461  }
1462  else
1463  bFill = false;
1464  }
1465  else
1466  {
1467  SwTwips nSpace = 0;
1468  if( FILL_TAB != rFill.Mode() )
1469  {
1470  const OUString aTmp(" ");
1471  SwDrawTextInfo aDrawInf( pSh, *pOut, aTmp, 0, 2 );
1472  nSpace = pFnt->GetTextSize_( aDrawInf ).Width()/2;
1473  }
1474  if( rFill.X() >= nRight )
1475  {
1476  if( FILL_INDENT != rFill.Mode() && ( rFill.bEmpty ||
1477  rFill.X() > rFill.nLineWidth + FILL_MIN_DIST ) )
1478  {
1480  rRect.Left( nRight );
1481  }
1482  else
1483  bFill = false;
1484  }
1485  else if( FILL_INDENT == rFill.Mode() )
1486  {
1487  SwTwips nIndent = rFill.X();
1488  if( !rFill.bEmpty || nIndent > nRight )
1489  bFill = false;
1490  else
1491  {
1492  nIndent -= rFill.Left();
1493  if( nIndent >= 0 && nSpace )
1494  {
1495  nIndent /= nSpace;
1496  nIndent *= nSpace;
1497  rFill.SetTab( sal_uInt16( nIndent ) );
1498  rRect.Left( nIndent + rFill.Left() );
1499  }
1500  else
1501  bFill = false;
1502  }
1503  }
1504  else if( rFill.X() > nLeft )
1505  {
1506  SwTwips nTextLeft = rFill.Left() + rLRSpace.GetTextLeft() +
1508  rFill.nLineWidth += rFill.bFirstLine ? nLeft : nTextLeft;
1509  SwTwips nLeftTab;
1510  SwTwips nRightTab = nLeft;
1511  sal_uInt16 nSpaceCnt = 0;
1512  sal_uInt16 nSpaceOnlyCnt = 0;
1513  sal_uInt16 nTabCnt = 0;
1514  sal_uInt16 nIdx = 0;
1515  do
1516  {
1517  nLeftTab = nRightTab;
1518  if( nIdx < rRuler.Count() )
1519  {
1520  const SvxTabStop &rTabStop = rRuler.operator[](nIdx);
1521  nRightTab = nTextLeft + rTabStop.GetTabPos();
1522  if( nLeftTab < nTextLeft && nRightTab > nTextLeft )
1523  nRightTab = nTextLeft;
1524  else
1525  ++nIdx;
1526  if( nRightTab > rFill.nLineWidth )
1527  ++nTabCnt;
1528  }
1529  else
1530  {
1531  const SvxTabStopItem& rTab =
1533  const SwTwips nDefTabDist = rTab[0].GetTabPos();
1534  nRightTab = nLeftTab - nTextLeft;
1535  nRightTab /= nDefTabDist;
1536  nRightTab = nRightTab * nDefTabDist + nTextLeft;
1537  while ( nRightTab <= nLeftTab )
1538  nRightTab += nDefTabDist;
1539  if( nRightTab > rFill.nLineWidth )
1540  ++nTabCnt;
1541  while ( nRightTab < rFill.X() )
1542  {
1543  nRightTab += nDefTabDist;
1544  if( nRightTab > rFill.nLineWidth )
1545  ++nTabCnt;
1546  }
1547  if( nLeftTab < nRightTab - nDefTabDist )
1548  nLeftTab = nRightTab - nDefTabDist;
1549  }
1550  if( nRightTab > nRight )
1551  nRightTab = nRight;
1552  }
1553  while( rFill.X() > nRightTab );
1554  --nTabCnt;
1555  if( FILL_TAB_SPACE == rFill.Mode() )
1556  {
1557  if( nSpace > 0 )
1558  {
1559  if( !nTabCnt )
1560  nLeftTab = rFill.nLineWidth;
1561  while( nLeftTab < rFill.X() )
1562  {
1563  nLeftTab += nSpace;
1564  ++nSpaceCnt;
1565  }
1566  if( nSpaceCnt )
1567  {
1568  nLeftTab -= nSpace;
1569  --nSpaceCnt;
1570  }
1571  if( rFill.X() - nLeftTab > nRightTab - rFill.X() )
1572  {
1573  nSpaceCnt = 0;
1574  ++nTabCnt;
1575  rRect.Left( nRightTab );
1576  }
1577  else
1578  {
1579  if( rFill.X() - nLeftTab > nSpace/2 )
1580  {
1581  ++nSpaceCnt;
1582  rRect.Left( nLeftTab + nSpace );
1583  }
1584  else
1585  rRect.Left( nLeftTab );
1586  }
1587  }
1588  else if( rFill.X() - nLeftTab < nRightTab - rFill.X() )
1589  rRect.Left( nLeftTab );
1590  else
1591  {
1592  if( nRightTab >= nRight )
1593  {
1595  rRect.Left( nRight );
1596  nTabCnt = 0;
1597  nSpaceCnt = 0;
1598  }
1599  else
1600  {
1601  rRect.Left( nRightTab );
1602  ++nTabCnt;
1603  }
1604  }
1605  }
1606  else if( FILL_SPACE == rFill.Mode() )
1607  {
1608  SwTwips nLeftSpace = nLeft;
1609  while( nLeftSpace < rFill.X() )
1610  {
1611  nLeftSpace += nSpace;
1612  ++nSpaceOnlyCnt;
1613  }
1614  rRect.Left( nLeftSpace );
1615  }
1616  else
1617  {
1618  if( rFill.X() - nLeftTab < nRightTab - rFill.X() )
1619  rRect.Left( nLeftTab );
1620  else
1621  {
1622  if( nRightTab >= nRight )
1623  {
1625  rRect.Left( nRight );
1626  nTabCnt = 0;
1627  nSpaceCnt = 0;
1628  }
1629  else
1630  {
1631  rRect.Left( nRightTab );
1632  ++nTabCnt;
1633  }
1634  }
1635  }
1636  rFill.SetTab( nTabCnt );
1637  rFill.SetSpace( nSpaceCnt );
1638  rFill.SetSpaceOnly( nSpaceOnlyCnt );
1639  if( bFill )
1640  {
1641  if( std::abs( rFill.X() - nCenter ) <=
1642  std::abs( rFill.X() - rRect.Left() ) )
1643  {
1644  rFill.SetOrient( text::HoriOrientation::CENTER );
1645  rFill.SetTab( 0 );
1646  rFill.SetSpace( 0 );
1647  rFill.SetSpaceOnly( 0 );
1648  rRect.Left( nCenter );
1649  }
1650  if( !rFill.bEmpty )
1651  rFill.nLineWidth += FILL_MIN_DIST;
1652  if( rRect.Left() < rFill.nLineWidth )
1653  bFill = false;
1654  }
1655  }
1656  }
1657  // Do we extend over the page's/column's/etc. lower edge?
1658  const SwFrame* pUp = GetUpper();
1659  if( pUp->IsInSct() )
1660  {
1661  if( pUp->IsSctFrame() )
1662  pUp = pUp->GetUpper();
1663  else if( pUp->IsColBodyFrame() &&
1664  pUp->GetUpper()->GetUpper()->IsSctFrame() )
1665  pUp = pUp->GetUpper()->GetUpper()->GetUpper();
1666  }
1667  SwRectFnSet aRectFnSet(this);
1668  SwTwips nLimit = aRectFnSet.GetPrtBottom(*pUp);
1669  SwTwips nRectBottom = rRect.Bottom();
1670  if ( aRectFnSet.IsVert() )
1671  nRectBottom = SwitchHorizontalToVertical( nRectBottom );
1672 
1673  if( aRectFnSet.YDiff( nLimit, nRectBottom ) < 0 )
1674  bFill = false;
1675  else
1676  rRect.Width( 1 );
1677  }
1678  }
1679  const_cast<SwCursorMoveState*>(rFill.pCMS)->m_bFillRet = bFill;
1680 }
1681 
1682 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
long GetLeft() const
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:341
Base class of the Writer layout elements.
Definition: frame.hxx:295
const sal_Unicode CH_BREAK
Definition: swfont.hxx:43
bool IsFirstMulti() const
Definition: inftxt.hxx:219
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:149
const SvxLRSpaceItem & GetLRSpace(bool=true) const
Definition: frmatr.hxx:44
void SwitchVerticalToHorizontal(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from vertical to horizontal layout...
Definition: txtfrm.cxx:583
bool m_bFieldInfo
should be fields recognized?
Definition: crstate.hxx:140
SwNode & GetNode(bool bPoint=true) const
Definition: pam.hxx:223
bool IsFollow() const
Definition: flowfrm.hxx:166
const SwSortedObjs * GetDrawObjs() const
Definition: frame.hxx:543
SwFillCursorPos & Fill() const
Definition: frmcrsr.cxx:543
Represents the style of a paragraph.
Definition: fmtcol.hxx:55
sal_uInt16 Count() const
sal_uInt16 GetLineNr() const
Definition: itrtxt.hxx:88
Marks a position in the document model.
Definition: pam.hxx:35
long GetLeftMarginWithNum(bool bTextLeft=false) const
Returns the additional indents of this text node and its numbering.
Definition: ndtxt.cxx:3162
void SetOrient(const sal_Int16 eNew)
Definition: frmcrsr.cxx:547
sal_Int16 eOrient
paragraph alignment
Definition: crstate.hxx:43
sal_uInt16 GetLower() const
bool IsInSct() const
Definition: frame.hxx:943
SwFont & GetFont()
Definition: swfntcch.hxx:58
bool m_bRealHeight
should the real height be calculated?
Definition: crstate.hxx:139
by left paragraph indention
Definition: crstate.hxx:32
sal_uInt16 nParaCnt
number of paragraphs to insert
Definition: crstate.hxx:38
long AdjustX(long nHorzMove)
bool IsSwapped() const
Definition: txtfrm.hxx:524
static bool IsRightMargin()
Definition: itrtxt.hxx:296
const SvxTabStopItem & GetTabStops(bool=true) const
Definition: paratr.hxx:190
fill with spaces and tabs
Definition: crstate.hxx:29
const SwLineLayout * NextLine()
Definition: itrtxt.cxx:124
bool HasPara() const
Definition: txtfrm.hxx:806
IDocumentDeviceAccess const & getIDocumentDeviceAccess() const
Definition: doc.cxx:270
TextFrameIndex GetStart() const
Definition: itrtxt.hxx:89
stay with the cursor inside text
Definition: crstate.hxx:125
friend bool sw_ChangeOffset(SwTextFrame *pFrame, TextFrameIndex nNew)
Definition: frmcrsr.cxx:109
SwRect aCursor
position and size of the ShadowCursor
Definition: crstate.hxx:37
SwNodeIndex nNode
Definition: pam.hxx:37
void Refresh(const SwFrame *pFrame)
Definition: frame.hxx:1320
SwModify * GetDep()
use these so we can grep for SwFrame's GetRegisteredIn accesses beware that SwTextFrame may return sw...
Definition: frame.hxx:457
void SwitchHorizontalToVertical(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from horizontal to vertical layout...
Definition: txtfrm.cxx:476
default
Definition: crstate.hxx:121
virtual bool UnitDown(SwPaM *, const SwTwips nOffset, bool bSetInReadOnly) const override
Definition: frmcrsr.cxx:1285
bool GetFirstLineOfsWithNum(short &rFirstOffset) const
Returns the combined first line indent of this text node and its numbering.
Definition: ndtxt.cxx:3205
sal_uIntPtr sal_uLong
virtual bool LeftMargin(SwPaM *) const override
Layout oriented cursor travelling: Left border, right border, previous Line, following Line...
Definition: frmcrsr.cxx:673
const SwRect & getFramePrintArea() const
Definition: frame.hxx:176
sal_uInt16 nSpaceCnt
number of spaces to insert
Definition: crstate.hxx:40
long GetLineSpace(const bool _bNoPropLineSpacing=false) const
Returns the additional line spacing for the next paragraph.
Definition: txtfrm.cxx:3672
sw::MergedPara * GetMergedPara()
Definition: txtfrm.hxx:438
bool HasFollow() const
Definition: flowfrm.hxx:165
void Height(long nNew)
Definition: swrect.hxx:189
virtual bool GetCharRect(SwRect &rRect, const SwPosition &rPos, SwCursorMoveState *pCMS=nullptr, bool bAllowFarAway=true) const override
Returns the screen position of rPos.
Definition: frmcrsr.cxx:179
long GetBottom(const SwRect &rRect) const
Definition: frame.hxx:1339
TextFrameIndex GetOfst() const
Definition: txtfrm.hxx:426
virtual bool UnitUp(SwPaM *, const SwTwips nOffset, bool bSetInReadOnly) const override
Definition: frmcrsr.cxx:1266
#define FILL_MIN_DIST
Definition: frmcrsr.cxx:520
Cursor Up/Down.
Definition: crstate.hxx:122
long SwTwips
Definition: swtypes.hxx:49
bool IsVert() const
Definition: frame.hxx:1328
static void SetRightMargin(const bool bNew)
Definition: itrtxt.hxx:295
void Pos(const Point &rNew)
Definition: swrect.hxx:167
SwPosition * pPos
Definition: frmcrsr.cxx:526
SwTwips FirstLeft() const
Definition: itrtxt.hxx:183
SwFillMode const eMode
desired fill-up rule
Definition: crstate.hxx:44
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
const OUString & GetText() const
Returns the text portion we want to edit (for inline see underneath)
Definition: txtfrm.cxx:1278
bool IsInside(TextFrameIndex nPos) const
Respect the Follows.
Definition: txtfrm.hxx:816
void SetTab(sal_uInt16 nNew)
Definition: frmcrsr.cxx:544
long GetPrtTop(const SwFrame &rFrame) const
Definition: frame.hxx:1370
SwTwips Y() const
Definition: itrtxt.hxx:91
virtual bool RightMargin(SwPaM *, bool bAPI=false) const override
Definition: frmcrsr.cxx:707
void SetPara(SwParaPortion *pNew, bool bDelete=true)
Definition: txtcache.cxx:112
bool IsMulti() const
Definition: inftxt.hxx:217
sal_uInt16 const aTextFormatCollSetRange[]
Definition: init.cxx:145
bool isFrameAreaDefinitionValid() const
Definition: frame.hxx:167
long Bottom() const
Definition: frmcrsr.cxx:542
bool IsHiddenNow() const
Hidden.
Definition: txtfrm.cxx:1345
long YDiff(long n1, long n2) const
Definition: frame.hxx:1384
sal_uInt16 sal_Unicode
bool bFirstLine
Definition: frmcrsr.cxx:529
SwFillMode Mode() const
Definition: frmcrsr.cxx:537
bool GetKeyCursorOfst(SwPosition *pPos, const Point &rPoint) const
Makes sure that the Frame is not switched (e.g.
Definition: txtfrm.hxx:390
long GetPrtBottom(const SwFrame &rFrame) const
Definition: frame.hxx:1371
void SetRight(const bool bNew)
Definition: frmcrsr.cxx:750
void Top(const long nTop)
Definition: swrect.hxx:202
const SwRect & getFrameArea() const
Definition: frame.hxx:175
void setX(long nX)
SwFlyFrame * GetPrevLink() const
Definition: flyfrm.hxx:172
bool getBrowseMode() const
Definition: viewopt.hxx:426
void FillCursorPos(SwFillData &rFill) const
Definition: frmcrsr.cxx:1295
bool IsInTab() const
Definition: frame.hxx:931
#define RES_PARATR_TABSTOP
Definition: hintids.hxx:166
sal_uInt16 nSpaceOnlyCnt
number of spaces to insert ("only spaces, no tabs" mode)
Definition: crstate.hxx:41
default, fill with tabs
Definition: crstate.hxx:28
sal_uLong GetIndex() const
Definition: ndindex.hxx:151
sal_Int32 & GetTabPos()
void SetSpace(sal_uInt16 nNew)
Definition: frmcrsr.cxx:545
bool IsTextFrame() const
Definition: frame.hxx:1210
const SwLineLayout * GetNextLine() const
Definition: itrtxt.cxx:134
virtual bool UnitUp(SwPaM *, const SwTwips nOffset, bool bSetInReadOnly) const
Definition: trvlfrm.cxx:960
SwFillMode
Definition: crstate.hxx:26
bool IsSctFrame() const
Definition: frame.hxx:1190
SwFlyFrame * FindFlyFrame()
Definition: frame.hxx:1087
void Right(const long nRight)
Definition: swrect.hxx:198
void setY(long nY)
virtual bool UnitDown(SwPaM *, const SwTwips nOffset, bool bSetInReadOnly) const
Definition: trvlfrm.cxx:965
SwAttrPool * GetPool() const
Definition: swatrset.hxx:190
if(nullptr==pCandidateA||nullptr==pCandidateB)
bool bEmpty
Definition: frmcrsr.cxx:532
SwFillData(const SwCursorMoveState *pC, SwPosition *pP, const SwRect &rR, const Point &rPt)
Definition: frmcrsr.cxx:533
SwTextFrame * GetFollow()
Definition: txtfrm.hxx:842
const SwAttrSet * GetAttrSet() const
WARNING: this may not return correct RES_PAGEDESC/RES_BREAK items for SwTextFrame, use GetBreakItem()/GetPageDescItem() instead.
Definition: findfrm.cxx:674
bool IsEmpty() const
Definition: txtfrm.hxx:509
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1288
bool IsCursorInProtectedArea() const
Definition: viewopt.hxx:363
TextFrameIndex MapModelToViewPos(SwPosition const &rPos) const
Definition: txtfrm.cxx:1254
void SetTop(SwRect &rRect, long nNew) const
Definition: frame.hxx:1347
sal_uInt16 nTabCnt
number of tabs respectively size of indentation
Definition: crstate.hxx:39
const SwContentFrame * GetFollow() const
Definition: cntfrm.hxx:113
TextFrameIndex GetCursorOfst(SwPosition *pPos, const Point &rPoint, bool bChgNode, SwCursorMoveState *=nullptr) const
Definition: itrcrsr.cxx:1258
const SwLineLayout * GetPrevLine()
Definition: itrtxt.cxx:144
long AdjustY(long nVertMove)
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:131
Collection of SwLinePortion instances, representing one line of text.
Definition: porlay.hxx:80
size_t size() const
Definition: ring.hxx:173
const SwPosition * GetPoint() const
Definition: pam.hxx:207
void Top()
Definition: itrtxt.hxx:100
size_t size() const
Definition: sortedobjs.cxx:42
SwPageFrame * FindPageFrame()
Definition: frame.hxx:658
Helper class which can be used instead of the macros if a function has too many returns.
Definition: txtfrm.hxx:917
long Left() const
Definition: frmcrsr.cxx:540
const SwFrame * Lower() const
Definition: layfrm.hxx:100
SwTextFrame * GetFrameAtPos(const SwPosition &rPos)
Definition: frmcrsr.cxx:152
SwLinePortion * GetFirstPortion() const
Definition: porlay.cxx:672
bool GetCursorOfst_(SwPosition *pPos, const Point &rPoint, const bool bChgFrame, SwCursorMoveState *=nullptr) const
Definition: frmcrsr.cxx:550
SwLayoutFrame * GetUpper()
Definition: frame.hxx:656
void TwipsToLine(const SwTwips)
Definition: itrtxt.cxx:300
SwTextFrame & GetFrameAtOfst(TextFrameIndex nOfst)
Definition: frmcrsr.cxx:144
bool HasArea() const
Definition: swrect.hxx:290
bool IsUndersized() const
Definition: flowfrm.hxx:158
const SwLineLayout * GetPrev()
Definition: itrtxt.cxx:83
SvxInterLineSpaceRule GetInterLineSpaceRule() const
SwTextFrame * GetFormatted(bool bForceQuickFormat=false)
In case the SwLineLayout was cleared out of the s_pTextCache, recreate it.
Definition: txtfrm.cxx:3348
sal_uInt16 GetLineHeight() const
Definition: itrtxt.hxx:117
const SvxLineSpacingItem & GetLineSpacing(bool=true) const
Definition: paratr.hxx:178
bool GetTopOfLine(SwTwips &_onTopOfLine, const SwPosition &_rPos) const
Determine top of line for given position in the text frame.
Definition: frmcrsr.cxx:454
ring_container GetRingContainer()
Definition: ring.hxx:240
SwRect aFrame
Definition: frmcrsr.cxx:524
bool IsLocked() const
Definition: txtfrm.hxx:505
Point m_aRealHeight
contains then the position/height of the cursor
Definition: crstate.hxx:135
const SfxPoolItem & GetDefaultItem(sal_uInt16 nWhich) const
TextFrameIndex GetLen() const
Definition: porlin.hxx:76
A page of the document layout.
Definition: pagefrm.hxx:40
bool m_bNoScroll
No scrolling of undersized textframes.
Definition: crstate.hxx:149
bool m_b2Lines
Check 2line portions and fill p2Lines.
Definition: crstate.hxx:148
long X() const
void InvalidateWindows(const SwRect &rRect)
Definition: viewsh.cxx:551
const OUString & GetText() const
Definition: inftxt.hxx:253
std::unique_ptr< Sw2LinesPos > m_p2Lines
for selections inside/around 2line portions
Definition: crstate.hxx:133
void SetParent(const SfxItemSet *pNew)
bool UnitUp_(SwPaM *, const SwTwips nOffset, bool bSetInReadOnly) const
Definition: frmcrsr.cxx:753
bool IsMultiPortion() const
Definition: porlin.hxx:136
void SwitchLTRtoRTL(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from LTR to RTL layout.
Definition: txtfrm.cxx:686
SwFillCursorPos * m_pFill
for automatic filling with tabs etc
Definition: crstate.hxx:132
Base class for anything that can be part of a line in the Writer layout.
Definition: porlin.hxx:52
bool GetAutoPos(SwRect &, const SwPosition &) const
A slimmer version of GetCharRect for autopositioning Frames.
Definition: frmcrsr.cxx:367
const SwLineLayout * Prev()
Definition: itrtxt.cxx:90
void Left(const long nLeft)
Definition: swrect.hxx:193
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
void Bottom(const long nBottom)
Definition: swrect.hxx:207
SwFontObj * Get()
Definition: swfntcch.cxx:56
void SetSpaceOnly(sal_uInt16 nNew)
Definition: frmcrsr.cxx:546
void SetOfst(TextFrameIndex nNewOfst)
Definition: txtfrm.hxx:852
long Y() const
Definition: frmcrsr.cxx:539
void SwitchRTLtoLTR(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from RTL to LTR layout.
Definition: txtfrm.hxx:722
const SvxULSpaceItem & GetULSpace(bool=true) const
Definition: frmatr.hxx:46
bool bColumn
Definition: frmcrsr.cxx:531
sal_uInt16 GetDropLeft() const
Definition: itrtxt.hxx:205
general base class for all free-flowing frames
Definition: flyfrm.hxx:60
TextFrameIndex GetLength() const
Definition: itrtxt.hxx:87
SwTextFrame * FindMaster() const
Definition: flowfrm.cxx:677
unsigned char sal_uInt8
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:426
void Width(long nNew)
Definition: swrect.hxx:185
void GetEndCharRect(SwRect *, TextFrameIndex, SwCursorMoveState *=nullptr, const long nMax=0)
Definition: itrcrsr.cxx:394
void SwapWidthAndHeight()
Swaps width and height of the text frame.
Definition: txtfrm.cxx:423
bool IsRightToLeft() const
Definition: frame.hxx:963
bool IsColBodyFrame() const
These SwFrame inlines are here, so that frame.hxx does not need to include layfrm.hxx.
Definition: layfrm.hxx:208
bool IsVertL2R() const
Definition: frame.hxx:1329
long X() const
Definition: frmcrsr.cxx:538
SwFlyFrame * GetNextLink() const
Definition: flyfrm.hxx:173
virtual OutputDevice * getReferenceDevice(bool bCreate) const =0
Returns the current reference device.
sal_uInt16 Width() const
Definition: possiz.hxx:46
const SwLineLayout * PrevLine()
Definition: itrtxt.cxx:170
CursorMoveState m_eState
Definition: crstate.hxx:136
bool IsPrtFormat() const
Definition: viewopt.hxx:495
double getLength(const B2DPolygon &rCandidate)
at right margin
Definition: crstate.hxx:123
void GetCharRect(SwRect *, TextFrameIndex, SwCursorMoveState *=nullptr, const long nMax=0)
Definition: itrcrsr.cxx:1172
static void lcl_VisualMoveRecursion(const SwLineLayout &rCurrLine, TextFrameIndex nIdx, TextFrameIndex &nPos, bool &bRight, sal_uInt8 &nCursorLevel, sal_uInt8 nDefaultDir)
Definition: frmcrsr.cxx:893
long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1343
#define FAR_AWAY
Definition: frmtool.hxx:51
void PrepareVisualMove(TextFrameIndex &nPos, sal_uInt8 &nCursorLevel, bool &bRight, bool bInsertCursor)
Prepares the cursor position for a visual cursor move (BiDi).
Definition: frmcrsr.cxx:1038
long Right() const
Definition: frmcrsr.cxx:541
const SwAttrSet & GetSwAttrSet() const
Does node has already its own auto-attributes? Access to SwAttrSet.
Definition: node.hxx:723
long GetRight() const
bool m_bPosCorr
Point had to be corrected.
Definition: crstate.hxx:141
const SwLineLayout * GetNext() const
Definition: itrtxt.hxx:85
bool UnitDown_(SwPaM *, const SwTwips nOffset, bool bSetInReadOnly) const
Definition: frmcrsr.cxx:1142
const SwLineLayout * GetCurr() const
Definition: itrtxt.hxx:84
bool IsVertical() const
Definition: frame.hxx:949
long GetTop(const SwRect &rRect) const
Definition: frame.hxx:1338
#define MIN_OFFSET_STEP
Definition: frmcrsr.cxx:50
const SwLineLayout * CharCursorToLine(TextFrameIndex const nPos)
Definition: itrtxt.cxx:202
SwDoc & GetDoc()
Definition: txtfrm.hxx:448
virtual bool GetCursorOfst(SwPosition *, Point &, SwCursorMoveState *=nullptr, bool bTestBackground=false) const override
In nOffset returns the offset of the char within the set text buffer, which is closest to the positio...
Definition: frmcrsr.cxx:662
fill with spaces
Definition: crstate.hxx:30
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:116
TextFrameIndex GetEnd() const
Definition: itrtxt.hxx:90
long const nRightMargin
sal_uInt16 GetDropLines() const
Definition: itrtxt.hxx:203
SwTwips nLineWidth
Definition: frmcrsr.cxx:528
SwLinePortion * GetNextPortion() const
Definition: porlin.hxx:74
bool sw_ChangeOffset(SwTextFrame *pFrame, TextFrameIndex nNew)
Definition: frmcrsr.cxx:109
long GetTextLeft() const
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:204
sal_Int32 nPos
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...
SwPosition MapViewToModelPos(TextFrameIndex nIndex) const
Definition: txtfrm.cxx:1233
only align left, center, right
Definition: crstate.hxx:31
const Point & rPoint
Definition: frmcrsr.cxx:527
const sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:61
SwRootFrame * getRootFrame()
Definition: frame.hxx:657
long Y() const
const SwCursorMoveState * pCMS
Definition: frmcrsr.cxx:525
SwTextFormatColl & GetNextTextFormatColl() const
Definition: fmtcol.hxx:97
sal_uInt16 GetUpper() const
bool IsProtected() const
Is the Frame or rather the Section in which it lies protected?
Definition: trvlfrm.cxx:1621
bool bInner
Definition: frmcrsr.cxx:530
SwFrame * GetNext()
Definition: frame.hxx:654
SwTextFormatColl * GetTextColl() const
Definition: ndtxt.hxx:836
sal_uInt16 nColumnCnt
number of necessary column breaks
Definition: crstate.hxx:42