LibreOffice Module sw (master)  1
trvlfnfl.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 <crsrsh.hxx>
21 #include <doc.hxx>
22 #include <pagefrm.hxx>
23 #include <cntfrm.hxx>
24 #include <ftnfrm.hxx>
25 #include <swcrsr.hxx>
26 #include <ndtxt.hxx>
27 #include <txtfrm.hxx>
28 #include <txtftn.hxx>
29 #include <ftnidx.hxx>
30 #include <viscrs.hxx>
31 #include "callnk.hxx"
32 #include <svx/srchdlg.hxx>
33 #include <wrtsh.hxx>
34 
35 bool SwCursorShell::CallCursorShellFN( FNCursorShell fnCursor )
36 {
37  if (SwWrtShell* pWrtSh = dynamic_cast<SwWrtShell*>(this))
38  pWrtSh->addCurrentPosition();
39 
40  SwCallLink aLk( *this ); // watch Cursor-Moves
41  bool bRet = (this->*fnCursor)();
42  if( bRet )
45  return bRet;
46 }
47 
48 bool SwCursorShell::CallCursorFN( FNCursor fnCursor )
49 {
50  if (SwWrtShell* pWrtSh = dynamic_cast<SwWrtShell*>(this))
51  pWrtSh->addCurrentPosition();
52 
53  SwCallLink aLk( *this ); // watch Cursor-Moves
54  SwCursor* pCursor = getShellCursor( true );
55  bool bRet = (pCursor->*fnCursor)();
56  if( bRet )
59  return bRet;
60 }
61 
63 {
64  // jump from content to footnote
65  bool bRet = false;
66  SwTextNode* pTextNd = GetPoint()->nNode.GetNode().GetTextNode();
67 
68  SwTextAttr *const pFootnote( pTextNd
69  ? pTextNd->GetTextAttrForCharAt(
70  GetPoint()->nContent.GetIndex(), RES_TXTATR_FTN)
71  : nullptr);
72  if (pFootnote)
73  {
74  SwCursorSaveState aSaveState( *this );
75  GetPoint()->nNode = *static_cast<SwTextFootnote*>(pFootnote)->GetStartNode();
76 
78  &GetPoint()->nNode,
79  true, !IsReadOnlyAvailable() );
80  if( pCNd )
81  {
82  GetPoint()->nContent.Assign( pCNd, 0 );
85  }
86  }
87  return bRet;
88 }
89 
91 {
93  if( !bRet )
94  {
95  SwTextNode* pTextNd = GetCursor_() ?
96  GetCursor_()->GetPoint()->nNode.GetNode().GetTextNode() : nullptr;
97  if( pTextNd )
98  {
99  std::pair<Point, bool> const tmp(GetCursor_()->GetSttPos(), true);
100  const SwFrame *pFrame = pTextNd->getLayoutFrame( GetLayout(),
101  GetCursor_()->Start(), &tmp);
102  const SwFootnoteBossFrame* pFootnoteBoss;
103  bool bSkip = pFrame && pFrame->IsInFootnote();
104  while( pFrame )
105  {
106  pFootnoteBoss = pFrame->FindFootnoteBossFrame();
107  if (!pFootnoteBoss)
108  break;
109  pFrame = pFootnoteBoss->FindFootnoteCont();
110  if( pFrame )
111  {
112  if( bSkip )
113  bSkip = false;
114  else
115  {
116  const SwContentFrame* pCnt = static_cast<const SwLayoutFrame*>
117  (pFrame)->ContainsContent();
118  if( pCnt )
119  {
120  SwTextFrame const*const pTF(
121  static_cast<const SwTextFrame*>(pCnt));
122  *GetCursor_()->GetPoint() =
123  pTF->MapViewToModelPos(pTF->GetOffset());
126  bRet = true;
127  break;
128  }
129  }
130  }
131  if( pFootnoteBoss->GetNext() && !pFootnoteBoss->IsPageFrame() )
132  pFrame = pFootnoteBoss->GetNext();
133  else
134  pFrame = pFootnoteBoss->GetUpper();
135  }
136  }
137  }
138  return bRet;
139 }
140 
142 {
143  // jump from footnote to anchor
144  const SwNode* pSttNd = GetNode().FindFootnoteStartNode();
145  if( pSttNd )
146  {
147  // search in all footnotes in document for this StartIndex
148  const SwFootnoteIdxs& rFootnoteArr = pSttNd->GetDoc().GetFootnoteIdxs();
149  for( size_t n = 0; n < rFootnoteArr.size(); ++n )
150  {
151  const SwTextFootnote* pTextFootnote = rFootnoteArr[ n ];
152  if( nullptr != pTextFootnote->GetStartNode() &&
153  pSttNd == &pTextFootnote->GetStartNode()->GetNode() )
154  {
155  SwCursorSaveState aSaveState( *this );
156 
157  SwTextNode& rTNd = const_cast<SwTextNode&>(pTextFootnote->GetTextNode());
158  GetPoint()->nNode = rTNd;
159  GetPoint()->nContent.Assign( &rTNd, pTextFootnote->GetStart() );
160 
163  }
164  }
165  }
166  return false;
167 }
168 
170 {
171  if (SwWrtShell* pWrtSh = dynamic_cast<SwWrtShell*>(this))
172  pWrtSh->addCurrentPosition();
173 
174  // jump from footnote to anchor
175  SwCallLink aLk( *this ); // watch Cursor-Moves
176  bool bRet = m_pCurrentCursor->GotoFootnoteAnchor();
177  if( bRet )
178  {
179  // special treatment for table header row
183  }
184  return bRet;
185 }
186 
187 static bool CmpLE( const SwTextFootnote& rFootnote, SwNodeOffset nNd, sal_Int32 nCnt )
188 {
189  const SwNodeOffset nTNd = rFootnote.GetTextNode().GetIndex();
190  return nTNd < nNd || ( nTNd == nNd && rFootnote.GetStart() <= nCnt );
191 }
192 
193 static bool CmpL( const SwTextFootnote& rFootnote, SwNodeOffset nNd, sal_Int32 nCnt )
194 {
195  const SwNodeOffset nTNd = rFootnote.GetTextNode().GetIndex();
196  return nTNd < nNd || ( nTNd == nNd && rFootnote.GetStart() < nCnt );
197 }
198 
200 {
201  const SwFootnoteIdxs& rFootnoteArr = GetDoc().GetFootnoteIdxs();
202  const SwTextFootnote* pTextFootnote = nullptr;
203  size_t nPos = 0;
204 
205  if( rFootnoteArr.empty() )
206  {
207  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound );
208  return false;
209  }
210 
211  if( rFootnoteArr.SeekEntry( GetPoint()->nNode, &nPos ))
212  {
213  // there is a footnote with this index, so search also for the next one
214  if( nPos < rFootnoteArr.size() )
215  {
216  SwNodeOffset nNdPos = GetPoint()->nNode.GetIndex();
217  const sal_Int32 nCntPos = GetPoint()->nContent.GetIndex();
218 
219  pTextFootnote = rFootnoteArr[ nPos ];
220  // search forwards
221  if( CmpLE( *pTextFootnote, nNdPos, nCntPos ) )
222  {
223  pTextFootnote = nullptr;
224  for( ++nPos; nPos < rFootnoteArr.size(); ++nPos )
225  {
226  pTextFootnote = rFootnoteArr[ nPos ];
227  if( !CmpLE( *pTextFootnote, nNdPos, nCntPos ) )
228  break; // found
229  pTextFootnote = nullptr;
230  }
231  }
232  else if( nPos )
233  {
234  // search backwards
235  pTextFootnote = nullptr;
236  while( nPos )
237  {
238  pTextFootnote = rFootnoteArr[ --nPos ];
239  if( CmpLE( *pTextFootnote, nNdPos, nCntPos ) )
240  {
241  pTextFootnote = rFootnoteArr[ ++nPos ];
242  break; // found
243  }
244  }
245  }
246  }
247  }
248  else if( nPos < rFootnoteArr.size() )
249  pTextFootnote = rFootnoteArr[ nPos ];
250 
251  if (pTextFootnote == nullptr)
252  {
253  pTextFootnote = rFootnoteArr[ 0 ];
254  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::EndWrapped );
255  }
256  else
257  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty );
258 
259  bool bRet = nullptr != pTextFootnote;
260  if( bRet )
261  {
262  SwCursorSaveState aSaveState( *this );
263 
264  SwTextNode& rTNd = const_cast<SwTextNode&>(pTextFootnote->GetTextNode());
265  GetPoint()->nNode = rTNd;
266  GetPoint()->nContent.Assign( &rTNd, pTextFootnote->GetStart() );
267  bRet = !IsSelOvr();
268  }
269  return bRet;
270 }
271 
273 {
274  const SwFootnoteIdxs& rFootnoteArr = GetDoc().GetFootnoteIdxs();
275  const SwTextFootnote* pTextFootnote = nullptr;
276  size_t nPos = 0;
277 
278  if( rFootnoteArr.empty() )
279  {
280  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound );
281  return false;
282  }
283 
284  if( rFootnoteArr.SeekEntry( GetPoint()->nNode, &nPos ) )
285  {
286  // there is a footnote with this index, so search also for the next one
287  SwNodeOffset nNdPos = GetPoint()->nNode.GetIndex();
288  const sal_Int32 nCntPos = GetPoint()->nContent.GetIndex();
289 
290  pTextFootnote = rFootnoteArr[ nPos ];
291  // search forwards
292  if( CmpL( *pTextFootnote, nNdPos, nCntPos ))
293  {
294  for( ++nPos; nPos < rFootnoteArr.size(); ++nPos )
295  {
296  pTextFootnote = rFootnoteArr[ nPos ];
297  if( !CmpL( *pTextFootnote, nNdPos, nCntPos ) )
298  {
299  pTextFootnote = rFootnoteArr[ nPos-1 ];
300  break;
301  }
302  }
303  }
304  else if( nPos )
305  {
306  // search backwards
307  pTextFootnote = nullptr;
308  while( nPos )
309  {
310  pTextFootnote = rFootnoteArr[ --nPos ];
311  if( CmpL( *pTextFootnote, nNdPos, nCntPos ))
312  break; // found
313  pTextFootnote = nullptr;
314  }
315  }
316  else
317  pTextFootnote = nullptr;
318  }
319  else if( nPos )
320  pTextFootnote = rFootnoteArr[ nPos-1 ];
321 
322  if( pTextFootnote == nullptr )
323  {
324  pTextFootnote = rFootnoteArr[ rFootnoteArr.size() - 1 ];
325  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::StartWrapped );
326  }
327  else
328  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty );
329 
330  bool bRet = nullptr != pTextFootnote;
331  if( bRet )
332  {
333  SwCursorSaveState aSaveState( *this );
334 
335  SwTextNode& rTNd = const_cast<SwTextNode&>(pTextFootnote->GetTextNode());
336  GetPoint()->nNode = rTNd;
337  GetPoint()->nContent.Assign( &rTNd, pTextFootnote->GetStart() );
338  bRet = !IsSelOvr();
339  }
340  return bRet;
341 }
342 
344 {
346 }
347 
349 {
351 }
352 
355 {
356  CurrShell aCurr( this );
357  const SwFrame* pFrame = GetCurrFrame();
358  do {
359  pFrame = pFrame->GetUpper();
360  } while( pFrame && !pFrame->IsFlyFrame() );
361 
362  if( !pFrame ) // no FlyFrame
363  return;
364 
365  SwCallLink aLk( *this ); // watch Cursor-Moves
366  SwCursorSaveState aSaveState( *m_pCurrentCursor );
367 
368  // jump in BodyFrame closest to FlyFrame
369  SwRect aTmpRect( m_aCharRect );
370  if( !pFrame->getFrameArea().Contains( aTmpRect ))
371  aTmpRect = pFrame->getFrameArea();
372  Point aPt( aTmpRect.Left(), aTmpRect.Top() +
373  ( aTmpRect.Bottom() - aTmpRect.Top() ) / 2 );
374  aPt.setX(aPt.getX() > (pFrame->getFrameArea().Left() + (pFrame->getFrameArea().SSize().Width() / 2 ))
375  ? pFrame->getFrameArea().Right()
376  : pFrame->getFrameArea().Left());
377 
378  const SwPageFrame* pPageFrame = pFrame->FindPageFrame();
379  const SwContentFrame* pFndFrame = pPageFrame->GetContentPos( aPt, false, true );
381 
383  if( bRet )
386 }
387 
388 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Base class of the Writer layout elements.
Definition: frame.hxx:314
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:159
static bool CmpLE(const SwTextFootnote &rFootnote, SwNodeOffset nNd, sal_Int32 nCnt)
Definition: trvlfnfl.cxx:187
SAL_DLLPRIVATE void UpdateCursor(sal_uInt16 eFlags=SwCursorShell::SCROLLWIN|SwCursorShell::CHKRANGE, bool bIdleEnd=false)
Definition: crsrsh.cxx:1573
SwNode & GetNode(bool bPoint=true) const
Definition: pam.hxx:224
void Right(const tools::Long nRight)
Definition: swrect.hxx:202
SwShellCursor * m_pCurrentCursor
current cursor
Definition: crsrsh.hxx:181
bool IsInProtectTable(bool bMove=false, bool bChgCursor=true)
Definition: swcrsr.cxx:568
bool GotoNextFootnoteAnchor()
Definition: trvlfnfl.cxx:343
check overlapping PaMs
Definition: crsrsh.hxx:160
void Left(const tools::Long nLeft)
Definition: swrect.hxx:197
SwNodeIndex nNode
Definition: pam.hxx:38
bool IsInFootnote() const
Definition: frame.hxx:949
SwShellCursor * getShellCursor(bool bBlock)
Delivers the current shell cursor.
Definition: crsrsh.cxx:3048
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1210
sal_Int64 n
virtual bool IsSelOvr(SwCursorSelOverFlags eFlags=SwCursorSelOverFlags::CheckNodeSection|SwCursorSelOverFlags::Toggle|SwCursorSelOverFlags::ChangePos)
Definition: swcrsr.cxx:226
SwNode & GetNode() const
Definition: ndindex.hxx:119
bool GotoFootnoteAnchor()
jump from footnote to anchor
Definition: trvlfnfl.cxx:169
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
bool GotoNextFootnoteAnchor()
Definition: trvlfnfl.cxx:199
virtual bool GetModelPositionForViewPoint(SwPosition *, Point &, SwCursorMoveState *=nullptr, bool bTestBackground=false) const
Definition: unusedf.cxx:47
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:3068
Used by the UI to modify the document model.
Definition: wrtsh.hxx:96
bool IsFlyFrame() const
Definition: frame.hxx:1210
constexpr TypedWhichId< SwFormatFootnote > RES_TXTATR_FTN(59)
SwIndex nContent
Definition: pam.hxx:39
const SwRect & getFrameArea() const
Definition: frame.hxx:179
SwFootnoteContFrame * FindFootnoteCont()
Definition: ftnfrm.cxx:1036
A wrapper around SfxPoolItem to store the start position of (usually) a text portion, with an optional end.
Definition: txatbase.hxx:43
bool GotoFootnoteText()
jump from content to footnote
Definition: trvlfnfl.cxx:90
sal_Int32 GetStart() const
Definition: txatbase.hxx:88
SwNodeOffset GetIndex() const
Definition: ndindex.hxx:152
size_type size() const
TextFrameIndex GetOffset() const
Definition: txtfrm.hxx:439
SwShellCursor * GetCursor_()
Definition: crsrsh.hxx:333
SwTextFootnote * SeekEntry(const SwNodeIndex &rIdx, size_t *pPos=nullptr) const
Definition: ftnidx.cxx:409
A helper class to save cursor state (position).
Definition: swcrsr.hxx:232
SwDoc & GetDoc()
Definition: node.hxx:213
const SwPosition * GetPoint() const
Definition: pam.hxx:208
SwIndex & Assign(SwIndexReg *, sal_Int32)
Definition: index.cxx:206
SwPageFrame * FindPageFrame()
Definition: frame.hxx:680
SwNodeOffset GetIndex() const
Definition: node.hxx:292
bool GotoFootnoteText()
Definition: trvlfnfl.cxx:62
SwLayoutFrame * GetUpper()
Definition: frame.hxx:678
SwFootnoteBossFrame * FindFootnoteBossFrame(bool bFootnotes=false)
Definition: findfrm.cxx:460
bool empty() const
void SSize(const Size &rNew)
Definition: swrect.hxx:180
bool GotoPrevFootnoteAnchor()
Definition: trvlfnfl.cxx:272
A page of the document layout.
Definition: pagefrm.hxx:57
static void SetSearchLabel(const SearchLabel &rSL)
bool Contains(const Point &rPOINT) const
Definition: swrect.hxx:356
bool GotoPrevFootnoteAnchor()
Definition: trvlfnfl.cxx:348
virtual bool IsReadOnlyAvailable() const
Definition: swcrsr.cxx:154
void Bottom(const tools::Long nBottom)
Definition: swrect.hxx:211
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
SwContentFrame * GetCurrFrame(const bool bCalcFrame=true) const
Get current frame in which the cursor is positioned.
Definition: crsrsh.cxx:2457
sal_Int32 GetIndex() const
Definition: index.hxx:91
SwNodes & GetNodes()
Definition: doc.hxx:408
void Top(const tools::Long nTop)
Definition: swrect.hxx:206
bool IsPageFrame() const
Definition: frame.hxx:1178
const Point & GetPtPos() const
Definition: viscrs.hxx:153
scroll window
Definition: crsrsh.hxx:159
SAL_DLLPRIVATE bool CallCursorShellFN(FNCursorShell)
Definition: trvlfnfl.cxx:35
static bool CmpL(const SwTextFootnote &rFootnote, SwNodeOffset nNd, sal_Int32 nCnt)
Definition: trvlfnfl.cxx:193
SwNodeIndex * GetStartNode() const
Definition: txtftn.hxx:41
SwFootnoteIdxs & GetFootnoteIdxs()
Definition: doc.hxx:633
SwContentNode * GoNextSection(SwNodeIndex *, bool bSkipHidden=true, bool bSkipProtect=true) const
Go to next content-node that is not protected or hidden (Both set FALSE ==> GoNext/GoPrevious!!!).
Definition: nodes.cxx:1919
make visible in spite of Readonly
Definition: crsrsh.hxx:161
SwDoc & GetDoc() const
Definition: pam.hxx:244
A layout frame is a frame that contains other frames (m_pLower), e.g. SwPageFrame or SwTabFrame...
Definition: layfrm.hxx:35
void GotoFlyAnchor()
jump from the frame to the anchor
Definition: trvlfnfl.cxx:354
bool GotoFootnoteAnchor()
Definition: trvlfnfl.cxx:141
static SwNode * GetStartNode(SwOutlineNodes const *pOutlNds, int nOutlineLevel, SwOutlineNodes::size_type *nOutl)
Definition: docglbl.cxx:89
SwRect m_aCharRect
Char-SRectangle on which the cursor is located.
Definition: crsrsh.hxx:170
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2172
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:1186
SwPosition MapViewToModelPos(TextFrameIndex nIndex) const
Definition: txtfrm.cxx:1249
SAL_DLLPRIVATE bool CallCursorFN(FNCursor)
Definition: trvlfnfl.cxx:48
const SwTextNode & GetTextNode() const
Definition: txtftn.hxx:70
const SwStartNode * FindFootnoteStartNode() const
Definition: node.hxx:202
sal_uInt16 nPos
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:864
SwFrame * GetNext()
Definition: frame.hxx:676
Base class of the Writer document model elements.
Definition: node.hxx:81