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 
34 bool SwCursorShell::CallCursorShellFN( FNCursorShell fnCursor )
35 {
36  SwCallLink aLk( *this ); // watch Cursor-Moves
37  bool bRet = (this->*fnCursor)();
38  if( bRet )
41  return bRet;
42 }
43 
44 bool SwCursorShell::CallCursorFN( FNCursor fnCursor )
45 {
46  SwCallLink aLk( *this ); // watch Cursor-Moves
47  SwCursor* pCursor = getShellCursor( true );
48  bool bRet = (pCursor->*fnCursor)();
49  if( bRet )
52  return bRet;
53 }
54 
56 {
57  // jump from content to footnote
58  bool bRet = false;
59  SwTextNode* pTextNd = GetPoint()->nNode.GetNode().GetTextNode();
60 
61  SwTextAttr *const pFootnote( pTextNd
62  ? pTextNd->GetTextAttrForCharAt(
63  GetPoint()->nContent.GetIndex(), RES_TXTATR_FTN)
64  : nullptr);
65  if (pFootnote)
66  {
67  SwCursorSaveState aSaveState( *this );
68  GetPoint()->nNode = *static_cast<SwTextFootnote*>(pFootnote)->GetStartNode();
69 
71  &GetPoint()->nNode,
72  true, !IsReadOnlyAvailable() );
73  if( pCNd )
74  {
75  GetPoint()->nContent.Assign( pCNd, 0 );
78  }
79  }
80  return bRet;
81 }
82 
84 {
86  if( !bRet )
87  {
88  SwTextNode* pTextNd = GetCursor_() ?
89  GetCursor_()->GetPoint()->nNode.GetNode().GetTextNode() : nullptr;
90  if( pTextNd )
91  {
92  std::pair<Point, bool> const tmp(GetCursor_()->GetSttPos(), true);
93  const SwFrame *pFrame = pTextNd->getLayoutFrame( GetLayout(),
94  GetCursor_()->Start(), &tmp);
95  const SwFootnoteBossFrame* pFootnoteBoss;
96  bool bSkip = pFrame && pFrame->IsInFootnote();
97  while( pFrame )
98  {
99  pFootnoteBoss = pFrame->FindFootnoteBossFrame();
100  if (!pFootnoteBoss)
101  break;
102  pFrame = pFootnoteBoss->FindFootnoteCont();
103  if( pFrame )
104  {
105  if( bSkip )
106  bSkip = false;
107  else
108  {
109  const SwContentFrame* pCnt = static_cast<const SwLayoutFrame*>
110  (pFrame)->ContainsContent();
111  if( pCnt )
112  {
113  SwTextFrame const*const pTF(
114  static_cast<const SwTextFrame*>(pCnt));
115  *GetCursor_()->GetPoint() =
116  pTF->MapViewToModelPos(pTF->GetOffset());
119  bRet = true;
120  break;
121  }
122  }
123  }
124  if( pFootnoteBoss->GetNext() && !pFootnoteBoss->IsPageFrame() )
125  pFrame = pFootnoteBoss->GetNext();
126  else
127  pFrame = pFootnoteBoss->GetUpper();
128  }
129  }
130  }
131  return bRet;
132 }
133 
135 {
136  // jump from footnote to anchor
137  const SwNode* pSttNd = GetNode().FindFootnoteStartNode();
138  if( pSttNd )
139  {
140  // search in all footnotes in document for this StartIndex
141  const SwFootnoteIdxs& rFootnoteArr = pSttNd->GetDoc()->GetFootnoteIdxs();
142  for( size_t n = 0; n < rFootnoteArr.size(); ++n )
143  {
144  const SwTextFootnote* pTextFootnote = rFootnoteArr[ n ];
145  if( nullptr != pTextFootnote->GetStartNode() &&
146  pSttNd == &pTextFootnote->GetStartNode()->GetNode() )
147  {
148  SwCursorSaveState aSaveState( *this );
149 
150  SwTextNode& rTNd = const_cast<SwTextNode&>(pTextFootnote->GetTextNode());
151  GetPoint()->nNode = rTNd;
152  GetPoint()->nContent.Assign( &rTNd, pTextFootnote->GetStart() );
153 
156  }
157  }
158  }
159  return false;
160 }
161 
163 {
164  // jump from footnote to anchor
165  SwCallLink aLk( *this ); // watch Cursor-Moves
166  bool bRet = m_pCurrentCursor->GotoFootnoteAnchor();
167  if( bRet )
168  {
169  // special treatment for table header row
173  }
174  return bRet;
175 }
176 
177 static bool CmpLE( const SwTextFootnote& rFootnote, sal_uLong nNd, sal_Int32 nCnt )
178 {
179  const sal_uLong nTNd = rFootnote.GetTextNode().GetIndex();
180  return nTNd < nNd || ( nTNd == nNd && rFootnote.GetStart() <= nCnt );
181 }
182 
183 static bool CmpL( const SwTextFootnote& rFootnote, sal_uLong nNd, sal_Int32 nCnt )
184 {
185  const sal_uLong nTNd = rFootnote.GetTextNode().GetIndex();
186  return nTNd < nNd || ( nTNd == nNd && rFootnote.GetStart() < nCnt );
187 }
188 
190 {
191  const SwFootnoteIdxs& rFootnoteArr = GetDoc()->GetFootnoteIdxs();
192  const SwTextFootnote* pTextFootnote = nullptr;
193  size_t nPos = 0;
194 
195  if( rFootnoteArr.empty() )
196  {
197  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound );
198  return false;
199  }
200 
201  if( rFootnoteArr.SeekEntry( GetPoint()->nNode, &nPos ))
202  {
203  // there is a footnote with this index, so search also for the next one
204  if( nPos < rFootnoteArr.size() )
205  {
206  sal_uLong nNdPos = GetPoint()->nNode.GetIndex();
207  const sal_Int32 nCntPos = GetPoint()->nContent.GetIndex();
208 
209  pTextFootnote = rFootnoteArr[ nPos ];
210  // search forwards
211  if( CmpLE( *pTextFootnote, nNdPos, nCntPos ) )
212  {
213  pTextFootnote = nullptr;
214  for( ++nPos; nPos < rFootnoteArr.size(); ++nPos )
215  {
216  pTextFootnote = rFootnoteArr[ nPos ];
217  if( !CmpLE( *pTextFootnote, nNdPos, nCntPos ) )
218  break; // found
219  pTextFootnote = nullptr;
220  }
221  }
222  else if( nPos )
223  {
224  // search backwards
225  pTextFootnote = nullptr;
226  while( nPos )
227  {
228  pTextFootnote = rFootnoteArr[ --nPos ];
229  if( CmpLE( *pTextFootnote, nNdPos, nCntPos ) )
230  {
231  pTextFootnote = rFootnoteArr[ ++nPos ];
232  break; // found
233  }
234  }
235  }
236  }
237  }
238  else if( nPos < rFootnoteArr.size() )
239  pTextFootnote = rFootnoteArr[ nPos ];
240 
241  if (pTextFootnote == nullptr)
242  {
243  pTextFootnote = rFootnoteArr[ 0 ];
244  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::EndWrapped );
245  }
246  else
247  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty );
248 
249  bool bRet = nullptr != pTextFootnote;
250  if( bRet )
251  {
252  SwCursorSaveState aSaveState( *this );
253 
254  SwTextNode& rTNd = const_cast<SwTextNode&>(pTextFootnote->GetTextNode());
255  GetPoint()->nNode = rTNd;
256  GetPoint()->nContent.Assign( &rTNd, pTextFootnote->GetStart() );
257  bRet = !IsSelOvr();
258  }
259  return bRet;
260 }
261 
263 {
264  const SwFootnoteIdxs& rFootnoteArr = GetDoc()->GetFootnoteIdxs();
265  const SwTextFootnote* pTextFootnote = nullptr;
266  size_t nPos = 0;
267 
268  if( rFootnoteArr.empty() )
269  {
270  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound );
271  return false;
272  }
273 
274  if( rFootnoteArr.SeekEntry( GetPoint()->nNode, &nPos ) )
275  {
276  // there is a footnote with this index, so search also for the next one
277  sal_uLong nNdPos = GetPoint()->nNode.GetIndex();
278  const sal_Int32 nCntPos = GetPoint()->nContent.GetIndex();
279 
280  pTextFootnote = rFootnoteArr[ nPos ];
281  // search forwards
282  if( CmpL( *pTextFootnote, nNdPos, nCntPos ))
283  {
284  for( ++nPos; nPos < rFootnoteArr.size(); ++nPos )
285  {
286  pTextFootnote = rFootnoteArr[ nPos ];
287  if( !CmpL( *pTextFootnote, nNdPos, nCntPos ) )
288  {
289  pTextFootnote = rFootnoteArr[ nPos-1 ];
290  break;
291  }
292  }
293  }
294  else if( nPos )
295  {
296  // search backwards
297  pTextFootnote = nullptr;
298  while( nPos )
299  {
300  pTextFootnote = rFootnoteArr[ --nPos ];
301  if( CmpL( *pTextFootnote, nNdPos, nCntPos ))
302  break; // found
303  pTextFootnote = nullptr;
304  }
305  }
306  else
307  pTextFootnote = nullptr;
308  }
309  else if( nPos )
310  pTextFootnote = rFootnoteArr[ nPos-1 ];
311 
312  if( pTextFootnote == nullptr )
313  {
314  pTextFootnote = rFootnoteArr[ rFootnoteArr.size() - 1 ];
315  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::StartWrapped );
316  }
317  else
318  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty );
319 
320  bool bRet = nullptr != pTextFootnote;
321  if( bRet )
322  {
323  SwCursorSaveState aSaveState( *this );
324 
325  SwTextNode& rTNd = const_cast<SwTextNode&>(pTextFootnote->GetTextNode());
326  GetPoint()->nNode = rTNd;
327  GetPoint()->nContent.Assign( &rTNd, pTextFootnote->GetStart() );
328  bRet = !IsSelOvr();
329  }
330  return bRet;
331 }
332 
334 {
336 }
337 
339 {
341 }
342 
345 {
346  CurrShell aCurr( this );
347  const SwFrame* pFrame = GetCurrFrame();
348  do {
349  pFrame = pFrame->GetUpper();
350  } while( pFrame && !pFrame->IsFlyFrame() );
351 
352  if( !pFrame ) // no FlyFrame
353  return;
354 
355  SwCallLink aLk( *this ); // watch Cursor-Moves
356  SwCursorSaveState aSaveState( *m_pCurrentCursor );
357 
358  // jump in BodyFrame closest to FlyFrame
359  SwRect aTmpRect( m_aCharRect );
360  if( !pFrame->getFrameArea().IsInside( aTmpRect ))
361  aTmpRect = pFrame->getFrameArea();
362  Point aPt( aTmpRect.Left(), aTmpRect.Top() +
363  ( aTmpRect.Bottom() - aTmpRect.Top() ) / 2 );
364  aPt.setX(aPt.getX() > (pFrame->getFrameArea().Left() + (pFrame->getFrameArea().SSize().Width() / 2 ))
365  ? pFrame->getFrameArea().Right()
366  : pFrame->getFrameArea().Left());
367 
368  const SwPageFrame* pPageFrame = pFrame->FindPageFrame();
369  const SwContentFrame* pFndFrame = pPageFrame->GetContentPos( aPt, false, true );
371 
373  if( bRet )
376 }
377 
378 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Base class of the Writer layout elements.
Definition: frame.hxx:297
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:151
sal_uLong GetIndex() const
Definition: node.hxx:282
SAL_DLLPRIVATE void UpdateCursor(sal_uInt16 eFlags=SwCursorShell::SCROLLWIN|SwCursorShell::CHKRANGE, bool bIdleEnd=false)
Definition: crsrsh.cxx:1566
SwNode & GetNode(bool bPoint=true) const
Definition: pam.hxx:223
SwShellCursor * m_pCurrentCursor
current cursor
Definition: crsrsh.hxx:175
bool IsInProtectTable(bool bMove=false, bool bChgCursor=true)
Definition: swcrsr.cxx:565
bool GotoNextFootnoteAnchor()
Definition: trvlfnfl.cxx:333
check overlapping PaMs
Definition: crsrsh.hxx:154
SwNodeIndex nNode
Definition: pam.hxx:37
bool IsInFootnote() const
Definition: frame.hxx:927
SwShellCursor * getShellCursor(bool bBlock)
Delivers the current shell cursor.
Definition: crsrsh.cxx:3025
sal_uIntPtr sal_uLong
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1190
sal_Int64 n
virtual bool IsSelOvr(SwCursorSelOverFlags eFlags=SwCursorSelOverFlags::CheckNodeSection|SwCursorSelOverFlags::Toggle|SwCursorSelOverFlags::ChangePos)
Definition: swcrsr.cxx:223
SwNode & GetNode() const
Definition: ndindex.hxx:119
bool GotoFootnoteAnchor()
jump from footnote to anchor
Definition: trvlfnfl.cxx:162
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
bool GotoNextFootnoteAnchor()
Definition: trvlfnfl.cxx:189
virtual bool GetModelPositionForViewPoint(SwPosition *, Point &, SwCursorMoveState *=nullptr, bool bTestBackground=false) const
Definition: unusedf.cxx:46
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:3052
bool IsFlyFrame() const
Definition: frame.hxx:1188
void Top(const long nTop)
Definition: swrect.hxx:204
SwIndex nContent
Definition: pam.hxx:38
const SwRect & getFrameArea() const
Definition: frame.hxx:177
SwFootnoteContFrame * FindFootnoteCont()
Definition: ftnfrm.cxx:1023
bool GotoFootnoteText()
jump from content to footnote
Definition: trvlfnfl.cxx:83
sal_uLong GetIndex() const
Definition: ndindex.hxx:152
sal_Int32 GetStart() const
Definition: txatbase.hxx:82
static bool CmpL(const SwTextFootnote &rFootnote, sal_uLong nNd, sal_Int32 nCnt)
Definition: trvlfnfl.cxx:183
void Right(const long nRight)
Definition: swrect.hxx:200
size_type size() const
constexpr TypedWhichId< SwFormatFootnote > RES_TXTATR_FTN(58)
TextFrameIndex GetOffset() const
Definition: txtfrm.hxx:429
SwShellCursor * GetCursor_()
Definition: crsrsh.hxx:328
static SwNodePtr GetStartNode(SwOutlineNodes const *pOutlNds, int nOutlineLevel, SwOutlineNodes::size_type *nOutl)
Definition: docglbl.cxx:89
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:230
const SwPosition * GetPoint() const
Definition: pam.hxx:207
SwIndex & Assign(SwIndexReg *, sal_Int32)
Definition: index.cxx:206
SwPageFrame * FindPageFrame()
Definition: frame.hxx:660
SwDoc * GetDoc()
Definition: node.hxx:702
bool GotoFootnoteText()
Definition: trvlfnfl.cxx:55
SwDoc * GetDoc() const
Definition: pam.hxx:243
SwLayoutFrame * GetUpper()
Definition: frame.hxx:658
SwFootnoteBossFrame * FindFootnoteBossFrame(bool bFootnotes=false)
Definition: findfrm.cxx:435
bool empty() const
void SSize(const Size &rNew)
Definition: swrect.hxx:178
bool GotoPrevFootnoteAnchor()
Definition: trvlfnfl.cxx:262
static bool CmpLE(const SwTextFootnote &rFootnote, sal_uLong nNd, sal_Int32 nCnt)
Definition: trvlfnfl.cxx:177
A page of the document layout.
Definition: pagefrm.hxx:41
static void SetSearchLabel(const SearchLabel &rSL)
bool GotoPrevFootnoteAnchor()
Definition: trvlfnfl.cxx:338
virtual bool IsReadOnlyAvailable() const
Definition: swcrsr.cxx:151
void Left(const long nLeft)
Definition: swrect.hxx:195
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:80
void Bottom(const long nBottom)
Definition: swrect.hxx:209
SwContentFrame * GetCurrFrame(const bool bCalcFrame=true) const
Get current frame in which the cursor is positioned.
Definition: crsrsh.cxx:2441
sal_Int32 GetIndex() const
Definition: index.hxx:91
bool IsInside(const Point &rPOINT) const
Definition: swrect.cxx:105
SwNodes & GetNodes()
Definition: doc.hxx:403
bool IsPageFrame() const
Definition: frame.hxx:1156
const Point & GetPtPos() const
Definition: viscrs.hxx:142
scroll window
Definition: crsrsh.hxx:153
SAL_DLLPRIVATE bool CallCursorShellFN(FNCursorShell)
Definition: trvlfnfl.cxx:34
SwNodeIndex * GetStartNode() const
Definition: txtftn.hxx:41
SwFootnoteIdxs & GetFootnoteIdxs()
Definition: doc.hxx:628
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:1906
make visible in spite of Readonly
Definition: crsrsh.hxx:155
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:344
bool GotoFootnoteAnchor()
Definition: trvlfnfl.cxx:134
SwRect m_aCharRect
Char-SRectangle on which the cursor is located.
Definition: crsrsh.hxx:164
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2069
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:1185
SwPosition MapViewToModelPos(TextFrameIndex nIndex) const
Definition: txtfrm.cxx:1238
SAL_DLLPRIVATE bool CallCursorFN(FNCursor)
Definition: trvlfnfl.cxx:44
const SwTextNode & GetTextNode() const
Definition: txtftn.hxx:69
const SwStartNode * FindFootnoteStartNode() const
Definition: node.hxx:200
sal_uInt16 nPos
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:844
SwFrame * GetNext()
Definition: frame.hxx:656
Base class of the Writer document model elements.
Definition: node.hxx:79